From aca368e33230e25eb4a80a929d6f833bf1d9899f Mon Sep 17 00:00:00 2001 From: RK_01 <50594595+RaphiMC@users.noreply.github.com> Date: Mon, 19 Feb 2024 22:25:49 +0100 Subject: [PATCH 001/272] Implemented ViaProxy bootstrap (#4201) * Implemented ViaProxy bootstrap * Applied requested changes to code * Override indra settings to Java 17 * Removed explicit java source/target version * Added ViaProxy artifact to build.yml * Added ViaProxy artifact to pullrequest.yml * Updated ViaProxy API usage * Implemented floodgate support for ViaProxy * Depend on stable ViaProxy release * Initialize command manager and ping passthrough before Geyser#start * Revert "Initialize command manager and ping passthrough before Geyser#start" This reverts commit 39356071c4d59d82469477f160919365f88d39c7. * Some ping passthrough improvements * Merged code properly * Updated ViaProxy API usage * Implemented better command handling * Updated ViaProxy and Geyser API usage * Combine bootstrap and plugin into one class * Minor code improvements * Call Geyser shutdown on plugin disable * Only call disable if Geyser was enabled once * Don't send two shutdown done messages * Use setter for enabled boolean --- .github/workflows/build.yml | 7 + .github/workflows/pullrequest.yml | 7 + .../geyser/api/util/PlatformType.java | 1 + bootstrap/viaproxy/build.gradle.kts | 26 ++ .../viaproxy/GeyserViaProxyConfiguration.java | 53 +++++ .../viaproxy/GeyserViaProxyDumpInfo.java | 67 ++++++ .../viaproxy/GeyserViaProxyLogger.java | 88 +++++++ .../platform/viaproxy/GeyserViaProxyMain.java | 45 ++++ .../viaproxy/GeyserViaProxyPlugin.java | 224 ++++++++++++++++++ .../viaproxy/src/main/resources/viaproxy.yml | 5 + .../kotlin/geyser.base-conventions.gradle.kts | 6 +- build.gradle.kts | 3 +- .../java/org/geysermc/geyser/GeyserImpl.java | 39 +-- .../java/JavaLoginDisconnectTranslator.java | 2 +- gradle/libs.versions.toml | 2 + settings.gradle.kts | 4 +- 16 files changed, 559 insertions(+), 20 deletions(-) create mode 100644 bootstrap/viaproxy/build.gradle.kts create mode 100644 bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyConfiguration.java create mode 100644 bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyDumpInfo.java create mode 100644 bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyLogger.java create mode 100644 bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyMain.java create mode 100644 bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyPlugin.java create mode 100644 bootstrap/viaproxy/src/main/resources/viaproxy.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6c5c15248..827136b4a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -77,6 +77,13 @@ jobs: name: Geyser Velocity path: bootstrap/velocity/build/libs/Geyser-Velocity.jar if-no-files-found: error + - name: Archive artifacts (Geyser ViaProxy) + uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 + if: success() + with: + name: Geyser ViaProxy + path: bootstrap/viaproxy/build/libs/Geyser-ViaProxy.jar + if-no-files-found: error - name: Publish to Maven Repository if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 797d68767..f2c8f5d8d 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -87,3 +87,10 @@ jobs: name: Geyser Velocity path: geyser/bootstrap/velocity/build/libs/Geyser-Velocity.jar if-no-files-found: error + - name: Archive artifacts (Geyser ViaProxy) + uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 + if: success() + with: + name: Geyser ViaProxy + path: geyser/bootstrap/viaproxy/build/libs/Geyser-ViaProxy.jar + if-no-files-found: error diff --git a/api/src/main/java/org/geysermc/geyser/api/util/PlatformType.java b/api/src/main/java/org/geysermc/geyser/api/util/PlatformType.java index 815381d6b..1abdc0230 100644 --- a/api/src/main/java/org/geysermc/geyser/api/util/PlatformType.java +++ b/api/src/main/java/org/geysermc/geyser/api/util/PlatformType.java @@ -40,4 +40,5 @@ public record PlatformType(String platformName) { public static final PlatformType SPONGE = new PlatformType("Sponge"); public static final PlatformType STANDALONE = new PlatformType("Standalone"); public static final PlatformType VELOCITY = new PlatformType("Velocity"); + public static final PlatformType VIAPROXY = new PlatformType("ViaProxy"); } diff --git a/bootstrap/viaproxy/build.gradle.kts b/bootstrap/viaproxy/build.gradle.kts new file mode 100644 index 000000000..4d5d4f949 --- /dev/null +++ b/bootstrap/viaproxy/build.gradle.kts @@ -0,0 +1,26 @@ +dependencies { + api(projects.core) +} + +platformRelocate("net.kyori") +platformRelocate("org.yaml") +platformRelocate("it.unimi.dsi.fastutil") +platformRelocate("org.cloudburstmc.netty") + +// These dependencies are already present on the platform +provided(libs.viaproxy) + +application { + mainClass.set("org.geysermc.geyser.platform.viaproxy.GeyserViaProxyMain") +} + +tasks.withType { + archiveBaseName.set("Geyser-ViaProxy") + + dependencies { + exclude(dependency("com.google.*:.*")) + exclude(dependency("io.netty:.*")) + exclude(dependency("org.slf4j:.*")) + exclude(dependency("org.ow2.asm:.*")) + } +} diff --git a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyConfiguration.java b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyConfiguration.java new file mode 100644 index 000000000..ad249eb3b --- /dev/null +++ b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyConfiguration.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ +package org.geysermc.geyser.platform.viaproxy; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import net.raphimc.vialegacy.api.LegacyProtocolVersion; +import net.raphimc.viaproxy.cli.options.Options; +import org.geysermc.geyser.configuration.GeyserJacksonConfiguration; + +import java.io.File; +import java.nio.file.Path; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class GeyserViaProxyConfiguration extends GeyserJacksonConfiguration { + + @Override + public Path getFloodgateKeyPath() { + return new File(GeyserViaProxyPlugin.ROOT_FOLDER, this.getFloodgateKeyFile()).toPath(); + } + + @Override + public int getPingPassthroughInterval() { + int interval = super.getPingPassthroughInterval(); + if (interval < 15 && Options.PROTOCOL_VERSION != null && Options.PROTOCOL_VERSION.olderThanOrEqualTo(LegacyProtocolVersion.r1_6_4)) { + // <= 1.6.4 servers sometimes block incoming connections from an IP address if too many connections are made + interval = 15; + } + return interval; + } + +} diff --git a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyDumpInfo.java b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyDumpInfo.java new file mode 100644 index 000000000..08f3d5371 --- /dev/null +++ b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyDumpInfo.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ +package org.geysermc.geyser.platform.viaproxy; + +import lombok.Getter; +import net.raphimc.viaproxy.ViaProxy; +import net.raphimc.viaproxy.cli.options.Options; +import net.raphimc.viaproxy.plugins.ViaProxyPlugin; +import org.geysermc.geyser.dump.BootstrapDumpInfo; +import org.geysermc.geyser.text.AsteriskSerializer; + +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@Getter +public class GeyserViaProxyDumpInfo extends BootstrapDumpInfo { + + private final String platformVersion; + private final boolean onlineMode; + + @AsteriskSerializer.Asterisk(isIp = true) + private final String serverIP; + private final int serverPort; + private final List plugins; + + public GeyserViaProxyDumpInfo() { + this.platformVersion = ViaProxy.VERSION; + this.onlineMode = Options.ONLINE_MODE; + if (Options.BIND_ADDRESS instanceof InetSocketAddress inetSocketAddress) { + this.serverIP = inetSocketAddress.getHostString(); + this.serverPort = inetSocketAddress.getPort(); + } else { + this.serverIP = "unsupported"; + this.serverPort = 0; + } + this.plugins = new ArrayList<>(); + + for (ViaProxyPlugin plugin : ViaProxy.getPluginManager().getPlugins()) { + this.plugins.add(new PluginInfo(true, plugin.getName(), plugin.getVersion(), "unknown", Collections.singletonList(plugin.getAuthor()))); + } + } + +} diff --git a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyLogger.java b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyLogger.java new file mode 100644 index 000000000..10f414b51 --- /dev/null +++ b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyLogger.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ +package org.geysermc.geyser.platform.viaproxy; + +import net.raphimc.viaproxy.cli.ConsoleFormatter; +import org.apache.logging.log4j.Logger; +import org.geysermc.geyser.GeyserLogger; +import org.geysermc.geyser.command.GeyserCommandSource; + +public class GeyserViaProxyLogger implements GeyserLogger, GeyserCommandSource { + + private final Logger logger; + private boolean debug; + + public GeyserViaProxyLogger(Logger logger) { + this.logger = logger; + } + + @Override + public void severe(String message) { + this.logger.fatal(ConsoleFormatter.convert(message)); + } + + @Override + public void severe(String message, Throwable error) { + this.logger.fatal(ConsoleFormatter.convert(message), error); + } + + @Override + public void error(String message) { + this.logger.error(ConsoleFormatter.convert(message)); + } + + @Override + public void error(String message, Throwable error) { + this.logger.error(ConsoleFormatter.convert(message), error); + } + + @Override + public void warning(String message) { + this.logger.warn(ConsoleFormatter.convert(message)); + } + + @Override + public void info(String message) { + this.logger.info(ConsoleFormatter.convert(message)); + } + + @Override + public void debug(String message) { + if (this.debug) { + this.logger.debug(ConsoleFormatter.convert(message)); + } + } + + @Override + public void setDebug(boolean debug) { + this.debug = debug; + } + + @Override + public boolean isDebug() { + return this.debug; + } + +} diff --git a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyMain.java b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyMain.java new file mode 100644 index 000000000..675c92534 --- /dev/null +++ b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyMain.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.platform.viaproxy; + +import net.raphimc.viaproxy.plugins.PluginManager; +import org.geysermc.geyser.GeyserMain; + +public class GeyserViaProxyMain extends GeyserMain { + + public static void main(String[] args) { + new GeyserViaProxyMain().displayMessage(); + } + + public String getPluginType() { + return "ViaProxy"; + } + + public String getPluginFolder() { + return PluginManager.PLUGINS_DIR.getName(); + } + +} diff --git a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyPlugin.java b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyPlugin.java new file mode 100644 index 000000000..47745df7d --- /dev/null +++ b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyPlugin.java @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ +package org.geysermc.geyser.platform.viaproxy; + +import net.lenni0451.lambdaevents.EventHandler; +import net.raphimc.vialegacy.api.LegacyProtocolVersion; +import net.raphimc.viaproxy.ViaProxy; +import net.raphimc.viaproxy.cli.options.Options; +import net.raphimc.viaproxy.plugins.PluginManager; +import net.raphimc.viaproxy.plugins.ViaProxyPlugin; +import net.raphimc.viaproxy.plugins.events.ConsoleCommandEvent; +import net.raphimc.viaproxy.plugins.events.ProxyStartEvent; +import net.raphimc.viaproxy.plugins.events.ProxyStopEvent; +import net.raphimc.viaproxy.plugins.events.ShouldVerifyOnlineModeEvent; +import org.apache.logging.log4j.LogManager; +import org.geysermc.geyser.GeyserBootstrap; +import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.GeyserLogger; +import org.geysermc.geyser.api.network.AuthType; +import org.geysermc.geyser.api.util.PlatformType; +import org.geysermc.geyser.command.GeyserCommandManager; +import org.geysermc.geyser.configuration.GeyserConfiguration; +import org.geysermc.geyser.dump.BootstrapDumpInfo; +import org.geysermc.geyser.ping.GeyserLegacyPingPassthrough; +import org.geysermc.geyser.ping.IGeyserPingPassthrough; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.text.GeyserLocale; +import org.geysermc.geyser.util.FileUtils; +import org.geysermc.geyser.util.LoopbackUtil; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.UUID; + +public class GeyserViaProxyPlugin extends ViaProxyPlugin implements GeyserBootstrap { + + public static final File ROOT_FOLDER = new File(PluginManager.PLUGINS_DIR, "Geyser"); + + private final GeyserViaProxyLogger logger = new GeyserViaProxyLogger(LogManager.getLogger("Geyser")); + private GeyserViaProxyConfiguration config; + private GeyserImpl geyser; + private GeyserCommandManager commandManager; + private IGeyserPingPassthrough pingPassthrough; + + @Override + public void onEnable() { + ROOT_FOLDER.mkdirs(); + + GeyserLocale.init(this); + this.onGeyserInitialize(); + + ViaProxy.EVENT_MANAGER.register(this); + } + + @Override + public void onDisable() { + this.onGeyserShutdown(); + } + + @EventHandler + private void onConsoleCommand(final ConsoleCommandEvent event) { + final String command = event.getCommand().startsWith("/") ? event.getCommand().substring(1) : event.getCommand(); + if (this.getGeyserCommandManager().runCommand(this.getGeyserLogger(), command + " " + String.join(" ", event.getArgs()))) { + event.setCancelled(true); + } + } + + @EventHandler + private void onShouldVerifyOnlineModeEvent(final ShouldVerifyOnlineModeEvent event) { + final UUID uuid = event.getProxyConnection().getGameProfile().getId(); + if (uuid == null) return; + + final GeyserSession connection = GeyserImpl.getInstance().onlineConnections().stream().filter(s -> s.javaUuid().equals(uuid)).findAny().orElse(null); + if (connection == null) return; + + if (connection.javaUsername().equals(event.getProxyConnection().getGameProfile().getName())) { + event.setCancelled(true); + } + } + + @EventHandler + private void onProxyStart(final ProxyStartEvent event) { + this.onGeyserEnable(); + } + + @EventHandler + private void onProxyStop(final ProxyStopEvent event) { + this.onGeyserDisable(); + } + + @Override + public void onGeyserInitialize() { + if (!this.loadConfig()) { + return; + } + + this.geyser = GeyserImpl.load(PlatformType.VIAPROXY, this); + LoopbackUtil.checkAndApplyLoopback(this.logger); + } + + @Override + public void onGeyserEnable() { + if (GeyserImpl.getInstance().isReloading()) { + if (!this.loadConfig()) { + return; + } + } + + this.commandManager = new GeyserCommandManager(this.geyser); + this.commandManager.init(); + + GeyserImpl.start(); + + if (Options.PROTOCOL_VERSION != null && Options.PROTOCOL_VERSION.newerThanOrEqualTo(LegacyProtocolVersion.b1_8tob1_8_1)) { + // Only initialize the ping passthrough if the protocol version is above beta 1.7.3, as that's when the status protocol was added + this.pingPassthrough = GeyserLegacyPingPassthrough.init(this.geyser); + } + } + + @Override + public void onGeyserDisable() { + this.geyser.disable(); + } + + @Override + public void onGeyserShutdown() { + this.geyser.shutdown(); + } + + @Override + public GeyserConfiguration getGeyserConfig() { + return this.config; + } + + @Override + public GeyserLogger getGeyserLogger() { + return this.logger; + } + + @Override + public GeyserCommandManager getGeyserCommandManager() { + return this.commandManager; + } + + @Override + public IGeyserPingPassthrough getGeyserPingPassthrough() { + return this.pingPassthrough; + } + + @Override + public Path getConfigFolder() { + return ROOT_FOLDER.toPath(); + } + + @Override + public BootstrapDumpInfo getDumpInfo() { + return new GeyserViaProxyDumpInfo(); + } + + @NotNull + @Override + public String getServerBindAddress() { + if (Options.BIND_ADDRESS instanceof InetSocketAddress socketAddress) { + return socketAddress.getHostString(); + } else { + throw new IllegalStateException("Unsupported bind address type: " + Options.BIND_ADDRESS.getClass().getName()); + } + } + + @Override + public int getServerPort() { + if (Options.BIND_ADDRESS instanceof InetSocketAddress socketAddress) { + return socketAddress.getPort(); + } else { + throw new IllegalStateException("Unsupported bind address type: " + Options.BIND_ADDRESS.getClass().getName()); + } + } + + @Override + public boolean testFloodgatePluginPresent() { + return false; + } + + private boolean loadConfig() { + try { + final File configFile = FileUtils.fileOrCopiedFromResource(new File(ROOT_FOLDER, "config.yml"), "config.yml", s -> s.replaceAll("generateduuid", UUID.randomUUID().toString()), this); + this.config = FileUtils.loadConfig(configFile, GeyserViaProxyConfiguration.class); + } catch (IOException e) { + this.logger.severe(GeyserLocale.getLocaleStringLog("geyser.config.failed"), e); + return false; + } + this.config.getRemote().setAuthType(Files.isRegularFile(this.config.getFloodgateKeyPath()) ? AuthType.FLOODGATE : AuthType.OFFLINE); + this.logger.setDebug(this.config.isDebugMode()); + GeyserConfiguration.checkGeyserConfiguration(this.config, this.logger); + return true; + } + +} diff --git a/bootstrap/viaproxy/src/main/resources/viaproxy.yml b/bootstrap/viaproxy/src/main/resources/viaproxy.yml new file mode 100644 index 000000000..f42cda77b --- /dev/null +++ b/bootstrap/viaproxy/src/main/resources/viaproxy.yml @@ -0,0 +1,5 @@ +name: "${name}-ViaProxy" +version: "${version}" +author: "${author}" +main: "org.geysermc.geyser.platform.viaproxy.GeyserViaProxyPlugin" +min-version: "3.2.0" diff --git a/build-logic/src/main/kotlin/geyser.base-conventions.gradle.kts b/build-logic/src/main/kotlin/geyser.base-conventions.gradle.kts index 01c769733..c9f984596 100644 --- a/build-logic/src/main/kotlin/geyser.base-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/geyser.base-conventions.gradle.kts @@ -22,8 +22,8 @@ indra { tasks { processResources { - // Spigot, BungeeCord, Velocity, Fabric - filesMatching(listOf("plugin.yml", "bungee.yml", "velocity-plugin.json", "fabric.mod.json")) { + // Spigot, BungeeCord, Velocity, Fabric, ViaProxy + filesMatching(listOf("plugin.yml", "bungee.yml", "velocity-plugin.json", "fabric.mod.json", "viaproxy.yml")) { expand( "id" to "geyser", "name" to "Geyser", @@ -34,4 +34,4 @@ tasks { ) } } -} \ No newline at end of file +} diff --git a/build.gradle.kts b/build.gradle.kts index a72b8a484..1d434e599 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -23,7 +23,8 @@ val platforms = setOf( projects.bungeecord, projects.spigot, projects.standalone, - projects.velocity + projects.velocity, + projects.viaproxy ).map { it.dependencyProject } subprojects { diff --git a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java index 5ed0c3947..6a8efaba1 100644 --- a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java +++ b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java @@ -44,9 +44,6 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec; import org.geysermc.api.Geyser; -import org.geysermc.geyser.api.command.CommandSource; -import org.geysermc.geyser.api.util.MinecraftVersion; -import org.geysermc.geyser.api.util.PlatformType; import org.geysermc.cumulus.form.Form; import org.geysermc.cumulus.form.util.FormBuilder; import org.geysermc.erosion.packet.Packets; @@ -56,12 +53,15 @@ import org.geysermc.floodgate.crypto.Base64Topping; import org.geysermc.floodgate.crypto.FloodgateCipher; import org.geysermc.floodgate.news.NewsItemAction; import org.geysermc.geyser.api.GeyserApi; +import org.geysermc.geyser.api.command.CommandSource; import org.geysermc.geyser.api.event.EventBus; import org.geysermc.geyser.api.event.EventRegistrar; import org.geysermc.geyser.api.event.lifecycle.*; import org.geysermc.geyser.api.network.AuthType; import org.geysermc.geyser.api.network.BedrockListener; import org.geysermc.geyser.api.network.RemoteServer; +import org.geysermc.geyser.api.util.MinecraftVersion; +import org.geysermc.geyser.api.util.PlatformType; import org.geysermc.geyser.command.GeyserCommandManager; import org.geysermc.geyser.configuration.GeyserConfiguration; import org.geysermc.geyser.entity.EntityDefinitions; @@ -169,6 +169,12 @@ public class GeyserImpl implements GeyserApi { */ private volatile boolean isReloading; + /** + * Determines if Geyser is currently enabled. This is used to determine if {@link #disable()} should be called during {@link #shutdown()}. + */ + @Setter + private boolean isEnabled; + private GeyserImpl(PlatformType platformType, GeyserBootstrap bootstrap) { instance = this; @@ -344,15 +350,17 @@ public class GeyserImpl implements GeyserApi { logger.info("Broadcast port set from system property: " + parsedPort); } - boolean floodgatePresent = bootstrap.testFloodgatePluginPresent(); - if (config.getRemote().authType() == AuthType.FLOODGATE && !floodgatePresent) { - logger.severe(GeyserLocale.getLocaleStringLog("geyser.bootstrap.floodgate.not_installed") + " " - + GeyserLocale.getLocaleStringLog("geyser.bootstrap.floodgate.disabling")); - return; - } else if (config.isAutoconfiguredRemote() && floodgatePresent) { - // Floodgate installed means that the user wants Floodgate authentication - logger.debug("Auto-setting to Floodgate authentication."); - config.getRemote().setAuthType(AuthType.FLOODGATE); + if (platformType != PlatformType.VIAPROXY) { + boolean floodgatePresent = bootstrap.testFloodgatePluginPresent(); + if (config.getRemote().authType() == AuthType.FLOODGATE && !floodgatePresent) { + logger.severe(GeyserLocale.getLocaleStringLog("geyser.bootstrap.floodgate.not_installed") + " " + + GeyserLocale.getLocaleStringLog("geyser.bootstrap.floodgate.disabling")); + return; + } else if (config.isAutoconfiguredRemote() && floodgatePresent) { + // Floodgate installed means that the user wants Floodgate authentication + logger.debug("Auto-setting to Floodgate authentication."); + config.getRemote().setAuthType(AuthType.FLOODGATE); + } } } @@ -639,12 +647,14 @@ public class GeyserImpl implements GeyserApi { Registries.RESOURCE_PACKS.get().clear(); - bootstrap.getGeyserLogger().info(GeyserLocale.getLocaleStringLog("geyser.core.shutdown.done")); + this.setEnabled(false); } public void shutdown() { shuttingDown = true; - this.disable(); + if (isEnabled) { + this.disable(); + } this.commandManager().getCommands().clear(); // Disable extensions, fire the shutdown event @@ -777,6 +787,7 @@ public class GeyserImpl implements GeyserApi { } else { instance.initialize(); } + instance.setEnabled(true); } public GeyserLogger getLogger() { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginDisconnectTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginDisconnectTranslator.java index daf42a68e..c0be2c624 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginDisconnectTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginDisconnectTranslator.java @@ -51,7 +51,7 @@ public class JavaLoginDisconnectTranslator extends PacketTranslator Date: Fri, 23 Feb 2024 16:58:39 +0000 Subject: [PATCH 002/272] NeoForge Platform Support (#3781) * Initial work on Forge platform * Rework modded platforms to use a common module * Add support for integrated worlds on modded platforms * Fix classload errors and move mixins to shared module * Fix Fabric mixins and check min height in mod world manager * Add Forge command support * Add back modrinth publishing * Don't apply application plugin to shared mod sources * Fix docs * Delete unused class * Clean up repositories * - Update to 1.20.2 - set custom refmap name - fixed console commands crashing the server (hasPermission now accepts CommandSourceStack instead of Player) - Forge wants fastutil relocated, so be it Current issues: - ClassNotFound exceptions with classes that are clearly present * - Fix ClassNotFound errors on Forge due to weird Classloader - Dont relocate gson * merge upstream * oh no * Bump lombok, architectury-loom * init: neoforge 1.20.4 support * NeoForge builds Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Archive neoforge artifacts * transformForge -> transformNeoForge * Neoforge boots! * Fix mixins on neoforge * Update build/pr file names * Update mods.toml to new neoforge standard * Fix refmap naming * more fixes - no need to include gson - cleanup nullable/nonnull annotations - add more info to geyser dumps on neoforge * yeet platform executor * yet another temp branch to figure out the runServer task * yeet transitive dependency, that cant be right * Attempt at getting the runServer task to work, part two * Revert the changes for the runServer task, try and shut down the injector * Remove spigot weird bug workaround, shut down properly Also add a compileOnly dependency for the mod module to get rid of spammy false warnings * Update to latest restart changes - fix duplicate nodes crashing neoforge - connector -> geyser in GeyserModCommandExecutor - create command manager early to fix issues with permission gather event * Consistent NeoForge spelling, move some dependencies to the version toml * Add lombok to version catalogue * Add plugins to version catalogue * revert move to buildSrc * Create `assets/geyser/icon.png` to reference icon from a single file on standalone/neoforge/fabric * add fabric permissions api to libs.versions.toml --------- Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> Co-authored-by: onebeastchris Co-authored-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> --- .github/workflows/build.yml | 22 ++- .github/workflows/pullrequest.yml | 9 +- .../geyser/api/pack/PathPackCodec.java | 2 +- .../geyser/api/util/PlatformType.java | 1 + .../main/resources/geyser-fabric.mixins.json | 15 -- bootstrap/mod/build.gradle.kts | 15 ++ bootstrap/mod/fabric/build.gradle.kts | 49 ++++++ bootstrap/mod/fabric/gradle.properties | 1 + .../fabric/GeyserFabricBootstrap.java | 72 ++++++++ .../platform/fabric/GeyserFabricDumpInfo.java | 0 .../platform/fabric/GeyserFabricMain.java | 0 .../platform/fabric/GeyserFabricPlatform.java | 99 +++++++++++ .../fabric/src/main/resources/fabric.mod.json | 8 +- bootstrap/mod/neoforge/build.gradle.kts | 52 ++++++ bootstrap/mod/neoforge/gradle.properties | 1 + .../neoforge/GeyserNeoForgeBootstrap.java | 83 ++++++++++ .../neoforge/GeyserNeoForgeDumpInfo.java | 84 ++++++++++ .../platform/neoforge/GeyserNeoForgeMain.java | 45 +++++ .../GeyserNeoForgePermissionHandler.java | 149 +++++++++++++++++ .../neoforge/GeyserNeoForgePlatform.java | 72 ++++++++ .../platform/neoforge/ModConstants.java | 30 ++++ .../src/main/resources/META-INF/mods.toml | 25 +++ .../platform/mod/GeyserChannelGetter.java | 43 +++++ .../platform/mod/GeyserModBootstrap.java} | 124 ++++++-------- .../mod/GeyserModCompressionDisabler.java | 56 +++++++ .../platform/mod/GeyserModConfiguration.java} | 9 +- .../platform/mod/GeyserModInjector.java | 156 ++++++++++++++++++ .../geyser/platform/mod/GeyserModLogger.java} | 10 +- .../mod/GeyserModUpdateListener.java} | 19 ++- .../platform/mod}/GeyserServerPortGetter.java | 2 +- .../platform/mod}/ModPingPassthrough.java | 7 +- .../command/GeyserModCommandExecutor.java} | 14 +- .../mod/command/ModCommandSender.java} | 10 +- .../mixin/client/IntegratedServerMixin.java | 15 +- .../mixin/server/DedicatedServerMixin.java} | 10 +- .../server/ServerConnectionListenerMixin.java | 46 ++++++ .../mod/platform/GeyserModPlatform.java | 92 +++++++++++ .../mod/world/GeyserModWorldManager.java} | 74 ++++++++- .../mod/src/main/resources/geyser.mixins.json | 18 ++ .../standalone/gui/GeyserStandaloneGUI.java | 2 +- build-logic/build.gradle.kts | 17 +- build-logic/settings.gradle.kts | 11 ++ .../kotlin/geyser.base-conventions.gradle.kts | 6 +- .../geyser.modded-conventions.gradle.kts | 78 ++++----- build.gradle.kts | 24 +-- core/build.gradle.kts | 3 +- .../java/org/geysermc/geyser/GeyserImpl.java | 1 + .../geyser/pack/SkullResourcePackManager.java | 2 +- .../PendingMicrosoftAuthentication.java | 3 +- .../main/resources/assets/geyser}/icon.png | Bin core/src/main/resources/icon.png | Bin 115461 -> 0 bytes gradle.properties | 4 +- gradle/libs.versions.toml | 31 +++- gradle/wrapper/gradle-wrapper.properties | 2 +- settings.gradle.kts | 24 ++- 55 files changed, 1504 insertions(+), 243 deletions(-) delete mode 100644 bootstrap/fabric/src/main/resources/geyser-fabric.mixins.json create mode 100644 bootstrap/mod/build.gradle.kts create mode 100644 bootstrap/mod/fabric/build.gradle.kts create mode 100644 bootstrap/mod/fabric/gradle.properties create mode 100644 bootstrap/mod/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricBootstrap.java rename bootstrap/{ => mod}/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricDumpInfo.java (100%) rename bootstrap/{ => mod}/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricMain.java (100%) create mode 100644 bootstrap/mod/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricPlatform.java rename bootstrap/{ => mod}/fabric/src/main/resources/fabric.mod.json (74%) create mode 100644 bootstrap/mod/neoforge/build.gradle.kts create mode 100644 bootstrap/mod/neoforge/gradle.properties create mode 100644 bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeBootstrap.java create mode 100644 bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeDumpInfo.java create mode 100644 bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeMain.java create mode 100644 bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgePermissionHandler.java create mode 100644 bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgePlatform.java create mode 100644 bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/ModConstants.java create mode 100644 bootstrap/mod/neoforge/src/main/resources/META-INF/mods.toml create mode 100644 bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserChannelGetter.java rename bootstrap/{fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricMod.java => mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java} (70%) create mode 100644 bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModCompressionDisabler.java rename bootstrap/{fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricConfiguration.java => mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModConfiguration.java} (80%) create mode 100644 bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModInjector.java rename bootstrap/{fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricLogger.java => mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModLogger.java} (90%) rename bootstrap/{fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricUpdateListener.java => mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModUpdateListener.java} (68%) rename bootstrap/{fabric/src/main/java/org/geysermc/geyser/platform/fabric => mod/src/main/java/org/geysermc/geyser/platform/mod}/GeyserServerPortGetter.java (97%) rename bootstrap/{fabric/src/main/java/org/geysermc/geyser/platform/fabric => mod/src/main/java/org/geysermc/geyser/platform/mod}/ModPingPassthrough.java (94%) rename bootstrap/{fabric/src/main/java/org/geysermc/geyser/platform/fabric/command/GeyserFabricCommandExecutor.java => mod/src/main/java/org/geysermc/geyser/platform/mod/command/GeyserModCommandExecutor.java} (82%) rename bootstrap/{fabric/src/main/java/org/geysermc/geyser/platform/fabric/command/FabricCommandSender.java => mod/src/main/java/org/geysermc/geyser/platform/mod/command/ModCommandSender.java} (88%) rename bootstrap/{fabric/src/main/java/org/geysermc/geyser/platform/fabric => mod/src/main/java/org/geysermc/geyser/platform/mod}/mixin/client/IntegratedServerMixin.java (85%) rename bootstrap/{fabric/src/main/java/org/geysermc/geyser/platform/fabric/mixin/server/MinecraftDedicatedServerMixin.java => mod/src/main/java/org/geysermc/geyser/platform/mod/mixin/server/DedicatedServerMixin.java} (76%) create mode 100644 bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/mixin/server/ServerConnectionListenerMixin.java create mode 100644 bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/platform/GeyserModPlatform.java rename bootstrap/{fabric/src/main/java/org/geysermc/geyser/platform/fabric/world/GeyserFabricWorldManager.java => mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java} (81%) create mode 100644 bootstrap/mod/src/main/resources/geyser.mixins.json create mode 100644 build-logic/settings.gradle.kts rename bootstrap/fabric/build.gradle.kts => build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts (70%) rename {bootstrap/fabric/src/main/resources/assets/geyser-fabric => core/src/main/resources/assets/geyser}/icon.png (100%) delete mode 100644 core/src/main/resources/icon.png diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 827136b4a..cd579c931 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -47,7 +47,14 @@ jobs: if: success() with: name: Geyser Fabric - path: bootstrap/fabric/build/libs/Geyser-Fabric.jar + path: bootstrap/mod/fabric/build/libs/Geyser-Fabric.jar + if-no-files-found: error + - name: Archive artifacts (Geyser NeoForge) + uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 + if: success() + with: + name: Geyser NeoForge + path: bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar if-no-files-found: error - name: Archive artifacts (Geyser Standalone) uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 @@ -118,7 +125,7 @@ jobs: echo "{\"project\": \"$project\", \"version\": \"$version\", \"id\": $GITHUB_RUN_NUMBER, \"commit\": \"$GITHUB_SHA\"}" > metadata.json rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" metadata.json $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$project/$GITHUB_RUN_NUMBER/ - - name: Publish to Modrinth + - name: Publish to Modrinth (Fabric) uses: gradle/gradle-build-action@3bfe3a46584a206fb8361cdedd0647b0c4204232 if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} env: @@ -126,7 +133,16 @@ jobs: with: arguments: fabric:modrinth gradle-home-cache-cleanup: true - + + - name: Publish to Modrinth (NeoForge) + uses: gradle/gradle-build-action@3bfe3a46584a206fb8361cdedd0647b0c4204232 + if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} + env: + MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }} + with: + arguments: neoforge:modrinth + gradle-home-cache-cleanup: true + - name: Notify Discord if: ${{ (success() || failure()) && github.repository == 'GeyserMC/Geyser' }} # See https://github.com/Tim203/actions-git-discord-webhook/commits diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index f2c8f5d8d..851c087c1 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -57,7 +57,14 @@ jobs: if: success() with: name: Geyser Fabric - path: geyser/bootstrap/fabric/build/libs/Geyser-Fabric.jar + path: geyser/bootstrap/mod/fabric/build/libs/Geyser-Fabric.jar + if-no-files-found: error + - name: Archive artifacts (Geyser NeoForge) + uses: actions/upload-artifact@v3 + if: success() + with: + name: Geyser NeoForge + path: geyser/bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar if-no-files-found: error - name: Archive artifacts (Geyser Standalone) uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 diff --git a/api/src/main/java/org/geysermc/geyser/api/pack/PathPackCodec.java b/api/src/main/java/org/geysermc/geyser/api/pack/PathPackCodec.java index ee5db8242..a3770451a 100644 --- a/api/src/main/java/org/geysermc/geyser/api/pack/PathPackCodec.java +++ b/api/src/main/java/org/geysermc/geyser/api/pack/PathPackCodec.java @@ -42,4 +42,4 @@ public abstract class PathPackCodec extends PackCodec { */ @NonNull public abstract Path path(); -} +} \ No newline at end of file diff --git a/api/src/main/java/org/geysermc/geyser/api/util/PlatformType.java b/api/src/main/java/org/geysermc/geyser/api/util/PlatformType.java index 1abdc0230..cda5e06e4 100644 --- a/api/src/main/java/org/geysermc/geyser/api/util/PlatformType.java +++ b/api/src/main/java/org/geysermc/geyser/api/util/PlatformType.java @@ -34,6 +34,7 @@ public record PlatformType(String platformName) { public static final PlatformType ANDROID = new PlatformType("Android"); public static final PlatformType BUNGEECORD = new PlatformType("BungeeCord"); public static final PlatformType FABRIC = new PlatformType("Fabric"); + public static final PlatformType NEOFORGE = new PlatformType("NeoForge"); public static final PlatformType SPIGOT = new PlatformType("Spigot"); @Deprecated diff --git a/bootstrap/fabric/src/main/resources/geyser-fabric.mixins.json b/bootstrap/fabric/src/main/resources/geyser-fabric.mixins.json deleted file mode 100644 index aeb051809..000000000 --- a/bootstrap/fabric/src/main/resources/geyser-fabric.mixins.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "required": true, - "package": "org.geysermc.geyser.platform.fabric.mixin", - "compatibilityLevel": "JAVA_16", - "refmap": "geyser-fabric-refmap.json", - "client": [ - "client.IntegratedServerMixin" - ], - "server": [ - "server.MinecraftDedicatedServerMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/bootstrap/mod/build.gradle.kts b/bootstrap/mod/build.gradle.kts new file mode 100644 index 000000000..7651a2df2 --- /dev/null +++ b/bootstrap/mod/build.gradle.kts @@ -0,0 +1,15 @@ +architectury { + common("neoforge", "fabric") +} + +loom { + mixin.defaultRefmapName.set("geyser-refmap.json") +} + +dependencies { + api(projects.core) + compileOnly(libs.mixin) + + // Only here to suppress "unknown enum constant EnvType.CLIENT" warnings. DO NOT USE! + compileOnly(libs.fabric.loader) +} \ No newline at end of file diff --git a/bootstrap/mod/fabric/build.gradle.kts b/bootstrap/mod/fabric/build.gradle.kts new file mode 100644 index 000000000..dac042ad7 --- /dev/null +++ b/bootstrap/mod/fabric/build.gradle.kts @@ -0,0 +1,49 @@ +plugins { + application +} + +architectury { + platformSetupLoomIde() + fabric() +} + +dependencies { + modImplementation(libs.fabric.loader) + modApi(libs.fabric.api) + + api(project(":mod", configuration = "namedElements")) + shadow(project(path = ":mod", configuration = "transformProductionFabric")) { + isTransitive = false + } + shadow(projects.core) { + exclude(group = "com.google.guava", module = "guava") + exclude(group = "com.google.code.gson", module = "gson") + exclude(group = "org.slf4j") + exclude(group = "com.nukkitx.fastutil") + exclude(group = "io.netty.incubator") + } + + modImplementation(libs.fabric.permissions) + include(libs.fabric.permissions) +} + +application { + mainClass.set("org.geysermc.geyser.platform.fabric.GeyserFabricMain") +} + +tasks { + remapJar { + archiveBaseName.set("Geyser-Fabric") + } + + remapModrinthJar { + archiveBaseName.set("geyser-fabric") + } +} + +modrinth { + loaders.add("fabric") + dependencies { + required.project("fabric-api") + } +} \ No newline at end of file diff --git a/bootstrap/mod/fabric/gradle.properties b/bootstrap/mod/fabric/gradle.properties new file mode 100644 index 000000000..90ee7a259 --- /dev/null +++ b/bootstrap/mod/fabric/gradle.properties @@ -0,0 +1 @@ +loom.platform=fabric \ No newline at end of file diff --git a/bootstrap/mod/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricBootstrap.java b/bootstrap/mod/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricBootstrap.java new file mode 100644 index 000000000..81e329c03 --- /dev/null +++ b/bootstrap/mod/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricBootstrap.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.platform.fabric; + +import me.lucko.fabric.api.permissions.v0.Permissions; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; +import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents; +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.world.entity.player.Player; +import org.geysermc.geyser.platform.mod.GeyserModBootstrap; +import org.geysermc.geyser.platform.mod.GeyserModUpdateListener; +import org.checkerframework.checker.nullness.qual.NonNull; + +public class GeyserFabricBootstrap extends GeyserModBootstrap implements ModInitializer { + + public GeyserFabricBootstrap() { + super(new GeyserFabricPlatform()); + } + + @Override + public void onInitialize() { + if (FabricLoader.getInstance().getEnvironmentType() == EnvType.SERVER) { + // Set as an event, so we can get the proper IP and port if needed + ServerLifecycleEvents.SERVER_STARTED.register((server) -> { + this.setServer(server); + onGeyserEnable(); + }); + } + + // These are only registered once + ServerLifecycleEvents.SERVER_STOPPING.register((server) -> onGeyserShutdown()); + ServerPlayConnectionEvents.JOIN.register((handler, $, $$) -> GeyserModUpdateListener.onPlayReady(handler.getPlayer())); + + this.onGeyserInitialize(); + } + + @Override + public boolean hasPermission(@NonNull Player source, @NonNull String permissionNode) { + return Permissions.check(source, permissionNode); + } + + @Override + public boolean hasPermission(@NonNull CommandSourceStack source, @NonNull String permissionNode, int permissionLevel) { + return Permissions.check(source, permissionNode, permissionLevel); + } +} diff --git a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricDumpInfo.java b/bootstrap/mod/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricDumpInfo.java similarity index 100% rename from bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricDumpInfo.java rename to bootstrap/mod/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricDumpInfo.java diff --git a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricMain.java b/bootstrap/mod/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricMain.java similarity index 100% rename from bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricMain.java rename to bootstrap/mod/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricMain.java diff --git a/bootstrap/mod/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricPlatform.java b/bootstrap/mod/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricPlatform.java new file mode 100644 index 000000000..4631ab493 --- /dev/null +++ b/bootstrap/mod/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricPlatform.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.platform.fabric; + +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.api.ModContainer; +import net.minecraft.server.MinecraftServer; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.geysermc.geyser.api.util.PlatformType; +import org.geysermc.geyser.dump.BootstrapDumpInfo; +import org.geysermc.geyser.platform.mod.GeyserModBootstrap; +import org.geysermc.geyser.platform.mod.platform.GeyserModPlatform; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Path; +import java.util.Optional; + +public class GeyserFabricPlatform implements GeyserModPlatform { + + private final ModContainer mod; + + public GeyserFabricPlatform() { + this.mod = FabricLoader.getInstance().getModContainer("geyser-fabric").orElseThrow(); + } + + @Override + public @NonNull PlatformType platformType() { + return PlatformType.FABRIC; + } + + @Override + public @NonNull String configPath() { + return "Geyser-Fabric"; + } + + @Override + public @NonNull Path dataFolder(@NonNull String modId) { + return FabricLoader.getInstance().getConfigDir().resolve(modId); + } + + @Override + public @NonNull BootstrapDumpInfo dumpInfo(@NonNull MinecraftServer server) { + return new GeyserFabricDumpInfo(server); + } + + @Override + public boolean testFloodgatePluginPresent(@NonNull GeyserModBootstrap bootstrap) { + Optional floodgate = FabricLoader.getInstance().getModContainer("floodgate"); + if (floodgate.isPresent()) { + Path floodgateDataFolder = FabricLoader.getInstance().getConfigDir().resolve("floodgate"); + bootstrap.getGeyserConfig().loadFloodgate(bootstrap, floodgateDataFolder); + return true; + } + + return false; + } + + @Override + public @Nullable InputStream resolveResource(@NonNull String resource) { + // We need to handle this differently, because Fabric shares the classloader across multiple mods + Path path = this.mod.findPath(resource).orElse(null); + if (path == null) { + return null; + } + + try { + return path.getFileSystem() + .provider() + .newInputStream(path); + } catch (IOException e) { + return null; + } + } +} diff --git a/bootstrap/fabric/src/main/resources/fabric.mod.json b/bootstrap/mod/fabric/src/main/resources/fabric.mod.json similarity index 74% rename from bootstrap/fabric/src/main/resources/fabric.mod.json rename to bootstrap/mod/fabric/src/main/resources/fabric.mod.json index a192109e2..6bd217433 100644 --- a/bootstrap/fabric/src/main/resources/fabric.mod.json +++ b/bootstrap/mod/fabric/src/main/resources/fabric.mod.json @@ -9,18 +9,18 @@ ], "contact": { "website": "${url}", - "repo": "https://github.com/GeyserMC/Geyser-Fabric" + "repo": "https://github.com/GeyserMC/Geyser" }, "license": "MIT", - "icon": "assets/geyser-fabric/icon.png", + "icon": "assets/geyser/icon.png", "environment": "*", "entrypoints": { "main": [ - "org.geysermc.geyser.platform.fabric.GeyserFabricMod" + "org.geysermc.geyser.platform.fabric.GeyserFabricBootstrap" ] }, "mixins": [ - "geyser-fabric.mixins.json" + "geyser.mixins.json" ], "depends": { "fabricloader": ">=0.15.2", diff --git a/bootstrap/mod/neoforge/build.gradle.kts b/bootstrap/mod/neoforge/build.gradle.kts new file mode 100644 index 000000000..d85087542 --- /dev/null +++ b/bootstrap/mod/neoforge/build.gradle.kts @@ -0,0 +1,52 @@ +plugins { + application +} + +architectury { + platformSetupLoomIde() + neoForge() +} + +dependencies { + // See https://github.com/google/guava/issues/6618 + modules { + module("com.google.guava:listenablefuture") { + replacedBy("com.google.guava:guava", "listenablefuture is part of guava") + } + } + + neoForge(libs.neoforge.minecraft) + + api(project(":mod", configuration = "namedElements")) + shadow(project(path = ":mod", configuration = "transformProductionNeoForge")) { + isTransitive = false + } + shadow(projects.core) { + exclude(group = "com.google.guava", module = "guava") + exclude(group = "com.google.code.gson", module = "gson") + exclude(group = "org.slf4j") + exclude(group = "io.netty.incubator") + } +} + +application { + mainClass.set("org.geysermc.geyser.platform.forge.GeyserNeoForgeMain") +} + +tasks { + shadowJar { + relocate("it.unimi.dsi.fastutil", "org.geysermc.relocate.fastutil") + } + + remapJar { + archiveBaseName.set("Geyser-NeoForge") + } + + remapModrinthJar { + archiveBaseName.set("geyser-neoforge") + } +} + +modrinth { + loaders.add("neoforge") +} \ No newline at end of file diff --git a/bootstrap/mod/neoforge/gradle.properties b/bootstrap/mod/neoforge/gradle.properties new file mode 100644 index 000000000..2914393db --- /dev/null +++ b/bootstrap/mod/neoforge/gradle.properties @@ -0,0 +1 @@ +loom.platform=neoforge \ No newline at end of file diff --git a/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeBootstrap.java b/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeBootstrap.java new file mode 100644 index 000000000..67cad1683 --- /dev/null +++ b/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeBootstrap.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.platform.neoforge; + +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.world.entity.player.Player; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.fml.common.Mod; +import net.neoforged.fml.loading.FMLLoader; +import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.event.entity.player.PlayerEvent; +import net.neoforged.neoforge.event.server.ServerStartedEvent; +import net.neoforged.neoforge.event.server.ServerStoppingEvent; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.geysermc.geyser.platform.mod.GeyserModBootstrap; +import org.geysermc.geyser.platform.mod.GeyserModUpdateListener; + +@Mod(ModConstants.MOD_ID) +public class GeyserNeoForgeBootstrap extends GeyserModBootstrap { + + private final GeyserNeoForgePermissionHandler permissionHandler = new GeyserNeoForgePermissionHandler(); + + public GeyserNeoForgeBootstrap() { + super(new GeyserNeoForgePlatform()); + + if (FMLLoader.getDist() == Dist.DEDICATED_SERVER) { + // Set as an event so we can get the proper IP and port if needed + NeoForge.EVENT_BUS.addListener(this::onServerStarted); + } + + NeoForge.EVENT_BUS.addListener(this::onServerStopping); + NeoForge.EVENT_BUS.addListener(this::onPlayerJoin); + NeoForge.EVENT_BUS.addListener(this.permissionHandler::onPermissionGather); + + this.onGeyserInitialize(); + } + + private void onServerStarted(ServerStartedEvent event) { + this.setServer(event.getServer()); + this.onGeyserEnable(); + } + + private void onServerStopping(ServerStoppingEvent event) { + this.onGeyserShutdown(); + } + + private void onPlayerJoin(PlayerEvent.PlayerLoggedInEvent event) { + GeyserModUpdateListener.onPlayReady(event.getEntity()); + } + + @Override + public boolean hasPermission(@NonNull Player source, @NonNull String permissionNode) { + return this.permissionHandler.hasPermission(source, permissionNode); + } + + @Override + public boolean hasPermission(@NonNull CommandSourceStack source, @NonNull String permissionNode, int permissionLevel) { + return this.permissionHandler.hasPermission(source, permissionNode, permissionLevel); + } +} diff --git a/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeDumpInfo.java b/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeDumpInfo.java new file mode 100644 index 000000000..623f68d3a --- /dev/null +++ b/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeDumpInfo.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.platform.neoforge; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.minecraft.server.MinecraftServer; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.fml.ModList; +import net.neoforged.fml.loading.FMLLoader; +import net.neoforged.neoforgespi.language.IModInfo; +import org.geysermc.geyser.dump.BootstrapDumpInfo; +import org.geysermc.geyser.text.AsteriskSerializer; + +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +@Getter +public class GeyserNeoForgeDumpInfo extends BootstrapDumpInfo { + + private final String platformName; + private final String platformVersion; + private final String minecraftVersion; + private final Dist dist; + + @AsteriskSerializer.Asterisk(isIp = true) + private final String serverIP; + private final int serverPort; + private final boolean onlineMode; + private final List mods; + + public GeyserNeoForgeDumpInfo(MinecraftServer server) { + this.platformName = FMLLoader.launcherHandlerName(); + this.platformVersion = FMLLoader.versionInfo().neoForgeVersion(); + this.minecraftVersion = FMLLoader.versionInfo().mcVersion(); + this.dist = FMLLoader.getDist(); + this.serverIP = server.getLocalIp() == null ? "unknown" : server.getLocalIp(); + this.serverPort = server.getPort(); + this.onlineMode = server.usesAuthentication(); + this.mods = new ArrayList<>(); + + for (IModInfo mod : ModList.get().getMods()) { + this.mods.add(new ModInfo( + ModList.get().isLoaded(mod.getModId()), + mod.getModId(), + mod.getVersion().toString(), + mod.getModURL().map(URL::toString).orElse("") + )); + } + } + + @Getter + @AllArgsConstructor + public static class ModInfo { + public boolean enabled; + public String name; + public String version; + public String url; + } +} \ No newline at end of file diff --git a/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeMain.java b/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeMain.java new file mode 100644 index 000000000..70bac2a40 --- /dev/null +++ b/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeMain.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.platform.neoforge; + +import org.geysermc.geyser.GeyserMain; + +public class GeyserNeoForgeMain extends GeyserMain { + + public static void main(String[] args) { + new GeyserNeoForgeMain().displayMessage(); + } + + @Override + public String getPluginType() { + return "NeoForge"; + } + + @Override + public String getPluginFolder() { + return "mods"; + } +} diff --git a/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgePermissionHandler.java b/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgePermissionHandler.java new file mode 100644 index 000000000..0a5f8f052 --- /dev/null +++ b/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgePermissionHandler.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.platform.neoforge; + +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.player.Player; +import net.neoforged.neoforge.server.permission.PermissionAPI; +import net.neoforged.neoforge.server.permission.events.PermissionGatherEvent; +import net.neoforged.neoforge.server.permission.nodes.PermissionDynamicContextKey; +import net.neoforged.neoforge.server.permission.nodes.PermissionNode; +import net.neoforged.neoforge.server.permission.nodes.PermissionType; +import net.neoforged.neoforge.server.permission.nodes.PermissionTypes; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.geysermc.geyser.Constants; +import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.api.command.Command; +import org.geysermc.geyser.command.GeyserCommandManager; + +import java.lang.reflect.Constructor; +import java.util.HashMap; +import java.util.Map; + +public class GeyserNeoForgePermissionHandler { + + private static final Constructor PERMISSION_NODE_CONSTRUCTOR; + + static { + try { + @SuppressWarnings("rawtypes") + Constructor constructor = PermissionNode.class.getDeclaredConstructor( + String.class, + PermissionType.class, + PermissionNode.PermissionResolver.class, + PermissionDynamicContextKey[].class + ); + constructor.setAccessible(true); + PERMISSION_NODE_CONSTRUCTOR = constructor; + } catch (NoSuchMethodException e) { + throw new RuntimeException("Unable to construct PermissionNode!", e); + } + } + + private final Map> permissionNodes = new HashMap<>(); + + public void onPermissionGather(PermissionGatherEvent.Nodes event) { + this.registerNode(Constants.UPDATE_PERMISSION, event); + + GeyserCommandManager commandManager = GeyserImpl.getInstance().commandManager(); + for (Map.Entry entry : commandManager.commands().entrySet()) { + Command command = entry.getValue(); + + // Don't register aliases + if (!command.name().equals(entry.getKey())) { + continue; + } + + this.registerNode(command.permission(), event); + } + + for (Map commands : commandManager.extensionCommands().values()) { + for (Map.Entry entry : commands.entrySet()) { + Command command = entry.getValue(); + + // Don't register aliases + if (!command.name().equals(entry.getKey())) { + continue; + } + + this.registerNode(command.permission(), event); + } + } + } + + public boolean hasPermission(@NonNull Player source, @NonNull String permissionNode) { + PermissionNode node = this.permissionNodes.get(permissionNode); + if (node == null) { + GeyserImpl.getInstance().getLogger().warning("Unable to find permission node " + permissionNode); + return false; + } + + return PermissionAPI.getPermission((ServerPlayer) source, node); + } + + public boolean hasPermission(@NonNull CommandSourceStack source, @NonNull String permissionNode, int permissionLevel) { + if (!source.isPlayer()) { + return true; + } + assert source.getPlayer() != null; + boolean permission = this.hasPermission(source.getPlayer(), permissionNode); + if (!permission) { + return source.getPlayer().hasPermissions(permissionLevel); + } + + return true; + } + + private void registerNode(String node, PermissionGatherEvent.Nodes event) { + PermissionNode permissionNode = this.createNode(node); + + // NeoForge likes to crash if you try and register a duplicate node + if (!event.getNodes().contains(permissionNode)) { + event.addNodes(permissionNode); + this.permissionNodes.put(node, permissionNode); + } + } + + @SuppressWarnings("unchecked") + private PermissionNode createNode(String node) { + // The typical constructors in PermissionNode require a + // mod id, which means our permission nodes end up becoming + // geyser_neoforge. instead of just . We work around + // this by using reflection to access the constructor that + // doesn't require a mod id or ResourceLocation. + try { + return (PermissionNode) PERMISSION_NODE_CONSTRUCTOR.newInstance( + node, + PermissionTypes.BOOLEAN, + (PermissionNode.PermissionResolver) (player, playerUUID, context) -> false, + new PermissionDynamicContextKey[0] + ); + } catch (Exception e) { + throw new RuntimeException("Unable to create permission node " + node, e); + } + } +} diff --git a/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgePlatform.java b/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgePlatform.java new file mode 100644 index 000000000..63abe4a4a --- /dev/null +++ b/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgePlatform.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.platform.neoforge; + +import net.minecraft.server.MinecraftServer; +import net.neoforged.fml.loading.FMLPaths; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.geysermc.geyser.GeyserBootstrap; +import org.geysermc.geyser.api.util.PlatformType; +import org.geysermc.geyser.dump.BootstrapDumpInfo; +import org.geysermc.geyser.platform.mod.GeyserModBootstrap; +import org.geysermc.geyser.platform.mod.platform.GeyserModPlatform; + +import java.io.InputStream; +import java.nio.file.Path; + +public class GeyserNeoForgePlatform implements GeyserModPlatform { + + @Override + public @NonNull PlatformType platformType() { + return PlatformType.NEOFORGE; + } + + @Override + public @NonNull String configPath() { + return "Geyser-NeoForge"; + } + + @Override + public @NonNull Path dataFolder(@NonNull String modId) { + return FMLPaths.CONFIGDIR.get().resolve(modId); + } + + @Override + public @NonNull BootstrapDumpInfo dumpInfo(@NonNull MinecraftServer server) { + return new GeyserNeoForgeDumpInfo(server); + } + + @Override + public boolean testFloodgatePluginPresent(@NonNull GeyserModBootstrap bootstrap) { + return false; // No Floodgate mod for NeoForge yet + } + + @Override + public @Nullable InputStream resolveResource(@NonNull String resource) { + return GeyserBootstrap.class.getClassLoader().getResourceAsStream(resource); + } +} diff --git a/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/ModConstants.java b/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/ModConstants.java new file mode 100644 index 000000000..aa72bb2a0 --- /dev/null +++ b/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/ModConstants.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.platform.neoforge; + +public class ModConstants { + public static final String MOD_ID = "geyser_neoforge"; +} diff --git a/bootstrap/mod/neoforge/src/main/resources/META-INF/mods.toml b/bootstrap/mod/neoforge/src/main/resources/META-INF/mods.toml new file mode 100644 index 000000000..2f9e9b12e --- /dev/null +++ b/bootstrap/mod/neoforge/src/main/resources/META-INF/mods.toml @@ -0,0 +1,25 @@ +modLoader="javafml" +loaderVersion="[1,)" +license="MIT" +[[mods]] +modId="geyser_neoforge" +version="${version}" +displayName="Geyser" +displayURL="https://geysermc.org/" +logoFile= "../assets/geyser/icon.png" +authors="GeyserMC" +description="${description}" +[[mixins]] +config = "geyser.mixins.json" +[[dependencies.geyser_neoforge]] + modId="neoforge" + type="required" + versionRange="[20.4.48-beta,)" + ordering="NONE" + side="BOTH" +[[dependencies.geyser_neoforge]] + modId="minecraft" + type="required" + versionRange="[1.20,1.21)" + ordering="NONE" + side="BOTH" \ No newline at end of file diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserChannelGetter.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserChannelGetter.java new file mode 100644 index 000000000..8dc0026bf --- /dev/null +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserChannelGetter.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.platform.mod; + +import io.netty.channel.ChannelFuture; + +import java.util.List; + +/** + * Represents a getter to the server channels in the connection listener class. + */ +public interface GeyserChannelGetter { + + /** + * Returns the channels. + * + * @return The channels. + */ + List geyser$getChannels(); +} diff --git a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricMod.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java similarity index 70% rename from bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricMod.java rename to bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java index 756063af7..db966ec1a 100644 --- a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricMod.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java @@ -23,21 +23,17 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.geyser.platform.fabric; +package org.geysermc.geyser.platform.mod; import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import lombok.Getter; +import lombok.RequiredArgsConstructor; import lombok.Setter; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.ModInitializer; -import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; -import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents; -import net.fabricmc.loader.api.FabricLoader; -import net.fabricmc.loader.api.ModContainer; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; import net.minecraft.server.MinecraftServer; +import net.minecraft.world.entity.player.Player; import org.apache.logging.log4j.LogManager; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -46,7 +42,6 @@ import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.api.command.Command; import org.geysermc.geyser.api.extension.Extension; -import org.geysermc.geyser.api.util.PlatformType; import org.geysermc.geyser.command.GeyserCommand; import org.geysermc.geyser.command.GeyserCommandManager; import org.geysermc.geyser.configuration.GeyserConfiguration; @@ -54,8 +49,9 @@ import org.geysermc.geyser.dump.BootstrapDumpInfo; import org.geysermc.geyser.level.WorldManager; import org.geysermc.geyser.ping.GeyserLegacyPingPassthrough; import org.geysermc.geyser.ping.IGeyserPingPassthrough; -import org.geysermc.geyser.platform.fabric.command.GeyserFabricCommandExecutor; -import org.geysermc.geyser.platform.fabric.world.GeyserFabricWorldManager; +import org.geysermc.geyser.platform.mod.command.GeyserModCommandExecutor; +import org.geysermc.geyser.platform.mod.platform.GeyserModPlatform; +import org.geysermc.geyser.platform.mod.world.GeyserModWorldManager; import org.geysermc.geyser.text.GeyserLocale; import org.geysermc.geyser.util.FileUtils; @@ -64,58 +60,46 @@ import java.io.IOException; import java.io.InputStream; import java.nio.file.Path; import java.util.Map; -import java.util.Optional; import java.util.UUID; -public class GeyserFabricMod implements ModInitializer, GeyserBootstrap { +@RequiredArgsConstructor +public abstract class GeyserModBootstrap implements GeyserBootstrap { @Getter - private static GeyserFabricMod instance; + private static GeyserModBootstrap instance; + + private final GeyserModPlatform platform; + private GeyserImpl geyser; - private ModContainer mod; private Path dataFolder; @Setter private MinecraftServer server; private GeyserCommandManager geyserCommandManager; - private GeyserFabricConfiguration geyserConfig; - private GeyserFabricLogger geyserLogger; + private GeyserModConfiguration geyserConfig; + private GeyserModInjector geyserInjector; + private GeyserModLogger geyserLogger; private IGeyserPingPassthrough geyserPingPassthrough; private WorldManager geyserWorldManager; - @Override - public void onInitialize() { - instance = this; - mod = FabricLoader.getInstance().getModContainer("geyser-fabric").orElseThrow(); - onGeyserInitialize(); - } - @Override public void onGeyserInitialize() { - if (FabricLoader.getInstance().getEnvironmentType() == EnvType.SERVER) { - // Set as an event, so we can get the proper IP and port if needed - ServerLifecycleEvents.SERVER_STARTED.register((server) -> { - this.server = server; - onGeyserEnable(); - }); - } - - // These are only registered once - ServerLifecycleEvents.SERVER_STOPPING.register((server) -> onGeyserShutdown()); - ServerPlayConnectionEvents.JOIN.register((handler, $, $$) -> GeyserFabricUpdateListener.onPlayReady(handler)); - - dataFolder = FabricLoader.getInstance().getConfigDir().resolve("Geyser-Fabric"); + instance = this; + dataFolder = this.platform.dataFolder(this.platform.configPath()); GeyserLocale.init(this); if (!loadConfig()) { return; } - this.geyserLogger = new GeyserFabricLogger(geyserConfig.isDebugMode()); + this.geyserLogger = new GeyserModLogger(geyserConfig.isDebugMode()); GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger); - this.geyser = GeyserImpl.load(PlatformType.FABRIC, this); + this.geyser = GeyserImpl.load(this.platform.platformType(), this); + + // Create command manager here, since the permission handler on neo needs it + this.geyserCommandManager = new GeyserCommandManager(geyser); + this.geyserCommandManager.init(); } - @Override public void onGeyserEnable() { if (GeyserImpl.getInstance().isReloading()) { if (!loadConfig()) { @@ -123,35 +107,37 @@ public class GeyserFabricMod implements ModInitializer, GeyserBootstrap { } this.geyserLogger.setDebug(geyserConfig.isDebugMode()); GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger); - } else { - this.geyserCommandManager = new GeyserCommandManager(geyser); - this.geyserCommandManager.init(); } + GeyserImpl.start(); + if (geyserConfig.isLegacyPingPassthrough()) { this.geyserPingPassthrough = GeyserLegacyPingPassthrough.init(geyser); } else { this.geyserPingPassthrough = new ModPingPassthrough(server, geyserLogger); } - GeyserImpl.start(); - - // No need to re-register commands, or re-recreate the world manager when reloading + // No need to re-register commands, or try to re-inject if (GeyserImpl.getInstance().isReloading()) { return; } - this.geyserWorldManager = new GeyserFabricWorldManager(server); + this.geyserWorldManager = new GeyserModWorldManager(server); + + // We want to do this late in the server startup process to allow other mods + // To do their job injecting, then connect into *that* + this.geyserInjector = new GeyserModInjector(server, this.platform); + this.geyserInjector.initializeLocalChannel(this); // Start command building // Set just "geyser" as the help command - GeyserFabricCommandExecutor helpExecutor = new GeyserFabricCommandExecutor(geyser, + GeyserModCommandExecutor helpExecutor = new GeyserModCommandExecutor(geyser, (GeyserCommand) geyser.commandManager().getCommands().get("help")); LiteralArgumentBuilder builder = Commands.literal("geyser").executes(helpExecutor); // Register all subcommands as valid for (Map.Entry command : geyser.commandManager().getCommands().entrySet()) { - GeyserFabricCommandExecutor executor = new GeyserFabricCommandExecutor(geyser, (GeyserCommand) command.getValue()); + GeyserModCommandExecutor executor = new GeyserModCommandExecutor(geyser, (GeyserCommand) command.getValue()); builder.then(Commands.literal(command.getKey()) .executes(executor) // Could also test for Bedrock but depending on when this is called it may backfire @@ -171,12 +157,12 @@ public class GeyserFabricMod implements ModInitializer, GeyserBootstrap { } // Register help command for just "/" - GeyserFabricCommandExecutor extensionHelpExecutor = new GeyserFabricCommandExecutor(geyser, + GeyserModCommandExecutor extensionHelpExecutor = new GeyserModCommandExecutor(geyser, (GeyserCommand) extensionCommands.get("help")); LiteralArgumentBuilder extCmdBuilder = Commands.literal(extensionMapEntry.getKey().description().id()).executes(extensionHelpExecutor); for (Map.Entry command : extensionCommands.entrySet()) { - GeyserFabricCommandExecutor executor = new GeyserFabricCommandExecutor(geyser, (GeyserCommand) command.getValue()); + GeyserModCommandExecutor executor = new GeyserModCommandExecutor(geyser, (GeyserCommand) command.getValue()); extCmdBuilder.then(Commands.literal(command.getKey()) .executes(executor) .requires(executor::testPermission) @@ -201,11 +187,14 @@ public class GeyserFabricMod implements ModInitializer, GeyserBootstrap { geyser.shutdown(); geyser = null; } - this.server = null; + if (geyserInjector != null) { + geyserInjector.shutdown(); + this.server = null; + } } @Override - public GeyserConfiguration getGeyserConfig() { + public GeyserModConfiguration getGeyserConfig() { return geyserConfig; } @@ -236,7 +225,7 @@ public class GeyserFabricMod implements ModInitializer, GeyserBootstrap { @Override public BootstrapDumpInfo getDumpInfo() { - return new GeyserFabricDumpInfo(server); + return this.platform.dumpInfo(this.server); } @Override @@ -258,32 +247,19 @@ public class GeyserFabricMod implements ModInitializer, GeyserBootstrap { @Override public boolean testFloodgatePluginPresent() { - Optional floodgate = FabricLoader.getInstance().getModContainer("floodgate"); - if (floodgate.isPresent()) { - geyserConfig.loadFloodgate(this, floodgate.orElse(null)); - return true; - } - return false; + return this.platform.testFloodgatePluginPresent(this); } @Nullable @Override public InputStream getResourceOrNull(String resource) { - // We need to handle this differently, because Fabric shares the classloader across multiple mods - Path path = this.mod.findPath(resource).orElse(null); - if (path == null) { - return null; - } - - try { - return path.getFileSystem() - .provider() - .newInputStream(path); - } catch (IOException e) { - return null; - } + return this.platform.resolveResource(resource); } + public abstract boolean hasPermission(@NonNull Player source, @NonNull String permissionNode); + + public abstract boolean hasPermission(@NonNull CommandSourceStack source, @NonNull String permissionNode, int permissionLevel); + @SuppressWarnings("BooleanMethodIsAlwaysInverted") private boolean loadConfig() { try { @@ -294,10 +270,10 @@ public class GeyserFabricMod implements ModInitializer, GeyserBootstrap { File configFile = FileUtils.fileOrCopiedFromResource(dataFolder.resolve("config.yml").toFile(), "config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()), this); - this.geyserConfig = FileUtils.loadConfig(configFile, GeyserFabricConfiguration.class); + this.geyserConfig = FileUtils.loadConfig(configFile, GeyserModConfiguration.class); return true; } catch (IOException ex) { - LogManager.getLogger("geyser-fabric").error(GeyserLocale.getLocaleStringLog("geyser.config.failed"), ex); + LogManager.getLogger("geyser").error(GeyserLocale.getLocaleStringLog("geyser.config.failed"), ex); ex.printStackTrace(); return false; } diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModCompressionDisabler.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModCompressionDisabler.java new file mode 100644 index 000000000..631a21510 --- /dev/null +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModCompressionDisabler.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019-2021 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.platform.mod; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelOutboundHandlerAdapter; +import io.netty.channel.ChannelPromise; +import net.minecraft.network.protocol.login.ClientboundGameProfilePacket; +import net.minecraft.network.protocol.login.ClientboundLoginCompressionPacket; + +/** + * Disables the compression packet (and the compression handlers from being added to the pipeline) for Geyser clients + * that won't be receiving the data over the network. + *

+ * As of 1.8 - 1.17.1, compression is enabled in the Netty pipeline by adding a listener after a packet is written. + * If we simply "cancel" or don't forward the packet, then the listener is never called. + */ +public class GeyserModCompressionDisabler extends ChannelOutboundHandlerAdapter { + + @Override + public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { + Class msgClass = msg.getClass(); + // Don't let any compression packet get through + if (!ClientboundLoginCompressionPacket.class.isAssignableFrom(msgClass)) { + if (ClientboundGameProfilePacket.class.isAssignableFrom(msgClass)) { + + // We're past the point that a compression packet can be sent, so we can safely yeet ourselves away + ctx.channel().pipeline().remove(this); + } + super.write(ctx, msg, promise); + } + } +} diff --git a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricConfiguration.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModConfiguration.java similarity index 80% rename from bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricConfiguration.java rename to bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModConfiguration.java index f557d16c0..a24380bd6 100644 --- a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricConfiguration.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModConfiguration.java @@ -23,23 +23,20 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.geyser.platform.fabric; +package org.geysermc.geyser.platform.mod; import com.fasterxml.jackson.annotation.JsonIgnore; -import net.fabricmc.loader.api.FabricLoader; -import net.fabricmc.loader.api.ModContainer; import org.geysermc.geyser.FloodgateKeyLoader; import org.geysermc.geyser.configuration.GeyserJacksonConfiguration; import java.nio.file.Path; -public class GeyserFabricConfiguration extends GeyserJacksonConfiguration { +public class GeyserModConfiguration extends GeyserJacksonConfiguration { @JsonIgnore private Path floodgateKeyPath; - public void loadFloodgate(GeyserFabricMod geyser, ModContainer floodgate) { + public void loadFloodgate(GeyserModBootstrap geyser, Path floodgateDataFolder) { Path geyserDataFolder = geyser.getConfigFolder(); - Path floodgateDataFolder = floodgate != null ? FabricLoader.getInstance().getConfigDir().resolve("floodgate") : null; floodgateKeyPath = FloodgateKeyLoader.getKeyPath(this, floodgateDataFolder, geyserDataFolder, geyser.getGeyserLogger()); } diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModInjector.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModInjector.java new file mode 100644 index 000000000..06496293f --- /dev/null +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModInjector.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.platform.mod; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.DefaultEventLoopGroup; +import io.netty.channel.local.LocalAddress; +import io.netty.util.concurrent.DefaultThreadFactory; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.network.ServerConnectionListener; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.geysermc.geyser.GeyserBootstrap; +import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.network.netty.GeyserInjector; +import org.geysermc.geyser.network.netty.LocalServerChannelWrapper; +import org.geysermc.geyser.platform.mod.platform.GeyserModPlatform; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.List; + +public class GeyserModInjector extends GeyserInjector { + + private final MinecraftServer server; + private final GeyserModPlatform platform; + private DefaultEventLoopGroup eventLoopGroup; + + /** + * Used to uninject ourselves on shutdown. + */ + private List allServerChannels; + + public GeyserModInjector(MinecraftServer server, GeyserModPlatform platform) { + this.server = server; + this.platform = platform; + } + + @Override + protected void initializeLocalChannel0(GeyserBootstrap bootstrap) throws Exception { + ServerConnectionListener connection = this.server.getConnection(); + + // Find the channel that Minecraft uses to listen to connections + ChannelFuture listeningChannel = null; + this.allServerChannels = ((GeyserChannelGetter) connection).geyser$getChannels(); + for (ChannelFuture o : allServerChannels) { + listeningChannel = o; + break; + } + + if (listeningChannel == null) { + throw new RuntimeException("Unable to find listening channel!"); + } + + // Making this a function prevents childHandler from being treated as a non-final variable + ChannelInitializer childHandler = getChildHandler(bootstrap, listeningChannel); + // This method is what initializes the connection in Java Edition, after Netty is all set. + Method initChannel = childHandler.getClass().getDeclaredMethod("initChannel", Channel.class); + initChannel.setAccessible(true); + + // Separate variable so we can shut it down later + eventLoopGroup = new DefaultEventLoopGroup(0, new DefaultThreadFactory("Geyser " + this.platform.platformType().platformName() + " connection thread", Thread.MAX_PRIORITY)); + ChannelFuture channelFuture = (new ServerBootstrap() + .channel(LocalServerChannelWrapper.class) + .childHandler(new ChannelInitializer<>() { + @Override + protected void initChannel(@NonNull Channel ch) throws Exception { + initChannel.invoke(childHandler, ch); + + if (bootstrap.getGeyserConfig().isDisableCompression()) { + ch.pipeline().addAfter("encoder", "geyser-compression-disabler", new GeyserModCompressionDisabler()); + } + } + }) + // Set to MAX_PRIORITY as MultithreadEventLoopGroup#newDefaultThreadFactory which DefaultEventLoopGroup implements does by default + .group(eventLoopGroup) + .localAddress(LocalAddress.ANY)) + .bind() + .syncUninterruptibly(); + // We don't need to add to the list, but plugins like ProtocolSupport and ProtocolLib that add to the main pipeline + // will work when we add to the list. + allServerChannels.add(channelFuture); + this.localChannel = channelFuture; + this.serverSocketAddress = channelFuture.channel().localAddress(); + } + + @SuppressWarnings("unchecked") + private ChannelInitializer getChildHandler(GeyserBootstrap bootstrap, ChannelFuture listeningChannel) { + List names = listeningChannel.channel().pipeline().names(); + ChannelInitializer childHandler = null; + for (String name : names) { + ChannelHandler handler = listeningChannel.channel().pipeline().get(name); + try { + Field childHandlerField = handler.getClass().getDeclaredField("childHandler"); + childHandlerField.setAccessible(true); + childHandler = (ChannelInitializer) childHandlerField.get(handler); + break; + } catch (Exception e) { + if (bootstrap.getGeyserConfig().isDebugMode()) { + bootstrap.getGeyserLogger().debug("The handler " + name + " isn't a ChannelInitializer. THIS ERROR IS SAFE TO IGNORE!"); + e.printStackTrace(); + } + } + } + if (childHandler == null) { + throw new RuntimeException(); + } + return childHandler; + } + + @Override + public void shutdown() { + if (this.allServerChannels != null) { + this.allServerChannels.remove(this.localChannel); + this.allServerChannels = null; + } + + if (eventLoopGroup != null) { + try { + eventLoopGroup.shutdownGracefully().sync(); + eventLoopGroup = null; + } catch (Exception e) { + GeyserImpl.getInstance().getLogger().error("Unable to shut down injector! " + e.getMessage()); + e.printStackTrace(); + } + } + + super.shutdown(); + } +} diff --git a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricLogger.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModLogger.java similarity index 90% rename from bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricLogger.java rename to bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModLogger.java index 180197f2d..444b725e9 100644 --- a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricLogger.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModLogger.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.geyser.platform.fabric; +package org.geysermc.geyser.platform.mod; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; @@ -32,12 +32,12 @@ import org.apache.logging.log4j.Logger; import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.text.ChatColor; -public class GeyserFabricLogger implements GeyserLogger { - private final Logger logger = LogManager.getLogger("geyser-fabric"); +public class GeyserModLogger implements GeyserLogger { + private final Logger logger = LogManager.getLogger("geyser"); private boolean debug; - public GeyserFabricLogger(boolean isDebug) { + public GeyserModLogger(boolean isDebug) { debug = isDebug; } @@ -73,7 +73,7 @@ public class GeyserFabricLogger implements GeyserLogger { @Override public void sendMessage(Component message) { - // As of Java Edition 1.19.2, Fabric's console doesn't natively support legacy format + // As of Java Edition 1.19.2, Minecraft's console doesn't natively support legacy format String flattened = LegacyComponentSerializer.legacySection().serialize(message); // Add the reset at the end, or else format will persist... forever. // https://cdn.discordapp.com/attachments/573909525132738590/1033904509170225242/unknown.png diff --git a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricUpdateListener.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModUpdateListener.java similarity index 68% rename from bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricUpdateListener.java rename to bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModUpdateListener.java index 1ea69cbe2..11ca0bc4f 100644 --- a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricUpdateListener.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModUpdateListener.java @@ -23,21 +23,22 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.geyser.platform.fabric; +package org.geysermc.geyser.platform.mod; -import me.lucko.fabric.api.permissions.v0.Permissions; -import net.minecraft.server.network.ServerGamePacketListenerImpl; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.world.entity.player.Player; import org.geysermc.geyser.Constants; -import org.geysermc.geyser.platform.fabric.command.FabricCommandSender; +import org.geysermc.geyser.platform.mod.command.ModCommandSender; import org.geysermc.geyser.util.VersionCheckUtils; -public final class GeyserFabricUpdateListener { - public static void onPlayReady(ServerGamePacketListenerImpl handler) { - if (Permissions.check(handler.player, Constants.UPDATE_PERMISSION, 2)) { - VersionCheckUtils.checkForGeyserUpdate(() -> new FabricCommandSender(handler.player.createCommandSourceStack())); +public final class GeyserModUpdateListener { + public static void onPlayReady(Player player) { + CommandSourceStack stack = player.createCommandSourceStack(); + if (GeyserModBootstrap.getInstance().hasPermission(stack, Constants.UPDATE_PERMISSION, 2)) { + VersionCheckUtils.checkForGeyserUpdate(() -> new ModCommandSender(stack)); } } - private GeyserFabricUpdateListener() { + private GeyserModUpdateListener() { } } diff --git a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserServerPortGetter.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserServerPortGetter.java similarity index 97% rename from bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserServerPortGetter.java rename to bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserServerPortGetter.java index 4f1c8b638..fad0d1678 100644 --- a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserServerPortGetter.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserServerPortGetter.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.geyser.platform.fabric; +package org.geysermc.geyser.platform.mod; import net.minecraft.server.MinecraftServer; diff --git a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/ModPingPassthrough.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/ModPingPassthrough.java similarity index 94% rename from bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/ModPingPassthrough.java rename to bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/ModPingPassthrough.java index e74be7fb7..12d690d83 100644 --- a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/ModPingPassthrough.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/ModPingPassthrough.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.geyser.platform.fabric; +package org.geysermc.geyser.platform.mod; import lombok.AllArgsConstructor; import net.kyori.adventure.text.Component; @@ -39,10 +39,11 @@ import net.minecraft.network.protocol.status.ServerStatusPacketListener; import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket; import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerStatusPacketListenerImpl; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.ping.GeyserPingInfo; import org.geysermc.geyser.ping.IGeyserPingPassthrough; -import org.jetbrains.annotations.Nullable; import java.net.InetSocketAddress; import java.util.Objects; @@ -100,7 +101,7 @@ public class ModPingPassthrough implements IGeyserPingPassthrough { } @Override - public void send(Packet packet, @Nullable PacketSendListener packetSendListener, boolean bl) { + public void send(@NonNull Packet packet, @Nullable PacketSendListener packetSendListener, boolean bl) { if (packet instanceof ClientboundStatusResponsePacket statusResponse) { status = statusResponse.status(); } diff --git a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/command/GeyserFabricCommandExecutor.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/command/GeyserModCommandExecutor.java similarity index 82% rename from bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/command/GeyserFabricCommandExecutor.java rename to bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/command/GeyserModCommandExecutor.java index 86b50d431..694dc732e 100644 --- a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/command/GeyserFabricCommandExecutor.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/command/GeyserModCommandExecutor.java @@ -23,31 +23,31 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.geyser.platform.fabric.command; +package org.geysermc.geyser.platform.mod.command; import com.mojang.brigadier.Command; import com.mojang.brigadier.context.CommandContext; -import me.lucko.fabric.api.permissions.v0.Permissions; import net.minecraft.commands.CommandSourceStack; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.command.GeyserCommand; import org.geysermc.geyser.command.GeyserCommandExecutor; +import org.geysermc.geyser.platform.mod.GeyserModBootstrap; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.text.GeyserLocale; import java.util.Collections; -public class GeyserFabricCommandExecutor extends GeyserCommandExecutor implements Command { +public class GeyserModCommandExecutor extends GeyserCommandExecutor implements Command { private final GeyserCommand command; - public GeyserFabricCommandExecutor(GeyserImpl connector, GeyserCommand command) { - super(connector, Collections.singletonMap(command.name(), command)); + public GeyserModCommandExecutor(GeyserImpl geyser, GeyserCommand command) { + super(geyser, Collections.singletonMap(command.name(), command)); this.command = command; } public boolean testPermission(CommandSourceStack source) { - return Permissions.check(source, command.permission(), command.isSuggestedOpOnly() ? 2 : 0); + return GeyserModBootstrap.getInstance().hasPermission(source, command.permission(), command.isSuggestedOpOnly() ? 2 : 0); } @Override @@ -57,7 +57,7 @@ public class GeyserFabricCommandExecutor extends GeyserCommandExecutor implement public int runWithArgs(CommandContext context, String args) { CommandSourceStack source = context.getSource(); - FabricCommandSender sender = new FabricCommandSender(source); + ModCommandSender sender = new ModCommandSender(source); GeyserSession session = getGeyserSession(sender); if (!testPermission(source)) { sender.sendMessage(ChatColor.RED + GeyserLocale.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", sender.locale())); diff --git a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/command/FabricCommandSender.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/command/ModCommandSender.java similarity index 88% rename from bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/command/FabricCommandSender.java rename to bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/command/ModCommandSender.java index 28875ec6e..17154ffd8 100644 --- a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/command/FabricCommandSender.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/command/ModCommandSender.java @@ -23,9 +23,8 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.geyser.platform.fabric.command; +package org.geysermc.geyser.platform.mod.command; -import me.lucko.fabric.api.permissions.v0.Permissions; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.minecraft.commands.CommandSourceStack; import net.minecraft.network.chat.Component; @@ -33,15 +32,16 @@ import net.minecraft.server.level.ServerPlayer; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.command.GeyserCommandSource; +import org.geysermc.geyser.platform.mod.GeyserModBootstrap; import org.geysermc.geyser.text.ChatColor; import java.util.Objects; -public class FabricCommandSender implements GeyserCommandSource { +public class ModCommandSender implements GeyserCommandSource { private final CommandSourceStack source; - public FabricCommandSender(CommandSourceStack source) { + public ModCommandSender(CommandSourceStack source) { this.source = source; } @@ -76,6 +76,6 @@ public class FabricCommandSender implements GeyserCommandSource { @Override public boolean hasPermission(String permission) { - return Permissions.check(source, permission, source.getServer().getOperatorUserPermissionLevel()); + return GeyserModBootstrap.getInstance().hasPermission(source, permission, source.getServer().getOperatorUserPermissionLevel()); } } diff --git a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/mixin/client/IntegratedServerMixin.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/mixin/client/IntegratedServerMixin.java similarity index 85% rename from bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/mixin/client/IntegratedServerMixin.java rename to bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/mixin/client/IntegratedServerMixin.java index 999a077bb..4db1165fc 100644 --- a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/mixin/client/IntegratedServerMixin.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/mixin/client/IntegratedServerMixin.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,18 +23,16 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.geyser.platform.fabric.mixin.client; +package org.geysermc.geyser.platform.mod.mixin.client; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; import net.minecraft.client.Minecraft; import net.minecraft.client.server.IntegratedServer; import net.minecraft.network.chat.Component; import net.minecraft.server.MinecraftServer; import net.minecraft.world.level.GameType; import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.platform.fabric.GeyserFabricMod; -import org.geysermc.geyser.platform.fabric.GeyserServerPortGetter; +import org.geysermc.geyser.platform.mod.GeyserModBootstrap; +import org.geysermc.geyser.platform.mod.GeyserServerPortGetter; import org.geysermc.geyser.text.GeyserLocale; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -45,7 +43,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.Objects; -@Environment(EnvType.CLIENT) @Mixin(IntegratedServer.class) public class IntegratedServerMixin implements GeyserServerPortGetter { @Shadow @@ -57,8 +54,8 @@ public class IntegratedServerMixin implements GeyserServerPortGetter { private void onOpenToLan(GameType gameType, boolean cheatsAllowed, int port, CallbackInfoReturnable cir) { if (cir.getReturnValueZ()) { // If the LAN is opened, starts Geyser. - GeyserFabricMod.getInstance().setServer((MinecraftServer) (Object) this); - GeyserFabricMod.getInstance().onGeyserEnable(); + GeyserModBootstrap.getInstance().setServer((MinecraftServer) (Object) this); + GeyserModBootstrap.getInstance().onGeyserEnable(); // Ensure player locale has been loaded, in case it's different from Java system language GeyserLocale.loadGeyserLocale(this.minecraft.options.languageCode); // Give indication that Geyser is loaded diff --git a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/mixin/server/MinecraftDedicatedServerMixin.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/mixin/server/DedicatedServerMixin.java similarity index 76% rename from bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/mixin/server/MinecraftDedicatedServerMixin.java rename to bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/mixin/server/DedicatedServerMixin.java index 23e148775..3b809d321 100644 --- a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/mixin/server/MinecraftDedicatedServerMixin.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/mixin/server/DedicatedServerMixin.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.geyser.platform.fabric.mixin.server; +package org.geysermc.geyser.platform.mod.mixin.server; import com.mojang.datafixers.DataFixer; import net.minecraft.server.MinecraftServer; @@ -33,14 +33,14 @@ import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.server.level.progress.ChunkProgressListenerFactory; import net.minecraft.server.packs.repository.PackRepository; import net.minecraft.world.level.storage.LevelStorageSource; -import org.geysermc.geyser.platform.fabric.GeyserServerPortGetter; +import org.geysermc.geyser.platform.mod.GeyserServerPortGetter; import org.spongepowered.asm.mixin.Mixin; import java.net.Proxy; @Mixin(DedicatedServer.class) -public abstract class MinecraftDedicatedServerMixin extends MinecraftServer implements GeyserServerPortGetter { - public MinecraftDedicatedServerMixin(Thread thread, LevelStorageSource.LevelStorageAccess levelStorageAccess, PackRepository packRepository, WorldStem worldStem, Proxy proxy, DataFixer dataFixer, Services services, ChunkProgressListenerFactory chunkProgressListenerFactory) { +public abstract class DedicatedServerMixin extends MinecraftServer implements GeyserServerPortGetter { + public DedicatedServerMixin(Thread thread, LevelStorageSource.LevelStorageAccess levelStorageAccess, PackRepository packRepository, WorldStem worldStem, Proxy proxy, DataFixer dataFixer, Services services, ChunkProgressListenerFactory chunkProgressListenerFactory) { super(thread, levelStorageAccess, packRepository, worldStem, proxy, dataFixer, services, chunkProgressListenerFactory); } diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/mixin/server/ServerConnectionListenerMixin.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/mixin/server/ServerConnectionListenerMixin.java new file mode 100644 index 000000000..52941d631 --- /dev/null +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/mixin/server/ServerConnectionListenerMixin.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.platform.mod.mixin.server; + +import io.netty.channel.ChannelFuture; +import net.minecraft.server.network.ServerConnectionListener; +import org.geysermc.geyser.platform.mod.GeyserChannelGetter; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.List; + +@Mixin(ServerConnectionListener.class) +public abstract class ServerConnectionListenerMixin implements GeyserChannelGetter { + + @Shadow @Final private List channels; + + @Override + public List geyser$getChannels() { + return this.channels; + } +} diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/platform/GeyserModPlatform.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/platform/GeyserModPlatform.java new file mode 100644 index 000000000..2f615591b --- /dev/null +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/platform/GeyserModPlatform.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.platform.mod.platform; + +import net.minecraft.server.MinecraftServer; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.geysermc.geyser.api.util.PlatformType; +import org.geysermc.geyser.dump.BootstrapDumpInfo; +import org.geysermc.geyser.platform.mod.GeyserModBootstrap; + +import java.io.InputStream; +import java.nio.file.Path; + +/** + * An interface which holds common methods that have different + * APIs on their respective mod platforms. + */ +public interface GeyserModPlatform { + + /** + * Gets the {@link PlatformType} of the mod platform. + * + * @return the platform type of the mod platform + */ + @NonNull + PlatformType platformType(); + + /** + * Gets the config path of the mod platform. + * + * @return the config path of the mod platform + */ + @NonNull + String configPath(); + + /** + * Gets the data folder of the mod platform. + * + * @return the data folder of the mod platform + */ + @NonNull + Path dataFolder(@NonNull String modId); + + /** + * Gets the dump info of the mod platform. + * + * @param server the server to get the dump info from + * @return the dump info of the mod platform + */ + @NonNull + BootstrapDumpInfo dumpInfo(@NonNull MinecraftServer server); + + /** + * Tests if the Floodgate plugin is present on the mod platform. + * + * @return {@code true} if the Floodgate plugin is present on the mod platform, {@code false} otherwise + */ + boolean testFloodgatePluginPresent(@NonNull GeyserModBootstrap bootstrap); + + /** + * Resolves a resource from the mod jar. + * + * @param resource the name of the resource + * @return the input stream of the resource + */ + @Nullable + InputStream resolveResource(@NonNull String resource); +} diff --git a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/world/GeyserFabricWorldManager.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java similarity index 81% rename from bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/world/GeyserFabricWorldManager.java rename to bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java index 9d7b81831..04c538632 100644 --- a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/world/GeyserFabricWorldManager.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java @@ -23,22 +23,41 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.geyser.platform.fabric.world; +package org.geysermc.geyser.platform.mod.world; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo; -import me.lucko.fabric.api.permissions.v0.Permissions; +import net.minecraft.SharedConstants; import net.minecraft.core.BlockPos; -import net.minecraft.nbt.*; +import net.minecraft.nbt.ByteArrayTag; +import net.minecraft.nbt.ByteTag; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.DoubleTag; +import net.minecraft.nbt.EndTag; +import net.minecraft.nbt.FloatTag; +import net.minecraft.nbt.IntArrayTag; +import net.minecraft.nbt.IntTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.LongArrayTag; +import net.minecraft.nbt.LongTag; +import net.minecraft.nbt.ShortTag; +import net.minecraft.nbt.StringTag; +import net.minecraft.nbt.Tag; +import net.minecraft.nbt.TagVisitor; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.WritableBookItem; import net.minecraft.world.item.WrittenBookItem; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BannerBlockEntity; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.LecternBlockEntity; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkStatus; import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.chunk.LevelChunkSection; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; @@ -46,6 +65,8 @@ import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; import org.geysermc.erosion.util.LecternUtils; import org.geysermc.geyser.level.GeyserWorldManager; +import org.geysermc.geyser.network.GameProtocol; +import org.geysermc.geyser.platform.mod.GeyserModBootstrap; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.BlockEntityUtils; @@ -54,13 +75,54 @@ import java.util.List; import java.util.Objects; import java.util.concurrent.CompletableFuture; -public class GeyserFabricWorldManager extends GeyserWorldManager { +public class GeyserModWorldManager extends GeyserWorldManager { private final MinecraftServer server; - public GeyserFabricWorldManager(MinecraftServer server) { + public GeyserModWorldManager(MinecraftServer server) { this.server = server; } + @Override + public int getBlockAt(GeyserSession session, int x, int y, int z) { + // If the protocol version of Geyser and the server are not the + // same, fallback to the chunk cache. May be able to update this + // in the future to use ViaVersion however, like Spigot does. + if (SharedConstants.getCurrentVersion().getProtocolVersion() != GameProtocol.getJavaProtocolVersion()) { + return super.getBlockAt(session, x, y, z); + } + + ServerPlayer player = this.getPlayer(session); + if (player == null) { + return 0; + } + + Level level = player.level(); + if (y < level.getMinBuildHeight()) { + return 0; + } + + ChunkAccess chunk = level.getChunkSource().getChunk(x >> 4, z >> 4, ChunkStatus.FULL, false); + if (chunk == null) { + return 0; + } + + int worldOffset = level.getMinBuildHeight() >> 4; + int chunkOffset = (y >> 4) - worldOffset; + if (chunkOffset < chunk.getSections().length) { + LevelChunkSection section = chunk.getSections()[chunkOffset]; + if (section != null && !section.hasOnlyAir()) { + return Block.getId(section.getBlockState(x & 15, y & 15, z & 15)); + } + } + + return 0; + } + + @Override + public boolean hasOwnChunkCache() { + return SharedConstants.getCurrentVersion().getProtocolVersion() == GameProtocol.getJavaProtocolVersion(); + } + @Override public boolean shouldExpectLecternHandled(GeyserSession session) { return true; @@ -154,7 +216,7 @@ public class GeyserFabricWorldManager extends GeyserWorldManager { @Override public boolean hasPermission(GeyserSession session, String permission) { ServerPlayer player = getPlayer(session); - return Permissions.check(player, permission); + return GeyserModBootstrap.getInstance().hasPermission(player, permission); } @Override diff --git a/bootstrap/mod/src/main/resources/geyser.mixins.json b/bootstrap/mod/src/main/resources/geyser.mixins.json new file mode 100644 index 000000000..47b2f60f3 --- /dev/null +++ b/bootstrap/mod/src/main/resources/geyser.mixins.json @@ -0,0 +1,18 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "org.geysermc.geyser.platform.mod.mixin", + "compatibilityLevel": "JAVA_17", + "mixins": [ + "server.ServerConnectionListenerMixin" + ], + "server": [ + "server.DedicatedServerMixin" + ], + "client": [ + "client.IntegratedServerMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/gui/GeyserStandaloneGUI.java b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/gui/GeyserStandaloneGUI.java index c3e2e10e8..b82d8cc94 100644 --- a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/gui/GeyserStandaloneGUI.java +++ b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/gui/GeyserStandaloneGUI.java @@ -100,7 +100,7 @@ public class GeyserStandaloneGUI { Container cp = frame.getContentPane(); // Fetch and set the icon for the frame - URL image = getClass().getClassLoader().getResource("icon.png"); + URL image = getClass().getClassLoader().getResource("assets/geyser/icon.png"); if (image != null) { ImageIcon icon = new ImageIcon(image); frame.setIconImage(icon.getImage()); diff --git a/build-logic/build.gradle.kts b/build-logic/build.gradle.kts index c0c683920..b7aab2bf0 100644 --- a/build-logic/build.gradle.kts +++ b/build-logic/build.gradle.kts @@ -4,14 +4,17 @@ plugins { repositories { gradlePluginPortal() - maven("https://repo.opencollab.dev/maven-snapshots") + + maven("https://repo.opencollab.dev/maven-snapshots/") + maven("https://maven.fabricmc.net/") + maven("https://maven.neoforged.net/releases") + maven("https://maven.architectury.dev/") } dependencies { - implementation("net.kyori", "indra-common", "3.1.1") - implementation("com.github.johnrengelman", "shadow", "7.1.3-SNAPSHOT") - - // Within the gradle plugin classpath, there is a version conflict between loom and some other - // plugin for databind. This fixes it: minimum 2.13.2 is required by loom. - implementation("com.fasterxml.jackson.core:jackson-databind:2.14.0") + implementation(libs.indra) + implementation(libs.shadow) + implementation(libs.architectury.plugin) + implementation(libs.architectury.loom) + implementation(libs.minotaur) } diff --git a/build-logic/settings.gradle.kts b/build-logic/settings.gradle.kts new file mode 100644 index 000000000..63bde189b --- /dev/null +++ b/build-logic/settings.gradle.kts @@ -0,0 +1,11 @@ +@file:Suppress("UnstableApiUsage") + +dependencyResolutionManagement { + versionCatalogs { + create("libs") { + from(files("../gradle/libs.versions.toml")) + } + } +} + +rootProject.name = "build-logic" \ No newline at end of file diff --git a/build-logic/src/main/kotlin/geyser.base-conventions.gradle.kts b/build-logic/src/main/kotlin/geyser.base-conventions.gradle.kts index c9f984596..3d41a3dd6 100644 --- a/build-logic/src/main/kotlin/geyser.base-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/geyser.base-conventions.gradle.kts @@ -22,8 +22,8 @@ indra { tasks { processResources { - // Spigot, BungeeCord, Velocity, Fabric, ViaProxy - filesMatching(listOf("plugin.yml", "bungee.yml", "velocity-plugin.json", "fabric.mod.json", "viaproxy.yml")) { + // Spigot, BungeeCord, Velocity, Fabric, ViaProxy, NeoForge + filesMatching(listOf("plugin.yml", "bungee.yml", "velocity-plugin.json", "fabric.mod.json", "viaproxy.yml", "META-INF/mods.toml")) { expand( "id" to "geyser", "name" to "Geyser", @@ -34,4 +34,4 @@ tasks { ) } } -} +} \ No newline at end of file diff --git a/bootstrap/fabric/build.gradle.kts b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts similarity index 70% rename from bootstrap/fabric/build.gradle.kts rename to build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts index 66af130b3..0842eae84 100644 --- a/bootstrap/fabric/build.gradle.kts +++ b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts @@ -1,50 +1,22 @@ +@file:Suppress("UnstableApiUsage") + import net.fabricmc.loom.task.RemapJarTask +import org.gradle.kotlin.dsl.dependencies +import org.gradle.kotlin.dsl.maven plugins { - id("fabric-loom") version "1.0-SNAPSHOT" - id("com.modrinth.minotaur") version "2.+" + id("geyser.publish-conventions") + id("architectury-plugin") + id("dev.architectury.loom") + id("com.modrinth.minotaur") } -dependencies { - //to change the versions see the gradle.properties file - minecraft(libs.fabric.minecraft) - mappings(loom.officialMojangMappings()) - modImplementation(libs.fabric.loader) - - // Fabric API. This is technically optional, but you probably want it anyway. - modImplementation(libs.fabric.api) - - // This should be in the libs TOML, but something about modImplementation AND include just doesn't work - include(modImplementation("me.lucko", "fabric-permissions-api", "0.2-SNAPSHOT")) - - // PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs. - // You may need to force-disable transitiveness on them. - - api(projects.core) - shadow(projects.core) { - exclude(group = "com.google.guava", module = "guava") - exclude(group = "com.google.code.gson", module = "gson") - exclude(group = "org.slf4j") - exclude(group = "com.nukkitx.fastutil") - exclude(group = "io.netty.incubator") - } +architectury { + minecraft = "1.20.4" } loom { - mixin.defaultRefmapName.set("geyser-fabric-refmap.json") -} - -repositories { - mavenLocal() - maven("https://repo.opencollab.dev/maven-releases/") - maven("https://repo.opencollab.dev/maven-snapshots/") - maven("https://jitpack.io") - maven("https://oss.sonatype.org/content/repositories/snapshots/") - maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") -} - -application { - mainClass.set("org.geysermc.geyser.platform.fabric.GeyserFabricMain") + silentMojangMappingsLicense() } tasks { @@ -59,7 +31,7 @@ tasks { shadowJar { // Mirrors the example fabric project, otherwise tons of dependencies are shaded that shouldn't be configurations = listOf(project.configurations.shadow.get()) - // The remapped shadowJar is the final desired Geyser-Fabric.jar + // The remapped shadowJar is the final desired mod jar archiveVersion.set(project.version.toString()) archiveClassifier.set("shaded") @@ -89,20 +61,32 @@ tasks { remapJar { dependsOn(shadowJar) inputFile.set(shadowJar.get().archiveFile) - archiveBaseName.set("Geyser-Fabric") - archiveVersion.set("") archiveClassifier.set("") + archiveVersion.set("") } register("remapModrinthJar", RemapJarTask::class) { dependsOn(shadowJar) inputFile.set(shadowJar.get().archiveFile) - archiveBaseName.set("geyser-fabric") archiveVersion.set(project.version.toString() + "+build." + System.getenv("GITHUB_RUN_NUMBER")) archiveClassifier.set("") } } +dependencies { + minecraft("com.mojang:minecraft:1.20.4") + mappings(loom.officialMojangMappings()) +} + +repositories { + maven("https://repo.opencollab.dev/maven-releases/") + maven("https://repo.opencollab.dev/maven-snapshots/") + maven("https://jitpack.io") + maven("https://oss.sonatype.org/content/repositories/snapshots/") + maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") + maven("https://maven.neoforged.net/releases") +} + modrinth { token.set(System.getenv("MODRINTH_TOKEN")) // Even though this is the default value, apparently this prevents GitHub Actions caching the token? projectId.set("wKkoqHrH") @@ -114,11 +98,5 @@ modrinth { uploadFile.set(tasks.getByPath("remapModrinthJar")) gameVersions.addAll("1.20.4") - - loaders.add("fabric") failSilently.set(true) - - dependencies { - required.project("fabric-api") - } -} +} \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 1d434e599..dfdff2187 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,9 +1,9 @@ plugins { `java-library` // Ensure AP works in eclipse (no effect on other IDEs) - `eclipse` + eclipse id("geyser.build-logic") - id("io.freefair.lombok") version "6.3.0" apply false + alias(libs.plugins.lombok) apply false } allprojects { @@ -12,14 +12,7 @@ allprojects { description = properties["description"] as String } -java { - toolchain { - languageVersion.set(JavaLanguageVersion.of(17)) - } -} - -val platforms = setOf( - projects.fabric, +val basePlatforms = setOf( projects.bungeecord, projects.spigot, projects.standalone, @@ -27,6 +20,12 @@ val platforms = setOf( projects.viaproxy ).map { it.dependencyProject } +val moddedPlatforms = setOf( + projects.fabric, + projects.neoforge, + projects.mod +).map { it.dependencyProject } + subprojects { apply { plugin("java-library") @@ -35,7 +34,8 @@ subprojects { } when (this) { - in platforms -> plugins.apply("geyser.platform-conventions") + in basePlatforms -> plugins.apply("geyser.platform-conventions") + in moddedPlatforms -> plugins.apply("geyser.modded-conventions") else -> plugins.apply("geyser.base-conventions") } -} +} \ No newline at end of file diff --git a/core/build.gradle.kts b/core/build.gradle.kts index f67b652be..6d289ae37 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -1,8 +1,7 @@ import net.kyori.blossom.BlossomExtension plugins { - id("net.kyori.blossom") - id("net.kyori.indra.git") + alias(libs.plugins.blossom) id("geyser.publish-conventions") } diff --git a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java index 6a8efaba1..8b54f5298 100644 --- a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java +++ b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java @@ -221,6 +221,7 @@ public class GeyserImpl implements GeyserApi { if (ex != null) { return; } + MinecraftLocale.ensureEN_US(); String locale = GeyserLocale.getDefaultLocale(); if (!"en_us".equals(locale)) { diff --git a/core/src/main/java/org/geysermc/geyser/pack/SkullResourcePackManager.java b/core/src/main/java/org/geysermc/geyser/pack/SkullResourcePackManager.java index e7a9f4f1e..f6c5140d8 100644 --- a/core/src/main/java/org/geysermc/geyser/pack/SkullResourcePackManager.java +++ b/core/src/main/java/org/geysermc/geyser/pack/SkullResourcePackManager.java @@ -187,7 +187,7 @@ public class SkullResourcePackManager { ZipEntry entry = new ZipEntry("skull_resource_pack/pack_icon.png"); zipOS.putNextEntry(entry); - zipOS.write(FileUtils.readAllBytes("icon.png")); + zipOS.write(FileUtils.readAllBytes("assets/geyser/icon.png")); zipOS.closeEntry(); } } diff --git a/core/src/main/java/org/geysermc/geyser/session/PendingMicrosoftAuthentication.java b/core/src/main/java/org/geysermc/geyser/session/PendingMicrosoftAuthentication.java index 132de67cb..0651039a0 100644 --- a/core/src/main/java/org/geysermc/geyser/session/PendingMicrosoftAuthentication.java +++ b/core/src/main/java/org/geysermc/geyser/session/PendingMicrosoftAuthentication.java @@ -123,7 +123,8 @@ public class PendingMicrosoftAuthentication { public CompletableFuture getCode(boolean offlineAccess) { // Request the code - CompletableFuture code = CompletableFuture.supplyAsync(() -> tryGetCode(offlineAccess)); + CompletableFuture code = CompletableFuture.supplyAsync( + () -> tryGetCode(offlineAccess)); // Once the code is received, continuously try to request the access token, profile, etc code.thenRun(() -> performLoginAttempt(System.currentTimeMillis())); return code; diff --git a/bootstrap/fabric/src/main/resources/assets/geyser-fabric/icon.png b/core/src/main/resources/assets/geyser/icon.png similarity index 100% rename from bootstrap/fabric/src/main/resources/assets/geyser-fabric/icon.png rename to core/src/main/resources/assets/geyser/icon.png diff --git a/core/src/main/resources/icon.png b/core/src/main/resources/icon.png deleted file mode 100644 index 4e6a38a787f0ed02a93b2580b5be0e838ffefea3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 115461 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�? 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 diff --git a/gradle.properties b/gradle.properties index 74504759e..a8e5eaaaf 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,8 +1,8 @@ # Gradle settings org.gradle.jvmargs=-Xmx4G -org.gradle.configureondemand=true -org.gradle.caching=true +org.gradle.daemon=false org.gradle.parallel=true +org.gradle.caching=true org.gradle.vfs.watch=false group=org.geysermc diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0dc0fbc4a..4ce5dda1a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -32,6 +32,18 @@ viaproxy = "3.2.0-SNAPSHOT" fabric-minecraft = "1.20.4" fabric-loader = "0.15.2" fabric-api = "0.91.2+1.20.4" +fabric-permissions = "0.2-SNAPSHOT" +neoforge-minecraft = "20.4.48-beta" +mixin = "0.8.5" + +# plugin versions +indra = "3.1.3" +shadow = "7.1.3-SNAPSHOT" +architectury-plugin = "3.4-SNAPSHOT" +architectury-loom = "1.4-SNAPSHOT" +minotaur = "2.8.7" +lombok = "8.4" +blossom = "1.2.0" [libraries] base-api = { group = "org.geysermc.api", name = "base-api", version.ref = "base-api" } @@ -75,10 +87,15 @@ jline-reader = { group = "org.jline", name = "jline-reader", version.ref = "jlin folia-api = { group = "dev.folia", name = "folia-api", version.ref = "folia" } paper-mojangapi = { group = "io.papermc.paper", name = "paper-mojangapi", version.ref = "folia" } -# check these on https://modmuss50.me/fabric.html +mixin = { group = "org.spongepowered", name = "mixin", version.ref = "mixin" } + +# Check these on https://modmuss50.me/fabric.html fabric-minecraft = { group = "com.mojang", name = "minecraft", version.ref = "fabric-minecraft" } fabric-loader = { group = "net.fabricmc", name = "fabric-loader", version.ref = "fabric-loader" } fabric-api = { group = "net.fabricmc.fabric-api", name = "fabric-api", version.ref = "fabric-api" } +fabric-permissions = { group = "me.lucko", name = "fabric-permissions-api", version.ref = "fabric-permissions" } + +neoforge-minecraft = { group = "net.neoforged", name = "neoforge", version.ref = "neoforge-minecraft" } adapters-spigot = { group = "org.geysermc.geyser.adapters", name = "spigot-all", version.ref = "adapters" } bungeecord-proxy = { group = "com.github.SpigotMC.BungeeCord", name = "bungeecord-proxy", version.ref = "bungeecord" } @@ -104,6 +121,18 @@ math = { group = "org.cloudburstmc.math", name = "immutable", version = "2.0" } blockstateupdater = { group = "org.cloudburstmc", name = "block-state-updater", version.ref = "blockstateupdater"} +# plugins +indra = { group = "net.kyori", name = "indra-common", version.ref = "indra" } +shadow = { group = "com.github.johnrengelman", name = "shadow", version.ref = "shadow" } +architectury-plugin = { group = "architectury-plugin", name = "architectury-plugin.gradle.plugin", version.ref = "architectury-plugin" } +architectury-loom = { group = "dev.architectury.loom", name = "dev.architectury.loom.gradle.plugin", version.ref = "architectury-loom" } +minotaur = { group = "com.modrinth.minotaur", name = "Minotaur", version.ref = "minotaur" } + +[plugins] +lombok = { id = "io.freefair.lombok", version.ref = "lombok" } +indra = { id = "net.kyori.indra", version.ref = "indra" } +blossom = { id = "net.kyori.blossom", version.ref = "blossom" } + [bundles] jackson = [ "jackson-annotations", "jackson-core", "jackson-dataformat-yaml" ] fastutil = [ "fastutil-int-int-maps", "fastutil-int-long-maps", "fastutil-int-byte-maps", "fastutil-int-boolean-maps", "fastutil-object-int-maps", "fastutil-object-object-maps" ] diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ae04661ee..db9a6b825 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/settings.gradle.kts b/settings.gradle.kts index 6c644bf09..68848bca4 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,8 @@ +@file:Suppress("UnstableApiUsage") + enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") dependencyResolutionManagement { -// repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { // Floodgate, Cumulus etc. maven("https://repo.opencollab.dev/main") @@ -18,6 +19,11 @@ dependencyResolutionManagement { mavenContent { snapshotsOnly() } } + // NeoForge + maven("https://maven.neoforged.net/releases") { + mavenContent { releasesOnly() } + } + // Minecraft maven("https://libraries.minecraft.net") { name = "minecraft" @@ -44,13 +50,11 @@ dependencyResolutionManagement { pluginManagement { repositories { gradlePluginPortal() + + maven("https://repo.opencollab.dev/maven-snapshots/") maven("https://maven.fabricmc.net/") - maven("https://repo.opencollab.dev/maven-snapshots") - } - plugins { - id("net.kyori.blossom") version "1.2.0" - id("net.kyori.indra") - id("net.kyori.indra.git") + maven("https://maven.architectury.dev/") + maven("https://maven.neoforged.net/releases") } includeBuild("build-logic") } @@ -61,6 +65,8 @@ include(":ap") include(":api") include(":bungeecord") include(":fabric") +include(":neoforge") +include(":mod") include(":spigot") include(":standalone") include(":velocity") @@ -70,7 +76,9 @@ include(":core") // Specify project dirs project(":bungeecord").projectDir = file("bootstrap/bungeecord") -project(":fabric").projectDir = file("bootstrap/fabric") +project(":fabric").projectDir = file("bootstrap/mod/fabric") +project(":neoforge").projectDir = file("bootstrap/mod/neoforge") +project(":mod").projectDir = file("bootstrap/mod") project(":spigot").projectDir = file("bootstrap/spigot") project(":standalone").projectDir = file("bootstrap/standalone") project(":velocity").projectDir = file("bootstrap/velocity") From f8e6d26fc2ee7e507085472015812683cc6e803d Mon Sep 17 00:00:00 2001 From: chris Date: Fri, 23 Feb 2024 18:40:41 +0100 Subject: [PATCH 003/272] Fix mod platform publishing (#4454) --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cd579c931..b316cd037 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -120,6 +120,7 @@ jobs: ssh -o StrictHostKeyChecking=no -i id_ecdsa $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP mkdir -p "~/uploads/$project/$GITHUB_RUN_NUMBER/" # Copy over artifacts rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" bootstrap/**/build/libs/Geyser-*.jar $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$project/$GITHUB_RUN_NUMBER/ + rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" bootstrap/mod/**/build/libs/Geyser-*.jar $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$project/$GITHUB_RUN_NUMBER/ # Run the build script # Push the metadata echo "{\"project\": \"$project\", \"version\": \"$version\", \"id\": $GITHUB_RUN_NUMBER, \"commit\": \"$GITHUB_SHA\"}" > metadata.json From 3c4a1a82c9ca8c990dae89ad55a3e9c395f878ef Mon Sep 17 00:00:00 2001 From: rtm516 Date: Sat, 2 Mar 2024 00:56:35 +0000 Subject: [PATCH 004/272] Deprecate unit cube in block components (#4470) * Depricate unit cube * Didn't mean to remove that --- .../custom/component/CustomBlockComponents.java | 7 +++++++ .../level/block/GeyserCustomBlockComponents.java | 12 ++++++++---- .../mappings/versions/MappingsReader_v1.java | 4 +++- .../populator/CustomBlockRegistryPopulator.java | 4 ---- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/block/custom/component/CustomBlockComponents.java b/api/src/main/java/org/geysermc/geyser/api/block/custom/component/CustomBlockComponents.java index 63788df8e..06608f787 100644 --- a/api/src/main/java/org/geysermc/geyser/api/block/custom/component/CustomBlockComponents.java +++ b/api/src/main/java/org/geysermc/geyser/api/block/custom/component/CustomBlockComponents.java @@ -129,8 +129,11 @@ public interface CustomBlockComponents { * Gets the unit cube component * Equivalent to "minecraft:unit_cube" * + * @deprecated Use {@link #geometry()} and compare with `minecraft:geometry.full_block` instead. + * * @return The rotation. */ + @Deprecated boolean unitCube(); /** @@ -181,6 +184,10 @@ public interface CustomBlockComponents { Builder transformation(TransformationComponent transformation); + /** + * @deprecated Use {@link #geometry(GeometryComponent)} with `minecraft:geometry.full_block` instead. + */ + @Deprecated Builder unitCube(boolean unitCube); Builder placeAir(boolean placeAir); diff --git a/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockComponents.java b/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockComponents.java index 1fa863d55..dfcb548ee 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockComponents.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockComponents.java @@ -58,7 +58,6 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents { Integer lightEmission; Integer lightDampening; TransformationComponent transformation; - boolean unitCube; boolean placeAir; Set tags; @@ -66,7 +65,13 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents { this.selectionBox = builder.selectionBox; this.collisionBox = builder.collisionBox; this.displayName = builder.displayName; - this.geometry = builder.geometry; + GeometryComponent geo = builder.geometry; + if (builder.unitCube && geo == null) { + geo = GeometryComponent.builder() + .identifier("minecraft:geometry.full_block") + .build(); + } + this.geometry = geo; if (builder.materialInstances.isEmpty()) { this.materialInstances = Object2ObjectMaps.emptyMap(); } else { @@ -78,7 +83,6 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents { this.lightEmission = builder.lightEmission; this.lightDampening = builder.lightDampening; this.transformation = builder.transformation; - this.unitCube = builder.unitCube; this.placeAir = builder.placeAir; if (builder.tags.isEmpty()) { this.tags = Set.of(); @@ -144,7 +148,7 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents { @Override public boolean unitCube() { - return unitCube; + return geometry.identifier().equals("minecraft:geometry.full_block"); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java b/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java index 0bc55c7b1..ce4a8f30e 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java +++ b/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java @@ -488,7 +488,9 @@ public class MappingsReader_v1 extends MappingsReader { } if (node.has("unit_cube")) { - builder.unitCube(node.get("unit_cube").asBoolean()); + builder.geometry(GeometryComponent.builder() + .identifier("minecraft:geometry.full_block") + .build()); } if (node.has("material_instances")) { diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java index ea33450bf..36b1fc859 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java @@ -422,10 +422,6 @@ public class CustomBlockRegistryPopulator { .build()); } - if (components.unitCube()) { - builder.putCompound("minecraft:unit_cube", NbtMap.EMPTY); - } - // place_air is not an actual component // We just apply a dummy event to prevent the client from trying to place a block // This mitigates the issue with the client sometimes double placing blocks From 5d95bf65a6f13baa4fb9ad3b6a6b0c0c42c43ab9 Mon Sep 17 00:00:00 2001 From: chris Date: Sat, 2 Mar 2024 03:21:31 +0100 Subject: [PATCH 005/272] Fix lecterns on 1.20.60, add support for virtual books (#4471) * Fix lecterns on 1.20.60, start on virtual lecterns * Fix: virtual books & actual books opening twice, resolve other issues, remove debug * undo some unnecessary diff * Don't try to send virtual books to pre 1.20.60 clients * address review by camotoy --- .../holder/BlockInventoryHolder.java | 30 +++++-- .../inventory/item/StoredItemMappings.java | 2 + .../geyser/session/GeyserSession.java | 7 ++ .../inventory/LecternInventoryTranslator.java | 71 ++++++++++++--- ...BedrockInventoryTransactionTranslator.java | 4 +- .../BedrockLecternUpdateTranslator.java | 11 +++ .../player/BedrockInteractTranslator.java | 5 ++ .../JavaContainerSetContentTranslator.java | 11 +-- .../JavaContainerSetSlotTranslator.java | 15 ++-- .../inventory/JavaOpenBookTranslator.java | 87 +++++++++++++++++++ .../geysermc/geyser/util/InventoryUtils.java | 9 +- 11 files changed, 218 insertions(+), 34 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenBookTranslator.java diff --git a/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java b/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java index 135e1057f..c11505ffb 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java @@ -32,8 +32,10 @@ import org.cloudburstmc.protocol.bedrock.packet.BlockEntityDataPacket; import org.cloudburstmc.protocol.bedrock.packet.ContainerClosePacket; import org.cloudburstmc.protocol.bedrock.packet.ContainerOpenPacket; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; +import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.Container; import org.geysermc.geyser.inventory.Inventory; +import org.geysermc.geyser.inventory.LecternContainer; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.type.BlockMapping; import org.geysermc.geyser.session.GeyserSession; @@ -151,13 +153,27 @@ public class BlockInventoryHolder extends InventoryHolder { @Override public void closeInventory(InventoryTranslator translator, GeyserSession session, Inventory inventory) { - if (((Container) inventory).isUsingRealBlock()) { - // No need to reset a block since we didn't change any blocks - // But send a container close packet because we aren't destroying the original. - ContainerClosePacket packet = new ContainerClosePacket(); - packet.setId((byte) inventory.getBedrockId()); - packet.setServerInitiated(true); - session.sendUpstreamPacket(packet); + if (inventory instanceof Container container) { + if (container.isUsingRealBlock() && !(inventory instanceof LecternContainer)) { + // No need to reset a block since we didn't change any blocks + // But send a container close packet because we aren't destroying the original. + ContainerClosePacket packet = new ContainerClosePacket(); + packet.setId((byte) inventory.getBedrockId()); + packet.setServerInitiated(true); + session.sendUpstreamPacket(packet); + return; + } + } else { + GeyserImpl.getInstance().getLogger().warning("Tried to close a non-container inventory in a block inventory holder! "); + if (GeyserImpl.getInstance().getLogger().isDebug()) { + GeyserImpl.getInstance().getLogger().debug("Current inventory: " + inventory); + GeyserImpl.getInstance().getLogger().debug("Open inventory: " + session.getOpenInventory()); + } + // Try to save ourselves? maybe? + // https://github.com/GeyserMC/Geyser/issues/4141 + // TODO: improve once this issue is pinned down properly + session.setOpenInventory(null); + session.setInventoryTranslator(InventoryTranslator.PLAYER_INVENTORY_TRANSLATOR); return; } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/StoredItemMappings.java b/core/src/main/java/org/geysermc/geyser/inventory/item/StoredItemMappings.java index 6bb786896..c15a5d3b4 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/StoredItemMappings.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/StoredItemMappings.java @@ -53,6 +53,7 @@ public class StoredItemMappings { private final ItemMapping upgradeTemplate; private final ItemMapping wheat; private final ItemMapping writableBook; + private final ItemMapping writtenBook; public StoredItemMappings(Map itemMappings) { this.bamboo = load(itemMappings, Items.BAMBOO); @@ -68,6 +69,7 @@ public class StoredItemMappings { this.upgradeTemplate = load(itemMappings, Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE); this.wheat = load(itemMappings, Items.WHEAT); this.writableBook = load(itemMappings, Items.WRITABLE_BOOK); + this.writtenBook = load(itemMappings, Items.WRITTEN_BOOK); } @NonNull diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index d40b07939..b151f9b09 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -89,6 +89,7 @@ import org.cloudburstmc.protocol.bedrock.data.command.CommandEnumData; import org.cloudburstmc.protocol.bedrock.data.command.CommandPermission; import org.cloudburstmc.protocol.bedrock.data.command.SoftEnumUpdateType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; +import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.packet.*; import org.cloudburstmc.protocol.common.DefinitionRegistry; import org.cloudburstmc.protocol.common.util.OptionalBoolean; @@ -595,6 +596,12 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { */ private final Queue keepAliveCache = new ConcurrentLinkedQueue<>(); + /** + * Stores the book that is currently being read. Used in {@link org.geysermc.geyser.translator.protocol.java.inventory.JavaOpenBookTranslator} + */ + @Setter + private @Nullable ItemData currentBook = null; + private final GeyserCameraData cameraData; private final GeyserEntityData entityData; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java index 92cd8a0d4..26721bfcc 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java @@ -36,36 +36,71 @@ import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.erosion.util.LecternUtils; +import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.inventory.Container; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.LecternContainer; import org.geysermc.geyser.inventory.PlayerInventory; -import org.geysermc.geyser.inventory.updater.InventoryUpdater; +import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater; +import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.BlockEntityUtils; import org.geysermc.geyser.util.InventoryUtils; import java.util.Collections; -public class LecternInventoryTranslator extends BaseInventoryTranslator { - private final InventoryUpdater updater; +public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator { + + /** + * Hack: Java opens a lectern first, and then follows it up with a ClientboundContainerSetContentPacket + * to actually send the book's contents. We delay opening the inventory until the book was sent. + */ + private boolean initialized = false; public LecternInventoryTranslator() { - super(1); - this.updater = new InventoryUpdater(); + super(1, "minecraft:lectern[facing=north,has_book=true,powered=true]", org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.LECTERN , ContainerInventoryUpdater.INSTANCE); } @Override public boolean prepareInventory(GeyserSession session, Inventory inventory) { + super.prepareInventory(session, inventory); + if (((Container) inventory).isUsingRealBlock()) { + initialized = false; // We have to wait until we get the book to show to the client + } else { + updateBook(session, inventory, inventory.getItem(0)); // See JavaOpenBookTranslator; placed here manually + initialized = true; + } return true; } @Override public void openInventory(GeyserSession session, Inventory inventory) { + // Hacky, but we're dealing with LECTERNS! It cannot not be hacky. + // "initialized" indicates whether we've received the book from the Java server yet. + // dropping lectern book is the fun workaround when we have to enter the gui to drop the book. + // Since we leave it immediately... don't open it! + if (initialized && !session.isDroppingLecternBook()) { + super.openInventory(session, inventory); + } } @Override public void closeInventory(GeyserSession session, Inventory inventory) { + // Of course, sending a simple ContainerClosePacket, or even breaking the block doesn't work to close a lectern. + // Heck, the latter crashes the client xd + // BDS just sends an empty base lectern tag... that kicks out the client. Fine. Let's do that! + LecternContainer lecternContainer = (LecternContainer) inventory; + Vector3i position = lecternContainer.isUsingRealBlock() ? session.getLastInteractionBlockPosition() : inventory.getHolderPosition(); + var baseLecternTag = LecternUtils.getBaseLecternTag(position.getX(), position.getY(), position.getZ(), 0); + BlockEntityUtils.updateBlockEntity(session, baseLecternTag.build(), position); + + super.closeInventory(session, inventory); // Removes the fake blocks if need be + + // Now: Restore the lectern, if it actually exists + if (lecternContainer.isUsingRealBlock()) { + GeyserImpl.getInstance().getWorldManager().sendLecternData(session, position.getX(), position.getY(), position.getZ()); + } } @Override @@ -82,13 +117,19 @@ public class LecternInventoryTranslator extends BaseInventoryTranslator { public void updateInventory(GeyserSession session, Inventory inventory) { GeyserItemStack itemStack = inventory.getItem(0); if (!itemStack.isEmpty()) { + boolean isDropping = session.isDroppingLecternBook(); updateBook(session, inventory, itemStack); + + if (!initialized && !isDropping) { + initialized = true; + openInventory(session, inventory); + } } } @Override public void updateSlot(GeyserSession session, Inventory inventory, int slot) { - this.updater.updateSlot(this, session, inventory, slot); + super.updateSlot(session, inventory, slot); if (slot == 0) { updateBook(session, inventory, inventory.getItem(0)); } @@ -107,11 +148,14 @@ public class LecternInventoryTranslator extends BaseInventoryTranslator { InventoryUtils.closeInventory(session, inventory.getJavaId(), false); } else if (lecternContainer.getBlockEntityTag() == null) { CompoundTag tag = book.getNbt(); - // Position has to be the last interacted position... right? - Vector3i position = session.getLastInteractionBlockPosition(); + Vector3i position = lecternContainer.isUsingRealBlock() ? session.getLastInteractionBlockPosition() : inventory.getHolderPosition(); + // If shouldExpectLecternHandled returns true, this is already handled for us // shouldRefresh means that we should boot out the client on our side because their lectern GUI isn't updated yet - boolean shouldRefresh = !session.getGeyser().getWorldManager().shouldExpectLecternHandled(session) && !session.getLecternCache().contains(position); + // TODO: yeet after 1.20.60 is minimum supported version + boolean shouldRefresh = !session.getGeyser().getWorldManager().shouldExpectLecternHandled(session) + && !session.getLecternCache().contains(position) + && !GameProtocol.is1_20_60orHigher(session.getUpstream().getProtocolVersion()); NbtMap blockEntityTag; if (tag != null) { @@ -147,10 +191,11 @@ public class LecternInventoryTranslator extends BaseInventoryTranslator { // the block entity tag lecternContainer.setBlockEntityTag(blockEntityTag); lecternContainer.setPosition(position); + + BlockEntityUtils.updateBlockEntity(session, blockEntityTag, position); + session.getLecternCache().add(position); + if (shouldRefresh) { - // Update the lectern because it's not updated client-side - BlockEntityUtils.updateBlockEntity(session, blockEntityTag, position); - session.getLecternCache().add(position); // Close the window - we will reopen it once the client has this data synced ServerboundContainerClosePacket closeWindowPacket = new ServerboundContainerClosePacket(lecternContainer.getJavaId()); session.sendDownstreamGamePacket(closeWindowPacket); @@ -161,6 +206,6 @@ public class LecternInventoryTranslator extends BaseInventoryTranslator { @Override public Inventory createInventory(String name, int windowId, ContainerType containerType, PlayerInventory playerInventory) { - return new LecternContainer(name, windowId, this.size, containerType, playerInventory); + return new LecternContainer(name, windowId, this.size + playerInventory.getSize(), containerType, playerInventory); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java index 29a78daf3..101035cb5 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java @@ -380,6 +380,8 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator legacySlots = packet.getLegacySlots(); - if (packet.getActions().size() == 1 && legacySlots.size() > 0) { + if (packet.getActions().size() == 1 && !legacySlots.isEmpty()) { InventoryActionData actionData = packet.getActions().get(0); LegacySetItemSlotData slotData = legacySlots.get(0); if (slotData.getContainerId() == 6 && !actionData.getFromItem().isNull()) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockLecternUpdateTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockLecternUpdateTranslator.java index b2a34d904..2678128ed 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockLecternUpdateTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockLecternUpdateTranslator.java @@ -31,8 +31,10 @@ import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.Ser import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundUseItemOnPacket; import org.cloudburstmc.protocol.bedrock.packet.LecternUpdatePacket; +import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.LecternContainer; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.inventory.LecternInventoryTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.InventoryUtils; @@ -77,6 +79,15 @@ public class BedrockLecternUpdateTranslator extends PacketTranslator containerOpenPacket.setBlockPosition(entity.getPosition().toInt()); session.sendUpstreamPacket(containerOpenPacket); } + } else { + // Case: Player opens a player inventory, while we think it shouldn't have! + // Close all inventories, reset to player inventory. + InventoryUtils.closeInventory(session, session.getOpenInventory().getJavaId(), false); } break; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetContentTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetContentTranslator.java index cfe1c404e..2f8204871 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetContentTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetContentTranslator.java @@ -27,6 +27,7 @@ package org.geysermc.geyser.translator.protocol.java.inventory; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundContainerSetContentPacket; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.session.GeyserSession; @@ -48,12 +49,12 @@ public class JavaContainerSetContentTranslator extends PacketTranslator= inventorySize) { - GeyserImpl geyser = session.getGeyser(); - geyser.getLogger().warning("ClientboundContainerSetContentPacket sent to " + session.bedrockUsername() + GeyserLogger logger = session.getGeyser().getLogger(); + logger.warning("ClientboundContainerSetContentPacket sent to " + session.bedrockUsername() + " that exceeds inventory size!"); - if (geyser.getConfig().isDebugMode()) { - geyser.getLogger().debug(packet); - geyser.getLogger().debug(inventory); + if (logger.isDebug()) { + logger.debug(packet); + logger.debug(inventory); } updateInventory(session, inventory, packet.getContainerId()); // 1.18.1 behavior: the previous items will be correctly set, but the state ID and carried item will not diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java index 734c6945a..4b8eef00d 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java @@ -34,7 +34,7 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapedRe import org.cloudburstmc.protocol.bedrock.data.inventory.descriptor.ItemDescriptorWithCount; import org.cloudburstmc.protocol.bedrock.packet.CraftingDataPacket; import org.cloudburstmc.protocol.bedrock.packet.InventorySlotPacket; -import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.recipe.GeyserShapedRecipe; @@ -65,8 +65,9 @@ public class JavaContainerSetSlotTranslator extends PacketTranslator= inventory.getSize()) { - GeyserImpl geyser = session.getGeyser(); - geyser.getLogger().warning("ClientboundContainerSetSlotPacket sent to " + session.bedrockUsername() + GeyserLogger logger = session.getGeyser().getLogger(); + logger.warning("ClientboundContainerSetSlotPacket sent to " + session.bedrockUsername() + " that exceeds inventory size!"); - if (geyser.getConfig().isDebugMode()) { - geyser.getLogger().debug(packet); - geyser.getLogger().debug(inventory); + if (logger.isDebug()) { + logger.debug(packet.toString()); + logger.debug(inventory.toString()); } // 1.19.0 behavior: the state ID will not be set due to exception return; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenBookTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenBookTranslator.java new file mode 100644 index 000000000..f9cf4ee28 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenBookTranslator.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.translator.protocol.java.inventory; + +import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; +import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundOpenBookPacket; +import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; +import org.geysermc.geyser.inventory.GeyserItemStack; +import org.geysermc.geyser.inventory.Inventory; +import org.geysermc.geyser.item.Items; +import org.geysermc.geyser.network.GameProtocol; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.inventory.InventoryTranslator; +import org.geysermc.geyser.translator.protocol.PacketTranslator; +import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.geyser.util.InventoryUtils; + +import java.util.Objects; + +@Translator(packet = ClientboundOpenBookPacket.class) +public class JavaOpenBookTranslator extends PacketTranslator { + + /** + * Unlike other fake inventories that rely on placing blocks in the world; + * the virtual lectern workaround for books isn't triggered the same way. + * Specifically, we don't get a window id - hence, we just use our own! + */ + private final static int FAKE_LECTERN_WINDOW_ID = -69; + + @Override + public void translate(GeyserSession session, ClientboundOpenBookPacket packet) { + GeyserItemStack stack = session.getPlayerInventory().getItemInHand(); + + // Don't spawn a fake lectern for books already opened "normally" by the client. + if (stack.getItemData(session).equals(session.getCurrentBook())) { + session.setCurrentBook(null); + return; + } + + // Only post 1.20.60 is it possible to tell the client to open a lectern. + if (!GameProtocol.is1_20_60orHigher(session.getUpstream().getProtocolVersion())) { + return; + } + + if (stack.asItem().equals(Items.WRITTEN_BOOK)) { + Inventory openInventory = session.getOpenInventory(); + if (openInventory != null) { + InventoryUtils.closeInventory(session, openInventory.getJavaId(), true); + + ServerboundContainerClosePacket closeWindowPacket = new ServerboundContainerClosePacket(openInventory.getJavaId()); + session.sendDownstreamGamePacket(closeWindowPacket); + } + + InventoryTranslator translator = InventoryTranslator.inventoryTranslator(ContainerType.LECTERN); + session.setInventoryTranslator(translator); + + // Should never be null + Objects.requireNonNull(translator, "lectern translator must exist"); + Inventory inventory = translator.createInventory("", FAKE_LECTERN_WINDOW_ID, ContainerType.LECTERN , session.getPlayerInventory()); + inventory.setItem(0, stack, session); + InventoryUtils.openInventory(session, inventory); + } + } +} diff --git a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java index 4d91f853c..30b2907cc 100644 --- a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java @@ -45,6 +45,7 @@ import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.Container; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.inventory.Inventory; +import org.geysermc.geyser.inventory.LecternContainer; import org.geysermc.geyser.inventory.PlayerInventory; import org.geysermc.geyser.inventory.click.Click; import org.geysermc.geyser.inventory.recipe.GeyserRecipe; @@ -123,7 +124,9 @@ public class InventoryUtils { if (inventory != null) { InventoryTranslator translator = session.getInventoryTranslator(); translator.closeInventory(session, inventory); - if (confirm && inventory.isDisplayed() && !inventory.isPending() && !(translator instanceof LecternInventoryTranslator)) { + if (confirm && inventory.isDisplayed() && !inventory.isPending() + && !(translator instanceof LecternInventoryTranslator) // TODO: double-check + ) { session.setClosingInventory(true); } } @@ -133,6 +136,10 @@ public class InventoryUtils { public static @Nullable Inventory getInventory(GeyserSession session, int javaId) { if (javaId == 0) { + // ugly hack: lecterns aren't their own inventory on Java, and can hence be closed with e.g. an id of 0 + if (session.getOpenInventory() instanceof LecternContainer) { + return session.getOpenInventory(); + } return session.getPlayerInventory(); } else { Inventory openInventory = session.getOpenInventory(); From 123990a79502cf6734e6858c1362c2431f050ece Mon Sep 17 00:00:00 2001 From: chris Date: Sat, 2 Mar 2024 20:03:18 +0100 Subject: [PATCH 006/272] Update ViaVersion api usage --- .../org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java index 1bc1718d7..1f14a2f65 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java @@ -433,7 +433,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { return false; } for (int i = protocolList.size() - 1; i >= 0; i--) { - MappingData mappingData = protocolList.get(i).getProtocol().getMappingData(); + MappingData mappingData = protocolList.get(i).protocol().getMappingData(); if (mappingData != null) { return true; } From 79154f3d0c37174fbba8a305e84b1176e1f239b4 Mon Sep 17 00:00:00 2001 From: chris Date: Mon, 4 Mar 2024 00:39:57 +0100 Subject: [PATCH 007/272] Fix: Lecterns not opening when there is no lectern cache (#4476) ... the LecternCache doesn't always exist. Oops. --- .../main/java/org/geysermc/geyser/session/GeyserSession.java | 2 +- .../translator/inventory/LecternInventoryTranslator.java | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index b151f9b09..8bdb41979 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -285,7 +285,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { * See {@link WorldManager#sendLecternData(GeyserSession, int, int, int)} * for more information. */ - private final Set lecternCache; + private final @Nullable Set lecternCache; /** * A list of all players that have a player head on with a custom texture. diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java index 26721bfcc..7a1ec7573 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java @@ -193,9 +193,11 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator lecternContainer.setPosition(position); BlockEntityUtils.updateBlockEntity(session, blockEntityTag, position); - session.getLecternCache().add(position); if (shouldRefresh) { + // the lectern cache doesn't always exist; only when we must refresh + session.getLecternCache().add(position); + // Close the window - we will reopen it once the client has this data synced ServerboundContainerClosePacket closeWindowPacket = new ServerboundContainerClosePacket(lecternContainer.getJavaId()); session.sendDownstreamGamePacket(closeWindowPacket); From 621dc6f89a0b355b16313df753abb9464d88105c Mon Sep 17 00:00:00 2001 From: Shanwer Date: Tue, 5 Mar 2024 06:37:45 +0800 Subject: [PATCH 008/272] Update actions to node20 (#4456) --- .github/workflows/build.yml | 30 +++++++++++++++--------------- .github/workflows/pullrequest.yml | 22 +++++++++++----------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b316cd037..385797af7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,7 +6,7 @@ on: paths-ignore: - '.github/ISSUE_TEMPLATE/*.yml' - '.github/actions/pullrequest.yml' - - '.idea/copyright/*.xml' + - '.idea/copyright/*.xml' - '.gitignore' - 'CONTRIBUTING.md' - 'LICENSE' @@ -20,72 +20,72 @@ jobs: steps: - name: Checkout repository and submodules # See https://github.com/actions/checkout/commits - uses: actions/checkout@72f2cec99f417b1a1c5e2e88945068983b7965f9 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: submodules: recursive - name: Validate Gradle Wrapper # See https://github.com/gradle/wrapper-validation-action/commits - uses: gradle/wrapper-validation-action@56b90f209b02bf6d1deae490e9ef18b21a389cd4 + uses: gradle/wrapper-validation-action@699bb18358f12c5b78b37bb0111d3a0e2276e0e2 # v2.1.1 # See https://github.com/actions/setup-java/commits - - uses: actions/setup-java@4075bfc1b51bf22876335ae1cd589602d60d8758 + - uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0 with: java-version: 17 distribution: temurin - name: Build # See https://github.com/gradle/gradle-build-action/commits - uses: gradle/gradle-build-action@3bfe3a46584a206fb8361cdedd0647b0c4204232 + uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 from https://github.com/gradle/actions/commits with: arguments: build gradle-home-cache-cleanup: true - name: Archive artifacts (Geyser Fabric) # See https://github.com/actions/upload-artifact/commits - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 if: success() with: name: Geyser Fabric path: bootstrap/mod/fabric/build/libs/Geyser-Fabric.jar if-no-files-found: error - name: Archive artifacts (Geyser NeoForge) - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 if: success() with: name: Geyser NeoForge path: bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar if-no-files-found: error - name: Archive artifacts (Geyser Standalone) - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 if: success() with: name: Geyser Standalone path: bootstrap/standalone/build/libs/Geyser-Standalone.jar if-no-files-found: error - name: Archive artifacts (Geyser Spigot) - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 if: success() with: name: Geyser Spigot path: bootstrap/spigot/build/libs/Geyser-Spigot.jar if-no-files-found: error - name: Archive artifacts (Geyser BungeeCord) - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 if: success() with: name: Geyser BungeeCord path: bootstrap/bungeecord/build/libs/Geyser-BungeeCord.jar if-no-files-found: error - name: Archive artifacts (Geyser Velocity) - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 if: success() with: name: Geyser Velocity path: bootstrap/velocity/build/libs/Geyser-Velocity.jar if-no-files-found: error - name: Archive artifacts (Geyser ViaProxy) - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 if: success() with: name: Geyser ViaProxy @@ -94,7 +94,7 @@ jobs: - name: Publish to Maven Repository if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} - uses: gradle/gradle-build-action@3bfe3a46584a206fb8361cdedd0647b0c4204232 + uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 env: ORG_GRADLE_PROJECT_geysermcUsername: ${{ vars.DEPLOY_USER }} ORG_GRADLE_PROJECT_geysermcPassword: ${{ secrets.DEPLOY_PASS }} @@ -127,7 +127,7 @@ jobs: rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" metadata.json $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$project/$GITHUB_RUN_NUMBER/ - name: Publish to Modrinth (Fabric) - uses: gradle/gradle-build-action@3bfe3a46584a206fb8361cdedd0647b0c4204232 + uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} env: MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }} @@ -136,7 +136,7 @@ jobs: gradle-home-cache-cleanup: true - name: Publish to Modrinth (NeoForge) - uses: gradle/gradle-build-action@3bfe3a46584a206fb8361cdedd0647b0c4204232 + uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} env: MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }} diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 851c087c1..309905b25 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -9,7 +9,7 @@ jobs: steps: - name: Set up JDK 17 # See https://github.com/actions/setup-java/commits - uses: actions/setup-java@4075bfc1b51bf22876335ae1cd589602d60d8758 + uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0 with: java-version: 17 distribution: temurin @@ -35,67 +35,67 @@ jobs: - name: Checkout repository and submodules # See https://github.com/actions/checkout/commits - uses: actions/checkout@72f2cec99f417b1a1c5e2e88945068983b7965f9 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: submodules: recursive path: geyser - name: Validate Gradle Wrapper # See https://github.com/gradle/wrapper-validation-action/commits - uses: gradle/wrapper-validation-action@56b90f209b02bf6d1deae490e9ef18b21a389cd4 + uses: gradle/wrapper-validation-action@699bb18358f12c5b78b37bb0111d3a0e2276e0e2 # v2.1.1 - name: Build Geyser # See https://github.com/gradle/gradle-build-action/commits - uses: gradle/gradle-build-action@3bfe3a46584a206fb8361cdedd0647b0c4204232 + uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 from https://github.com/gradle/actions/commits with: arguments: build build-root-directory: geyser - name: Archive artifacts (Geyser Fabric) # See https://github.com/actions/upload-artifact/commits - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 if: success() with: name: Geyser Fabric path: geyser/bootstrap/mod/fabric/build/libs/Geyser-Fabric.jar if-no-files-found: error - name: Archive artifacts (Geyser NeoForge) - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 if: success() with: name: Geyser NeoForge path: geyser/bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar if-no-files-found: error - name: Archive artifacts (Geyser Standalone) - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 if: success() with: name: Geyser Standalone path: geyser/bootstrap/standalone/build/libs/Geyser-Standalone.jar if-no-files-found: error - name: Archive artifacts (Geyser Spigot) - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 if: success() with: name: Geyser Spigot path: geyser/bootstrap/spigot/build/libs/Geyser-Spigot.jar if-no-files-found: error - name: Archive artifacts (Geyser BungeeCord) - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 if: success() with: name: Geyser BungeeCord path: geyser/bootstrap/bungeecord/build/libs/Geyser-BungeeCord.jar if-no-files-found: error - name: Archive artifacts (Geyser Velocity) - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 if: success() with: name: Geyser Velocity path: geyser/bootstrap/velocity/build/libs/Geyser-Velocity.jar if-no-files-found: error - name: Archive artifacts (Geyser ViaProxy) - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 if: success() with: name: Geyser ViaProxy From 1af24e5547e613bf18c58063ca3b89f2374dcc04 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Fri, 8 Mar 2024 21:24:15 +0000 Subject: [PATCH 009/272] Add new village map icons (#4480) --- .../java/org/geysermc/geyser/level/BedrockMapIcon.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/level/BedrockMapIcon.java b/core/src/main/java/org/geysermc/geyser/level/BedrockMapIcon.java index eac8aca09..120e40f17 100644 --- a/core/src/main/java/org/geysermc/geyser/level/BedrockMapIcon.java +++ b/core/src/main/java/org/geysermc/geyser/level/BedrockMapIcon.java @@ -56,7 +56,14 @@ public enum BedrockMapIcon { ICON_GREEN_BANNER(MapIconType.GREEN_BANNER, 13, 94, 124, 22), ICON_RED_BANNER(MapIconType.RED_BANNER, 13, 176, 46, 38), ICON_BLACK_BANNER(MapIconType.BLACK_BANNER, 13, 29, 29, 33), - ICON_TREASURE_MARKER(MapIconType.TREASURE_MARKER, 4); + ICON_TREASURE_MARKER(MapIconType.TREASURE_MARKER, 4), + ICON_DESERT_VILLAGE(MapIconType.DESERT_VILLAGE, 17), + ICON_PLAINS_VILLAGE(MapIconType.PLAINS_VILLAGE, 18), + ICON_SAVANNA_VILLAGE(MapIconType.SAVANNA_VILLAGE, 19), + ICON_SNOWY_VILLAGE(MapIconType.SNOWY_VILLAGE, 20), + ICON_TAIGA_VILLAGE(MapIconType.TAIGA_VILLAGE, 21), + ICON_JUNGLE_TEMPLE(MapIconType.JUNGLE_TEMPLE, 22), + ICON_SWAMP_HUT(MapIconType.SWAMP_HUT, 23); private static final BedrockMapIcon[] VALUES = values(); From 32f66371d97620e7ea4bda3a5a0ca7a5c75b510c Mon Sep 17 00:00:00 2001 From: chris Date: Fri, 8 Mar 2024 22:30:17 +0100 Subject: [PATCH 010/272] Should resolve https://github.com/GeyserMC/Geyser/issues/4121 (#4481) --- .../inventory/PlayerInventoryTranslator.java | 12 ++++++++++++ .../entity/player/BedrockInteractTranslator.java | 11 +---------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java index 613121dfd..1447f2b5b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java @@ -44,6 +44,8 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.SwapAction; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.TransferItemStackRequestAction; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.response.ItemStackResponse; +import org.cloudburstmc.protocol.bedrock.packet.ContainerClosePacket; +import org.cloudburstmc.protocol.bedrock.packet.ContainerOpenPacket; import org.cloudburstmc.protocol.bedrock.packet.InventoryContentPacket; import org.cloudburstmc.protocol.bedrock.packet.InventorySlotPacket; import org.geysermc.geyser.inventory.*; @@ -534,10 +536,20 @@ public class PlayerInventoryTranslator extends InventoryTranslator { @Override public void openInventory(GeyserSession session, Inventory inventory) { + ContainerOpenPacket containerOpenPacket = new ContainerOpenPacket(); + containerOpenPacket.setId((byte) 0); + containerOpenPacket.setType(org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.INVENTORY); + containerOpenPacket.setUniqueEntityId(-1); + containerOpenPacket.setBlockPosition(session.getPlayerEntity().getPosition().toInt()); + session.sendUpstreamPacket(containerOpenPacket); } @Override public void closeInventory(GeyserSession session, Inventory inventory) { + ContainerClosePacket packet = new ContainerClosePacket(); + packet.setServerInitiated(true); + packet.setId((byte) ContainerId.INVENTORY); + session.sendUpstreamPacket(packet); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockInteractTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockInteractTranslator.java index 4b40bb38e..80141f849 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockInteractTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockInteractTranslator.java @@ -33,8 +33,6 @@ import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.Server import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerCommandPacket; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData; -import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; -import org.cloudburstmc.protocol.bedrock.packet.ContainerOpenPacket; import org.cloudburstmc.protocol.bedrock.packet.InteractPacket; import org.cloudburstmc.protocol.bedrock.packet.SetEntityLinkPacket; import org.geysermc.geyser.entity.type.Entity; @@ -126,14 +124,7 @@ public class BedrockInteractTranslator extends PacketTranslator ServerboundPlayerCommandPacket openVehicleWindowPacket = new ServerboundPlayerCommandPacket(session.getPlayerEntity().getEntityId(), PlayerState.OPEN_VEHICLE_INVENTORY); session.sendDownstreamGamePacket(openVehicleWindowPacket); } else { - session.setOpenInventory(session.getPlayerInventory()); - - ContainerOpenPacket containerOpenPacket = new ContainerOpenPacket(); - containerOpenPacket.setId((byte) 0); - containerOpenPacket.setType(ContainerType.INVENTORY); - containerOpenPacket.setUniqueEntityId(-1); - containerOpenPacket.setBlockPosition(entity.getPosition().toInt()); - session.sendUpstreamPacket(containerOpenPacket); + InventoryUtils.openInventory(session, session.getPlayerInventory()); } } else { // Case: Player opens a player inventory, while we think it shouldn't have! From f1e125a360356070f12dc33f5c4e3b1cc7660c65 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Fri, 8 Mar 2024 21:32:28 +0000 Subject: [PATCH 011/272] Add merge group trigger to pullrequest workflow (#4482) --- .github/workflows/pullrequest.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 309905b25..93be4711e 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -2,6 +2,7 @@ name: Build Pull Request on: pull_request: + merge_group: jobs: build: From 92ce0fc6c7bbb061f7428c88a695e9f8e06d0788 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Sat, 9 Mar 2024 01:24:16 +0000 Subject: [PATCH 012/272] Ignore merge queue branches from build workflow (#4483) --- .github/workflows/build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 385797af7..1d70d9948 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,6 +3,8 @@ name: Build on: workflow_dispatch: push: + branches-ignore: + - 'gh-readonly-queue/**' paths-ignore: - '.github/ISSUE_TEMPLATE/*.yml' - '.github/actions/pullrequest.yml' From 527eab0b586c8a8904beb3ed989036e7e08f9f9d Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Fri, 8 Mar 2024 19:51:32 -0800 Subject: [PATCH 013/272] Cap render distance at 96 (#3530) Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> Co-authored-by: onebeastchris --- .../main/java/org/geysermc/geyser/session/GeyserSession.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 8bdb41979..73cbf32c8 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -1464,6 +1464,11 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { } public void setServerRenderDistance(int renderDistance) { + // +1 is for Fabric and Spigot + // Without the client misses loading some chunks per https://github.com/GeyserMC/Geyser/issues/3490 + // Fog still appears essentially normally + // Ensure render distance is not above 96 as sending a larger value at any point crashes mobile clients and 96 is the max of any bedrock platform + renderDistance = Math.min(renderDistance, 96); this.serverRenderDistance = renderDistance; ChunkRadiusUpdatedPacket chunkRadiusUpdatedPacket = new ChunkRadiusUpdatedPacket(); From 0ad7c4325d43b0865c0ebea5cd0f83aba93bf40d Mon Sep 17 00:00:00 2001 From: chris Date: Sun, 10 Mar 2024 23:38:38 +0100 Subject: [PATCH 014/272] Fix: Workaround for recipes involving custom items to show up in the recipe book (#4484) * Allow adding custom items to the creative inventory in order for recipes outputting said custom items to work * yeet includeInCreativeInventory as it would break existing nonvanilla extensions - and is pretty pointless anyways * rename mappings to `creative_group` and `creative_category` * delete outdated comment --- .../api/block/custom/CustomBlockData.java | 8 +-- .../api/item/custom/CustomItemData.java | 19 ++++++ .../item/custom/NonVanillaCustomItemData.java | 25 ++------ .../geyser/item/GeyserCustomItemData.java | 35 ++++++++++- .../item/GeyserNonVanillaCustomItemData.java | 62 +++++++------------ .../mappings/versions/MappingsReader_v1.java | 8 +++ .../CustomItemRegistryPopulator.java | 27 +++++--- .../populator/ItemRegistryPopulator.java | 12 +++- .../geyser/session/GeyserSession.java | 7 +-- 9 files changed, 124 insertions(+), 79 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/block/custom/CustomBlockData.java b/api/src/main/java/org/geysermc/geyser/api/block/custom/CustomBlockData.java index 9f142faab..2605cda21 100644 --- a/api/src/main/java/org/geysermc/geyser/api/block/custom/CustomBlockData.java +++ b/api/src/main/java/org/geysermc/geyser/api/block/custom/CustomBlockData.java @@ -61,16 +61,16 @@ public interface CustomBlockData { boolean includedInCreativeInventory(); /** - * Gets the item's creative category, or tab id. + * Gets the block's creative category, or tab id. * - * @return the item's creative category + * @return the block's creative category */ @Nullable CreativeCategory creativeCategory(); /** - * Gets the item's creative group. + * Gets the block's creative group. * - * @return the item's creative group + * @return the block's creative group */ @Nullable String creativeGroup(); diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java index 404679e60..3b871cd74 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java @@ -29,6 +29,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.api.GeyserApi; +import java.util.OptionalInt; import java.util.Set; /** @@ -77,6 +78,20 @@ public interface CustomItemData { */ boolean displayHandheld(); + /** + * Gets the item's creative category, or tab id. + * + * @return the item's creative category + */ + @NonNull OptionalInt creativeCategory(); + + /** + * Gets the item's creative group. + * + * @return the item's creative group + */ + @Nullable String creativeGroup(); + /** * Gets the item's texture size. This is to resize the item if the texture is not 16x16. * @@ -119,6 +134,10 @@ public interface CustomItemData { Builder displayHandheld(boolean displayHandheld); + Builder creativeCategory(int creativeCategory); + + Builder creativeGroup(@Nullable String creativeGroup); + Builder textureSize(int textureSize); Builder renderOffsets(@Nullable CustomRenderOffsets renderOffsets); diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java index 616a5bba6..37a4247d1 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java @@ -30,7 +30,6 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.api.GeyserApi; -import java.util.OptionalInt; import java.util.Set; /** @@ -107,20 +106,6 @@ public interface NonVanillaCustomItemData extends CustomItemData { */ @Nullable Set repairMaterials(); - /** - * Gets the item's creative category, or tab id. - * - * @return the item's creative category - */ - @NonNull OptionalInt creativeCategory(); - - /** - * Gets the item's creative group. - * - * @return the item's creative group - */ - @Nullable String creativeGroup(); - /** * Gets if the item is a hat. This is used to determine if the item should be rendered on the player's head, and * normally allow the player to equip it. This is not meant for armor. @@ -196,10 +181,6 @@ public interface NonVanillaCustomItemData extends CustomItemData { Builder repairMaterials(@Nullable Set repairMaterials); - Builder creativeCategory(int creativeCategory); - - Builder creativeGroup(@Nullable String creativeGroup); - Builder hat(boolean isHat); Builder foil(boolean isFoil); @@ -218,6 +199,12 @@ public interface NonVanillaCustomItemData extends CustomItemData { return displayHandheld(isTool); } + @Override + Builder creativeCategory(int creativeCategory); + + @Override + Builder creativeGroup(@Nullable String creativeGroup); + @Override Builder customItemOptions(@NonNull CustomItemOptions customItemOptions); diff --git a/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java b/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java index 2906a9be3..a2054f78a 100644 --- a/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java +++ b/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java @@ -35,6 +35,7 @@ import org.geysermc.geyser.api.item.custom.CustomRenderOffsets; import java.util.HashSet; import java.util.Objects; +import java.util.OptionalInt; import java.util.Set; @EqualsAndHashCode @@ -46,6 +47,8 @@ public class GeyserCustomItemData implements CustomItemData { private final String icon; private final boolean allowOffhand; private final boolean displayHandheld; + private final OptionalInt creativeCategory; + private final String creativeGroup; private final int textureSize; private final CustomRenderOffsets renderOffsets; private final Set tags; @@ -56,6 +59,8 @@ public class GeyserCustomItemData implements CustomItemData { String icon, boolean allowOffhand, boolean displayHandheld, + OptionalInt creativeCategory, + String creativeGroup, int textureSize, CustomRenderOffsets renderOffsets, Set tags) { @@ -65,6 +70,8 @@ public class GeyserCustomItemData implements CustomItemData { this.icon = icon; this.allowOffhand = allowOffhand; this.displayHandheld = displayHandheld; + this.creativeCategory = creativeCategory; + this.creativeGroup = creativeGroup; this.textureSize = textureSize; this.renderOffsets = renderOffsets; this.tags = tags; @@ -100,6 +107,16 @@ public class GeyserCustomItemData implements CustomItemData { return this.displayHandheld; } + @Override + public @NonNull OptionalInt creativeCategory() { + return this.creativeCategory; + } + + @Override + public @Nullable String creativeGroup() { + return this.creativeGroup; + } + @Override public int textureSize() { return textureSize; @@ -118,11 +135,12 @@ public class GeyserCustomItemData implements CustomItemData { public static class Builder implements CustomItemData.Builder { protected String name = null; protected CustomItemOptions customItemOptions = null; - protected String displayName = null; protected String icon = null; protected boolean allowOffhand = true; // Bedrock doesn't give items offhand allowance unless they serve gameplay purpose, but we want to be friendly with Java protected boolean displayHandheld = false; + protected OptionalInt creativeCategory = OptionalInt.empty(); + protected String creativeGroup = null; protected int textureSize = 16; protected CustomRenderOffsets renderOffsets = null; protected Set tags = new HashSet<>(); @@ -163,6 +181,18 @@ public class GeyserCustomItemData implements CustomItemData { return this; } + @Override + public Builder creativeCategory(int creativeCategory) { + this.creativeCategory = OptionalInt.of(creativeCategory); + return this; + } + + @Override + public Builder creativeGroup(@Nullable String creativeGroup) { + this.creativeGroup = creativeGroup; + return this; + } + @Override public Builder textureSize(int textureSize) { this.textureSize = textureSize; @@ -193,7 +223,8 @@ public class GeyserCustomItemData implements CustomItemData { if (this.icon == null) { this.icon = this.name; } - return new GeyserCustomItemData(this.name, this.customItemOptions, this.displayName, this.icon, this.allowOffhand, this.displayHandheld, this.textureSize, this.renderOffsets, this.tags); + return new GeyserCustomItemData(this.name, this.customItemOptions, this.displayName, this.icon, this.allowOffhand, + this.displayHandheld, this.creativeCategory, this.creativeGroup, this.textureSize, this.renderOffsets, this.tags); } } } diff --git a/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java b/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java index bb4e60589..14f8c3a39 100644 --- a/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java +++ b/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java @@ -33,10 +33,8 @@ import org.geysermc.geyser.api.item.custom.CustomItemOptions; import org.geysermc.geyser.api.item.custom.CustomRenderOffsets; import org.geysermc.geyser.api.item.custom.NonVanillaCustomItemData; -import java.util.OptionalInt; import java.util.Set; -@SuppressWarnings("OptionalUsedAsFieldOrParameterType") @EqualsAndHashCode(callSuper = true) @ToString public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData implements NonVanillaCustomItemData { @@ -50,8 +48,6 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i private final int protectionValue; private final String translationString; private final Set repairMaterials; - private final OptionalInt creativeCategory; - private final String creativeGroup; private final boolean isHat; private final boolean isFoil; private final boolean isTool; @@ -61,7 +57,8 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i public GeyserNonVanillaCustomItemData(Builder builder) { super(builder.name, builder.customItemOptions, builder.displayName, builder.icon, builder.allowOffhand, - builder.displayHandheld, builder.textureSize, builder.renderOffsets, builder.tags); + builder.displayHandheld, builder.creativeCategory, builder.creativeGroup, + builder.textureSize, builder.renderOffsets, builder.tags); this.identifier = builder.identifier; this.javaId = builder.javaId; @@ -73,8 +70,6 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i this.protectionValue = builder.protectionValue; this.translationString = builder.translationString; this.repairMaterials = builder.repairMaterials; - this.creativeCategory = builder.creativeCategory; - this.creativeGroup = builder.creativeGroup; this.isHat = builder.hat; this.isFoil = builder.foil; this.isTool = builder.tool; @@ -133,16 +128,6 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i return repairMaterials; } - @Override - public @NonNull OptionalInt creativeCategory() { - return creativeCategory; - } - - @Override - public String creativeGroup() { - return creativeGroup; - } - @Override public boolean isHat() { return isHat; @@ -186,9 +171,6 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i private Set repairMaterials; - private OptionalInt creativeCategory = OptionalInt.empty(); - private String creativeGroup = null; - private boolean hat = false; private boolean foil = false; private boolean tool = false; @@ -243,103 +225,101 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i } @Override - public NonVanillaCustomItemData.Builder identifier(@NonNull String identifier) { + public Builder identifier(@NonNull String identifier) { this.identifier = identifier; return this; } @Override - public NonVanillaCustomItemData.Builder javaId(int javaId) { + public Builder javaId(int javaId) { this.javaId = javaId; return this; } @Override - public NonVanillaCustomItemData.Builder stackSize(int stackSize) { + public Builder stackSize(int stackSize) { this.stackSize = stackSize; return this; } @Override - public NonVanillaCustomItemData.Builder maxDamage(int maxDamage) { + public Builder maxDamage(int maxDamage) { this.maxDamage = maxDamage; return this; } @Override - public NonVanillaCustomItemData.Builder toolType(@Nullable String toolType) { + public Builder toolType(@Nullable String toolType) { this.toolType = toolType; return this; } @Override - public NonVanillaCustomItemData.Builder toolTier(@Nullable String toolTier) { + public Builder toolTier(@Nullable String toolTier) { this.toolTier = toolTier; return this; } @Override - public NonVanillaCustomItemData.Builder armorType(@Nullable String armorType) { + public Builder armorType(@Nullable String armorType) { this.armorType = armorType; return this; } @Override - public NonVanillaCustomItemData.Builder protectionValue(int protectionValue) { + public Builder protectionValue(int protectionValue) { this.protectionValue = protectionValue; return this; } @Override - public NonVanillaCustomItemData.Builder translationString(@Nullable String translationString) { + public Builder translationString(@Nullable String translationString) { this.translationString = translationString; return this; } @Override - public NonVanillaCustomItemData.Builder repairMaterials(@Nullable Set repairMaterials) { + public Builder repairMaterials(@Nullable Set repairMaterials) { this.repairMaterials = repairMaterials; return this; } @Override - public NonVanillaCustomItemData.Builder creativeCategory(int creativeCategory) { - this.creativeCategory = OptionalInt.of(creativeCategory); - return this; + public Builder creativeCategory(int creativeCategory) { + return (Builder) super.creativeCategory(creativeCategory); } @Override - public NonVanillaCustomItemData.Builder creativeGroup(@Nullable String creativeGroup) { - this.creativeGroup = creativeGroup; - return this; + public Builder creativeGroup(@Nullable String creativeGroup) { + return (Builder) super.creativeGroup(creativeGroup); } @Override - public NonVanillaCustomItemData.Builder hat(boolean isHat) { + public Builder hat(boolean isHat) { this.hat = isHat; return this; } @Override - public NonVanillaCustomItemData.Builder foil(boolean isFoil) { + public Builder foil(boolean isFoil) { this.foil = isFoil; return this; } @Override - public NonVanillaCustomItemData.Builder edible(boolean isEdible) { + public Builder edible(boolean isEdible) { this.edible = isEdible; return this; } @Override - public NonVanillaCustomItemData.Builder canAlwaysEat(boolean canAlwaysEat) { + public Builder canAlwaysEat(boolean canAlwaysEat) { this.canAlwaysEat = canAlwaysEat; return this; } @Override - public NonVanillaCustomItemData.Builder chargeable(boolean isChargeable) { + public Builder chargeable(boolean isChargeable) { this.chargeable = isChargeable; return this; } diff --git a/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java b/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java index ce4a8f30e..e8901a550 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java +++ b/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java @@ -193,6 +193,14 @@ public class MappingsReader_v1 extends MappingsReader { customItemData.icon(node.get("icon").asText()); } + if (node.has("creative_category")) { + customItemData.creativeCategory(node.get("creative_category").asInt()); + } + + if (node.has("creative_group")) { + customItemData.creativeGroup(node.get("creative_group").asText()); + } + if (node.has("allow_offhand")) { customItemData.allowOffhand(node.get("allow_offhand").asBoolean()); } diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java index c1f1bb10c..2e00bd4ad 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java @@ -246,13 +246,6 @@ public class CustomItemRegistryPopulator { computeRenderOffsets(isHat, customItemData, componentBuilder); - if (creativeGroup != null) { - itemProperties.putString("creative_group", creativeGroup); - } - if (creativeCategory.isPresent()) { - itemProperties.putInt("creative_category", creativeCategory.getAsInt()); - } - if (customItemData.isFoil()) { itemProperties.putBoolean("foil", true); } @@ -278,6 +271,14 @@ public class CustomItemRegistryPopulator { } itemProperties.putCompound("minecraft:icon", iconMap); + if (customItemData.creativeCategory().isPresent()) { + itemProperties.putInt("creative_category", customItemData.creativeCategory().getAsInt()); + + if (customItemData.creativeGroup() != null) { + itemProperties.putString("creative_group", customItemData.creativeGroup()); + } + } + componentBuilder.putCompound("minecraft:display_name", NbtMap.builder().putString("value", customItemData.displayName()).build()); // Add a Geyser tag to the item, allowing Molang queries @@ -370,21 +371,33 @@ public class CustomItemRegistryPopulator { componentBuilder.putString("minecraft:render_offsets", "boots"); componentBuilder.putCompound("minecraft:wearable", WearableSlot.FEET.getSlotNbt()); componentBuilder.putCompound("minecraft:armor", NbtMap.builder().putInt("protection", protectionValue).build()); + + itemProperties.putString("enchantable_slot", "armor_feet"); + itemProperties.putInt("enchantable_value", 15); } case "chestplate" -> { componentBuilder.putString("minecraft:render_offsets", "chestplates"); componentBuilder.putCompound("minecraft:wearable", WearableSlot.CHEST.getSlotNbt()); componentBuilder.putCompound("minecraft:armor", NbtMap.builder().putInt("protection", protectionValue).build()); + + itemProperties.putString("enchantable_slot", "armor_torso"); + itemProperties.putInt("enchantable_value", 15); } case "leggings" -> { componentBuilder.putString("minecraft:render_offsets", "leggings"); componentBuilder.putCompound("minecraft:wearable", WearableSlot.LEGS.getSlotNbt()); componentBuilder.putCompound("minecraft:armor", NbtMap.builder().putInt("protection", protectionValue).build()); + + itemProperties.putString("enchantable_slot", "armor_legs"); + itemProperties.putInt("enchantable_value", 15); } case "helmet" -> { componentBuilder.putString("minecraft:render_offsets", "helmets"); componentBuilder.putCompound("minecraft:wearable", WearableSlot.HEAD.getSlotNbt()); componentBuilder.putCompound("minecraft:armor", NbtMap.builder().putInt("protection", protectionValue).build()); + + itemProperties.putString("enchantable_slot", "armor_head"); + itemProperties.putInt("enchantable_value", 15); } } } diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java index 539452169..c1593447d 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java @@ -425,6 +425,16 @@ public class ItemRegistryPopulator { GeyserCustomMappingData customMapping = CustomItemRegistryPopulator.registerCustomItem( customItemName, javaItem, mappingItem, customItem, customProtocolId, palette.protocolVersion ); + + if (customItem.creativeCategory().isPresent()) { + creativeItems.add(ItemData.builder() + .netId(creativeNetId.incrementAndGet()) + .definition(customMapping.itemDefinition()) + .blockDefinition(null) + .count(1) + .build()); + } + // ComponentItemData - used to register some custom properties componentItemData.add(customMapping.componentItemData()); customItemOptions.add(Pair.of(customItem.customItemOptions(), customMapping.itemDefinition())); @@ -523,7 +533,7 @@ public class ItemRegistryPopulator { mappings.set(javaItem.javaId(), mapping); registry.put(customItemId, mapping.getBedrockDefinition()); - if (customItem.creativeGroup() != null || customItem.creativeCategory().isPresent()) { + if (customItem.creativeCategory().isPresent()) { creativeItems.add(ItemData.builder() .definition(registration.mapping().getBedrockDefinition()) .netId(creativeNetId.incrementAndGet()) diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 73cbf32c8..7a4a8ff6f 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -113,8 +113,6 @@ import org.geysermc.geyser.api.event.bedrock.SessionLoginEvent; import org.geysermc.geyser.api.network.AuthType; import org.geysermc.geyser.api.network.RemoteServer; import org.geysermc.geyser.api.util.PlatformType; -import org.geysermc.geyser.impl.camera.CameraDefinitions; -import org.geysermc.geyser.impl.camera.GeyserCameraData; import org.geysermc.geyser.command.GeyserCommandSource; import org.geysermc.geyser.configuration.EmoteOffhandWorkaroundOption; import org.geysermc.geyser.configuration.GeyserConfiguration; @@ -127,6 +125,8 @@ import org.geysermc.geyser.entity.type.Tickable; import org.geysermc.geyser.entity.type.player.SessionPlayerEntity; import org.geysermc.geyser.erosion.AbstractGeyserboundPacketHandler; import org.geysermc.geyser.erosion.GeyserboundHandshakePacketHandler; +import org.geysermc.geyser.impl.camera.CameraDefinitions; +import org.geysermc.geyser.impl.camera.GeyserCameraData; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.PlayerInventory; import org.geysermc.geyser.inventory.recipe.GeyserRecipe; @@ -1464,9 +1464,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { } public void setServerRenderDistance(int renderDistance) { - // +1 is for Fabric and Spigot - // Without the client misses loading some chunks per https://github.com/GeyserMC/Geyser/issues/3490 - // Fog still appears essentially normally // Ensure render distance is not above 96 as sending a larger value at any point crashes mobile clients and 96 is the max of any bedrock platform renderDistance = Math.min(renderDistance, 96); this.serverRenderDistance = renderDistance; From a0fd720e7c00a542933b9e8544c5fb3e8f3d7cb8 Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Mon, 11 Mar 2024 00:03:37 -0700 Subject: [PATCH 015/272] Fix client crash issue if empty recipe is sent (#4485) * Fix client crash issue if empty recipe is sent Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * More efficent order Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Recipes are recipies Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> --------- Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> --- .../java/JavaClientboundRecipesTranslator.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaClientboundRecipesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaClientboundRecipesTranslator.java index fbf4c6f7b..3fe5abff8 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaClientboundRecipesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaClientboundRecipesTranslator.java @@ -27,7 +27,6 @@ package org.geysermc.geyser.translator.protocol.java; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundRecipePacket; import org.cloudburstmc.protocol.bedrock.packet.UnlockedRecipesPacket; -import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; @@ -47,12 +46,22 @@ public class JavaClientboundRecipesTranslator extends PacketTranslator { + List recipes = getBedrockRecipes(session, packet.getRecipes()); + if (recipes.isEmpty()) { + // Sending an empty list here packet will crash the client as of 1.20.60 + return; + } recipesPacket.setAction(UnlockedRecipesPacket.ActionType.NEWLY_UNLOCKED); - recipesPacket.getUnlockedRecipes().addAll(getBedrockRecipes(session, packet.getRecipes())); + recipesPacket.getUnlockedRecipes().addAll(recipes); } case REMOVE -> { + List recipes = getBedrockRecipes(session, packet.getRecipes()); + if (recipes.isEmpty()) { + // Sending an empty list here will crash the client as of 1.20.60 + return; + } recipesPacket.setAction(UnlockedRecipesPacket.ActionType.REMOVE_UNLOCKED); - recipesPacket.getUnlockedRecipes().addAll(getBedrockRecipes(session, packet.getRecipes())); + recipesPacket.getUnlockedRecipes().addAll(recipes); } } session.sendUpstreamPacket(recipesPacket); @@ -70,5 +79,4 @@ public class JavaClientboundRecipesTranslator extends PacketTranslator Date: Mon, 11 Mar 2024 00:29:27 -0700 Subject: [PATCH 016/272] Support Bedrock 1.20.70 (#4477) * Support 1.20.70 Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Update readme Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Use 1.20.70 mappings Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Creative lectern drops work but not survival yet Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Fix lectern book pickup in survival Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Add copyright notices to new files Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Temp fix for incorrect creative_items from Cloudburst/Data Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Fix item frame breaking in creative Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Clarify what to remove when 1.20.60 support is dropped Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Don't use dim change enum pre 1.20.70 Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> --------- Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> --- README.md | 2 +- build-logic/src/main/kotlin/extensions.kt | 48 +- core/build.gradle.kts | 16 + .../geysermc/geyser/network/GameProtocol.java | 12 +- .../populator/BlockRegistryPopulator.java | 8 +- .../registry/populator/Conversion630_622.java | 4 + ...ion630_649.java => Conversion649_630.java} | 36 +- .../registry/populator/Conversion662_649.java | 156 + .../populator/ItemRegistryPopulator.java | 6 +- .../BedrockItemFrameDropItemTranslator.java | 2 + .../BedrockLecternUpdateTranslator.java | 1 + .../player/BedrockActionTranslator.java | 76 +- .../BedrockLevelSoundEventTranslator.java | 26 + .../resources/bedrock/biome_definitions.dat | Bin 2605093 -> 41676 bytes .../bedrock/block_palette.1_20_70.nbt | Bin 0 -> 176502 bytes .../bedrock/creative_items.1_20_70.json | 5803 ++++++++++++++++ .../resources/bedrock/entity_identifiers.dat | Bin 7886 -> 7886 bytes .../bedrock/runtime_item_states.1_20_70.json | 6126 +++++++++++++++++ core/src/main/resources/mappings | 2 +- gradle/libs.versions.toml | 6 +- 20 files changed, 12288 insertions(+), 42 deletions(-) rename core/src/main/java/org/geysermc/geyser/registry/populator/{Conversion630_649.java => Conversion649_630.java} (51%) create mode 100644 core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java create mode 100644 core/src/main/resources/bedrock/block_palette.1_20_70.nbt create mode 100644 core/src/main/resources/bedrock/creative_items.1_20_70.json create mode 100644 core/src/main/resources/bedrock/runtime_item_states.1_20_70.json diff --git a/README.md b/README.md index d58e2eb58..c6445155f 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here! -### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.61 and Minecraft Java 1.20.4 +### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.70 and Minecraft Java 1.20.4 ## Setting Up Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser. diff --git a/build-logic/src/main/kotlin/extensions.kt b/build-logic/src/main/kotlin/extensions.kt index 1e1732852..b4a14f678 100644 --- a/build-logic/src/main/kotlin/extensions.kt +++ b/build-logic/src/main/kotlin/extensions.kt @@ -24,11 +24,17 @@ */ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar +import org.gradle.api.DefaultTask import org.gradle.api.Project import org.gradle.api.artifacts.MinimalExternalModuleDependency import org.gradle.api.artifacts.ProjectDependency import org.gradle.api.provider.Provider +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.options.Option +import org.gradle.api.tasks.TaskAction import org.gradle.kotlin.dsl.named +import java.io.File +import java.net.URL fun Project.relocate(pattern: String) { tasks.named("shadowJar") { @@ -69,5 +75,45 @@ fun Project.provided(dependency: MinimalExternalModuleDependency) = fun Project.provided(provider: Provider) = provided(provider.get()) +open class DownloadFilesTask : DefaultTask() { + @Input + var urls: List = listOf() + + @Input + var destinationDir: String = "" + + @Option(option="suffix", description="suffix") + @Input + var suffix: String = "" + + @Input + var suffixedFiles: List = listOf() + + @TaskAction + fun downloadAndAddSuffix() { + urls.forEach { fileUrl -> + val fileName = fileUrl.substringAfterLast("/") + val baseName = fileName.substringBeforeLast(".") + val extension = fileName.substringAfterLast(".", "") + val shouldSuffix = fileName in suffixedFiles + val suffixedFileName = if (shouldSuffix && extension.isNotEmpty()) "$baseName.$suffix.$extension" else fileName + val outputFile = File(destinationDir, suffixedFileName) + + if (!outputFile.parentFile.exists()) { + outputFile.parentFile.mkdirs() + } + + URL(fileUrl).openStream().use { input -> + outputFile.outputStream().use { output -> + input.copyTo(output) + } + } + + println("Downloaded: $suffixedFileName") + } + } +} + private fun calcExclusion(section: String, bit: Int, excludedOn: Int): String = - if (excludedOn and bit > 0) section else "" \ No newline at end of file + if (excludedOn and bit > 0) section else "" + diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 6d289ae37..054f4f0ae 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -132,3 +132,19 @@ inner class GitInfo { // todo remove this when we're not using Jenkins anymore fun jenkinsBuildNumber(): String? = System.getenv("BUILD_NUMBER") + +// Manual task to download the bedrock data files from the CloudburstMC/Data repository +// Invoke with ./gradlew :core:downloadBedrockData --suffix=1_20_70 +// Set suffix to the current Bedrock version +tasks.register("downloadBedrockData") { + urls = listOf( + "https://raw.githubusercontent.com/CloudburstMC/Data/master/entity_identifiers.dat", + "https://raw.githubusercontent.com/CloudburstMC/Data/master/biome_definitions.dat", + "https://raw.githubusercontent.com/CloudburstMC/Data/master/block_palette.nbt", + "https://raw.githubusercontent.com/CloudburstMC/Data/master/creative_items.json", + "https://raw.githubusercontent.com/CloudburstMC/Data/master/runtime_item_states.json" + ) + suffixedFiles = listOf("block_palette.nbt", "creative_items.json", "runtime_item_states.json") + + destinationDir = "$projectDir/src/main/resources/bedrock" +} \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java index a03a36ad2..3ead79d9e 100644 --- a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java +++ b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java @@ -32,6 +32,7 @@ import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec; import org.cloudburstmc.protocol.bedrock.codec.v622.Bedrock_v622; import org.cloudburstmc.protocol.bedrock.codec.v630.Bedrock_v630; import org.cloudburstmc.protocol.bedrock.codec.v649.Bedrock_v649; +import org.cloudburstmc.protocol.bedrock.codec.v662.Bedrock_v662; import org.cloudburstmc.protocol.bedrock.netty.codec.packet.BedrockPacketCodec; import org.geysermc.geyser.session.GeyserSession; @@ -47,7 +48,7 @@ public final class GameProtocol { * Default Bedrock codec that should act as a fallback. Should represent the latest available * release of the game that Geyser supports. */ - public static final BedrockCodec DEFAULT_BEDROCK_CODEC = Bedrock_v649.CODEC; + public static final BedrockCodec DEFAULT_BEDROCK_CODEC = Bedrock_v662.CODEC; /** * A list of all supported Bedrock versions that can join Geyser @@ -67,8 +68,11 @@ public final class GameProtocol { SUPPORTED_BEDROCK_CODECS.add(Bedrock_v630.CODEC.toBuilder() .minecraftVersion("1.20.50/1.20.51") .build()); + SUPPORTED_BEDROCK_CODECS.add(Bedrock_v649.CODEC.toBuilder() + .minecraftVersion("1.20.60/1.20.62") + .build()); SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC.toBuilder() - .minecraftVersion("1.20.60/1.20.61") + .minecraftVersion("1.20.70") .build()); } @@ -92,6 +96,10 @@ public final class GameProtocol { return session.getUpstream().getProtocolVersion() < Bedrock_v630.CODEC.getProtocolVersion(); } + public static boolean isPre1_20_70(GeyserSession session) { + return session.getUpstream().getProtocolVersion() < Bedrock_v662.CODEC.getProtocolVersion(); + } + public static boolean is1_20_60orHigher(int protocolVersion) { return protocolVersion >= Bedrock_v649.CODEC.getProtocolVersion(); } diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java index 8aa16fe48..4c52a1530 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java @@ -42,6 +42,7 @@ import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.codec.v622.Bedrock_v622; import org.cloudburstmc.protocol.bedrock.codec.v630.Bedrock_v630; import org.cloudburstmc.protocol.bedrock.codec.v649.Bedrock_v649; +import org.cloudburstmc.protocol.bedrock.codec.v662.Bedrock_v662; import org.cloudburstmc.protocol.bedrock.data.BlockPropertyData; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.geysermc.geyser.GeyserImpl; @@ -118,9 +119,10 @@ public final class BlockRegistryPopulator { private static void registerBedrockBlocks() { var blockMappers = ImmutableMap., Remapper>builder() .put(ObjectIntPair.of("1_20_40", Bedrock_v622.CODEC.getProtocolVersion()), Conversion630_622::remapBlock) - .put(ObjectIntPair.of("1_20_50", Bedrock_v630.CODEC.getProtocolVersion()), tag -> tag) + .put(ObjectIntPair.of("1_20_50", Bedrock_v630.CODEC.getProtocolVersion()), Conversion649_630::remapBlock) // Only changes in 1.20.60 are hard_stained_glass (an EDU only block) - .put(ObjectIntPair.of("1_20_60", Bedrock_v649.CODEC.getProtocolVersion()), tag -> tag) + .put(ObjectIntPair.of("1_20_60", Bedrock_v649.CODEC.getProtocolVersion()), Conversion662_649::remapBlock) + .put(ObjectIntPair.of("1_20_70", Bedrock_v662.CODEC.getProtocolVersion()), tag -> tag) .build(); // We can keep this strong as nothing should be garbage collected @@ -133,7 +135,7 @@ public final class BlockRegistryPopulator { List vanillaBlockStates; List blockStates; try (InputStream stream = GeyserImpl.getInstance().getBootstrap().getResourceOrThrow(String.format("bedrock/block_palette.%s.nbt", palette.key())); - NBTInputStream nbtInputStream = new NBTInputStream(new DataInputStream(new GZIPInputStream(stream)), true, true)) { + NBTInputStream nbtInputStream = new NBTInputStream(new DataInputStream(new GZIPInputStream(stream)), true, true)) { NbtMap blockPalette = (NbtMap) nbtInputStream.readTag(); vanillaBlockStates = new ArrayList<>(blockPalette.getList("blocks", NbtType.COMPOUND)); diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion630_622.java b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion630_622.java index 7c1453dc7..398eabc3c 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion630_622.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion630_622.java @@ -121,6 +121,8 @@ class Conversion630_622 { } static GeyserMappingItem remapItem(@SuppressWarnings("unused") Item item, GeyserMappingItem mapping) { + mapping = Conversion649_630.remapItem(item, mapping); + String replacement = ITEMS.get(mapping.getBedrockIdentifier()); if (replacement == null) { return mapping; @@ -130,6 +132,8 @@ class Conversion630_622 { } static NbtMap remapBlock(NbtMap tag) { + tag = Conversion649_630.remapBlock(tag); + final String name = tag.getString("name"); String replacement; diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion630_649.java b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion649_630.java similarity index 51% rename from core/src/main/java/org/geysermc/geyser/registry/populator/Conversion630_649.java rename to core/src/main/java/org/geysermc/geyser/registry/populator/Conversion649_630.java index ed66322ff..56de1081e 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion630_649.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion649_630.java @@ -22,19 +22,41 @@ * @author GeyserMC * @link https://github.com/GeyserMC/Geyser */ - package org.geysermc.geyser.registry.populator; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.registry.type.GeyserMappingItem; +public class Conversion649_630 { + + static GeyserMappingItem remapItem(@SuppressWarnings("unused") Item item, GeyserMappingItem mapping) { + mapping = Conversion662_649.remapItem(item, mapping); -public class Conversion630_649 { + String identifer = mapping.getBedrockIdentifier(); - static GeyserMappingItem remapItem(@SuppressWarnings("unused") Item item, GeyserMappingItem mapping) { - if (mapping.getBedrockIdentifier().equalsIgnoreCase("minecraft:scute")) { - return mapping.withBedrockIdentifier("minecraft:turtle_scute"); + switch (identifer) { + case "minecraft:turtle_scute" -> { return mapping.withBedrockIdentifier("minecraft:scute"); } + case "minecraft:trial_spawner" -> { return mapping.withBedrockIdentifier("minecraft:mob_spawner"); } + case "minecraft:trial_key" -> { return mapping.withBedrockIdentifier("minecraft:echo_shard"); } + default -> { return mapping; } + } + } + + static NbtMap remapBlock(NbtMap tag) { + tag = Conversion662_649.remapBlock(tag); + + final String name = tag.getString("name"); + + if (name.equals("minecraft:trial_spawner")) { + NbtMapBuilder builder = tag.toBuilder() + .putString("name", "minecraft:mob_spawner") + .putCompound("states", NbtMap.EMPTY); + + return builder.build(); + } + + return tag; } - return mapping; - } } diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java new file mode 100644 index 000000000..6dc6b01a0 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.registry.populator; + +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; +import org.geysermc.geyser.item.type.Item; +import org.geysermc.geyser.registry.type.GeyserMappingItem; + +import java.util.List; +import java.util.stream.Stream; + +public class Conversion662_649 { + + private static final List NEW_MISC = List.of("minecraft:grass_block", "minecraft:trial_spawner"); + private static final List NEW_WOODS = List.of("minecraft:oak_wood", "minecraft:spruce_wood", "minecraft:birch_wood", "minecraft:jungle_wood", "minecraft:acacia_wood", "minecraft:dark_oak_wood", "minecraft:stripped_oak_wood", "minecraft:stripped_spruce_wood", "minecraft:stripped_birch_wood", "minecraft:stripped_jungle_wood", "minecraft:stripped_acacia_wood", "minecraft:stripped_dark_oak_wood"); + private static final List NEW_LEAVES = List.of("minecraft:oak_leaves", "minecraft:spruce_leaves", "minecraft:birch_leaves", "minecraft:jungle_leaves"); + private static final List NEW_LEAVES2 = List.of("minecraft:acacia_leaves", "minecraft:dark_oak_leaves"); + private static final List NEW_SLABS = List.of("minecraft:oak_slab", "minecraft:spruce_slab", "minecraft:birch_slab", "minecraft:jungle_slab", "minecraft:acacia_slab", "minecraft:dark_oak_slab", "minecraft:oak_double_slab", "minecraft:spruce_double_slab", "minecraft:birch_double_slab", "minecraft:jungle_double_slab", "minecraft:acacia_double_slab", "minecraft:dark_oak_double_slab"); + private static final List NEW_BLOCKS = Stream.of(NEW_WOODS, NEW_LEAVES, NEW_LEAVES2, NEW_SLABS, NEW_MISC).flatMap(List::stream).toList(); + + + static GeyserMappingItem remapItem(@SuppressWarnings("unused") Item item, GeyserMappingItem mapping) { + String identifer = mapping.getBedrockIdentifier(); + + if (identifer.equals("minecraft:grass_block")) { + return mapping.withBedrockIdentifier("minecraft:grass"); + } + + if (NEW_WOODS.contains(identifer)) { + switch (identifer) { + case "minecraft:oak_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(0); } + case "minecraft:spruce_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(1); } + case "minecraft:birch_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(2); } + case "minecraft:jungle_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(3); } + case "minecraft:acacia_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(4); } + case "minecraft:dark_oak_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(5); } + case "minecraft:stripped_oak_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(8); } + case "minecraft:stripped_spruce_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(9); } + case "minecraft:stripped_birch_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(10); } + case "minecraft:stripped_jungle_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(11); } + case "minecraft:stripped_acacia_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(12); } + case "minecraft:stripped_dark_oak_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(13); } + } + } + + if (NEW_LEAVES.contains(identifer) || NEW_LEAVES2.contains(identifer)) { + switch (identifer) { + case "minecraft:oak_leaves" -> { return mapping.withBedrockIdentifier("minecraft:leaves").withBedrockData(0); } + case "minecraft:spruce_leaves" -> { return mapping.withBedrockIdentifier("minecraft:leaves").withBedrockData(1); } + case "minecraft:birch_leaves" -> { return mapping.withBedrockIdentifier("minecraft:leaves").withBedrockData(2); } + case "minecraft:jungle_leaves" -> { return mapping.withBedrockIdentifier("minecraft:leaves").withBedrockData(3); } + case "minecraft:acacia_leaves" -> { return mapping.withBedrockIdentifier("minecraft:leaves2").withBedrockData(0); } + case "minecraft:dark_oak_leaves" -> { return mapping.withBedrockIdentifier("minecraft:leaves2").withBedrockData(1); } + } + } + + return mapping; + } + + static NbtMap remapBlock(NbtMap tag) { + final String name = tag.getString("name"); + + if (!NEW_BLOCKS.contains(name)) { + return tag; + } + + String replacement; + + if (name.equals("minecraft:grass_block")) { + replacement = "minecraft:grass"; + + NbtMapBuilder builder = tag.toBuilder(); + builder.putString("name", replacement); + + return builder.build(); + } + + if (NEW_WOODS.contains(name)) { + replacement = "minecraft:wood"; + + NbtMap states = tag.getCompound("states"); + boolean stripped = name.startsWith("minecraft:stripped_"); + String woodType = name.replaceAll("minecraft:|_wood|stripped_", ""); + + NbtMapBuilder statesBuilder = states.toBuilder() + .putString("wood_type", woodType) + .putBoolean("stripped_bit", stripped); + + NbtMapBuilder builder = tag.toBuilder() + .putString("name", replacement) + .putCompound("states", statesBuilder.build()); + + return builder.build(); + } + + if (NEW_LEAVES.contains(name) || NEW_LEAVES2.contains(name)) { + boolean leaves2 = NEW_LEAVES2.contains(name); + replacement = leaves2 ? "minecraft:leaves2" : "minecraft:leaves"; + + NbtMap states = tag.getCompound("states"); + String leafType = name.replaceAll("minecraft:|_leaves", ""); + + NbtMapBuilder statesBuilder = states.toBuilder() + .putString(leaves2 ? "new_leaf_type" : "old_leaf_type", leafType); + + NbtMapBuilder builder = tag.toBuilder() + .putString("name", replacement) + .putCompound("states", statesBuilder.build()); + + return builder.build(); + } + + + if (NEW_SLABS.contains(name)) { + replacement = name.contains("double") ? "minecraft:double_wooden_slab" : "minecraft:wooden_slab"; + + NbtMap states = tag.getCompound("states"); + String woodType = name.replaceAll("minecraft:|_double|_slab", ""); + + NbtMapBuilder statesBuilder = states.toBuilder() + .putString("wood_type", woodType); + + NbtMapBuilder builder = tag.toBuilder() + .putString("name", replacement) + .putCompound("states", statesBuilder.build()); + + return builder.build(); + } + + return tag; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java index c1593447d..708f92dc5 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java @@ -41,6 +41,7 @@ import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.codec.v622.Bedrock_v622; import org.cloudburstmc.protocol.bedrock.codec.v630.Bedrock_v630; import org.cloudburstmc.protocol.bedrock.codec.v649.Bedrock_v649; +import org.cloudburstmc.protocol.bedrock.codec.v662.Bedrock_v662; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; @@ -90,8 +91,9 @@ public class ItemRegistryPopulator { public static void populate() { List paletteVersions = new ArrayList<>(3); paletteVersions.add(new PaletteVersion("1_20_40", Bedrock_v622.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion630_622::remapItem)); - paletteVersions.add(new PaletteVersion("1_20_50", Bedrock_v630.CODEC.getProtocolVersion())); - paletteVersions.add(new PaletteVersion("1_20_60", Bedrock_v649.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion630_649::remapItem)); + paletteVersions.add(new PaletteVersion("1_20_50", Bedrock_v630.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion649_630::remapItem)); + paletteVersions.add(new PaletteVersion("1_20_60", Bedrock_v649.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion662_649::remapItem)); + paletteVersions.add(new PaletteVersion("1_20_70", Bedrock_v662.CODEC.getProtocolVersion())); GeyserBootstrap bootstrap = GeyserImpl.getInstance().getBootstrap(); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockItemFrameDropItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockItemFrameDropItemTranslator.java index 8632dc4e1..4a5145ead 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockItemFrameDropItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockItemFrameDropItemTranslator.java @@ -39,10 +39,12 @@ import org.geysermc.geyser.translator.protocol.Translator; * Pre-1.16.210: used for both survival and creative item frame item removal *

* 1.16.210: only used in creative. + * 1.20.70: no longer used. */ @Translator(packet = ItemFrameDropItemPacket.class) public class BedrockItemFrameDropItemTranslator extends PacketTranslator { + // TODO: Remove when 1.20.60 is no longer supported @Override public void translate(GeyserSession session, ItemFrameDropItemPacket packet) { Entity entity = ItemFrameEntity.getItemFrameEntity(session, packet.getBlockPosition()); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockLecternUpdateTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockLecternUpdateTranslator.java index 2678128ed..6bac96206 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockLecternUpdateTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockLecternUpdateTranslator.java @@ -47,6 +47,7 @@ public class BedrockLecternUpdateTranslator extends PacketTranslatoriEQ9%3yWrUVui<|w@CMohycJki)-uZjK zw{P_>bovCbc>(---Q$)1>SOm1AXZUks9McXonN=RAa~G|_5Sy33K2F54H@?kQaOoA z5zM!sdyB~+A6dzV_0^onHAMWid_#m2&0>g)1^odo*ew6l1vr0AV>K^=i_X6fu2@i~ zG+_g>C@y{A9&{H#WsEI?6Dnev5)kwxF$Lz5giDuI&GY`1Ty=efi@+fvqXjOJ#G-gI z74T9E;l=hlTZuC8_7QgYw9}h;+oOrFp^vD9jyB?P>4)pYVg%!bj9JhkWH|Jx0gSMl zKt?5uPFEwB6>j#|g@q_g?VwcekjdIoE%?-+pxD<|uuJw#J;hmC~f=e$OzZcIqJG)x*bC zloK{DQ$37rjxSfG*=)SQXd%>SP=VnW)j@3Y`Z-lT9%72~zx?V+2!1=KuF|OGRO`58 z2lTMKN}UHAd(}H2G^8%`Bqq(^fycOT#J@ra^J0Xq3D*ZiAqXdj)PwQ#6Ehvo)B!zF z@)4ZHtr%%RQs-6Dky_Jmz8*Le&^(4MSwZ7Xwb3=2i(v9a&C;lOj7Pd2&<2n+Bcx@KwBwrAgQTWanI#A&4`fcu z(+W{O923F~wT9YoeMpQ5LEc}(MR`#Z5Q1Wa4}*JyJ~2J!W@hC``DW;DqvuO!S7n_< zIJ&Pbs{p6ewMkcsWrvWi3`t8mbQOxG0&c1G99GTI=;tD7*Gu|22=;5}d*M$FJvJTL z%ln9lFoUAI(xY}O4q$vcJprb&UfcgXdaIq@4)5Kd%i-Nluazb7Ak$E(IG;U0zc%8$ z0EXuz;0Q|x3>4fmXv&9cQN!i9oi~XskhR6y^d&HoE5gDmKB&VVe~9Ov62W#Yrv*xH z8s@<_`|P7UP+%9cheo^Z@6RqYjJOt6H9|uzoIj^x)$wiRVdjnOW6(h{GvOM=jDv3} z#%Z82C-K2rJ{;hK&|^UpVV;)RG0M4A-_Ec}lqg02fk#q(ld<6mCd-s|Mss|lh49Hg zId`o6Nv^JruT9o|TuC5KzIzE6e8aAg;WIem2Tg1O#&LZwfu%=ovK|~#!hF20)i^Cp za21)xr3sF7m>x)EDer?*>iO5yqWn+ns=Qs#V&_js&1TfqYMGUj1pf%wpR_uhaO*1R zhegOz36nZ3WyYi#Efc;n06z@Uh569kVc7>Ck=Bw?Fks05&(#XCG`uBQaI40uuwar# ziljs9t#%|G*l3-iWL*L4vu!?{@T*4KFtN!!Dw4)_*`_8|t{H3ulJ;81;Pd5!-fmxs z)U$oeQ6#;%b4)Rk8a(#<6Mcz42Kn)Kl01aTiB``#XrF?l-Q#o15>`99b6as-YELdE zF)zr%a%Jx7_~a24f(3!5F&@M~s^10@Gwmg{kzRW$Hmj&lM$)$hq+ z$xwrQKE$*(m24@T2%qOT--Iu~Dcr`|2FTrHb;If^H3Rg83>M~@Y(;Qpn{#ni%C(9M z%+S=KbAr29O~DzXO#^2fu1m@W%Jk%fhq_#hlF$B`TV2US6PJ2nmU|(tW0TG;w`Tep z_i{BE7K9a$z1HM~Kp)|T%WK?QBO@h`RvH5l~`KZ?~!Lw8_gTW z=*anl)qQ!lZIVt53bAIt*dT;>F+nNtQ(xX`II7QIV9&yvUMJt>$ep&n5)RP$bEN5O z^K%hwQx)8k4pBF3@Aohm>2>OY`SADJf*J63G;hrR4(0q+vITx#S1@~|T%}JsIJMsD zl6+L*mnvN7VY<+a;Io$t7irXDj0=QP?``>(!Vgm%$mg>ezoJ>M%t#HL-Uk%A)+Fc} zt~gw!@dGW7`W5dBu!QwJdK)10@MEVp51wbe3_LMFGw@YAT?`dQ--FWLTpy8`th^W7 fa4c?*k3lf?sBeKoFW>l(%v6ahe+T}Yhwl0hK|=ny literal 2605093 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%0Dr|j|qX{c2 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

bkIWg`I^~cgV&?1^)kY?)Q07(A8SpTQ2lKpk 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νeHj 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ⅇf_;0AHH<-@xezNx8u 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 D9);gD literal 0 HcmV?d00001 diff --git a/core/src/main/resources/bedrock/creative_items.1_20_70.json b/core/src/main/resources/bedrock/creative_items.1_20_70.json new file mode 100644 index 000000000..ed498b782 --- /dev/null +++ b/core/src/main/resources/bedrock/creative_items.1_20_70.json @@ -0,0 +1,5803 @@ +{ + "items": [ + { + "id": "minecraft:oak_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQFAAAACAQAbmFtZRQAbWluZWNyYWZ0Om9ha19wbGFua3MECQBuYW1lX2hhc2ilMDLR92rQ4wMKAG5ldHdvcmtfaWS2GotyCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:spruce_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTiAwAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9wbGFua3MECQBuYW1lX2hhc2iumBkmFGFE8gMKAG5ldHdvcmtfaWSo8TFgCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:birch_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTjAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX3BsYW5rcwQJAG5hbWVfaGFzaLrrAKJqV2WFAwoAbmV0d29ya19pZL+e3ZAKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:jungle_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTkAwAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9wbGFua3MECQBuYW1lX2hhc2iBM3k4T3FAugMKAG5ldHdvcmtfaWSXUmBCCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:acacia_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTlAwAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9wbGFua3MECQBuYW1lX2hhc2g60edJxO5/aAMKAG5ldHdvcmtfaWTUXozECgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:dark_oak_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTmAwAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX3BsYW5rcwQJAG5hbWVfaGFzaAr64wkQ9cA7AwoAbmV0d29ya19pZFbMeR0KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:mangrove_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTlAgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX3BsYW5rcwQJAG5hbWVfaGFzaPvLtcEA0F8xAwoAbmV0d29ya19pZEvnlCYKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:cherry_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAwAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9wbGFua3MECQBuYW1lX2hhc2hNIvVh/lVW7gMKAG5ldHdvcmtfaWQTXpRoCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:bamboo_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT9AgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19wbGFua3MECQBuYW1lX2hhc2gYnjNz7SCCjgMKAG5ldHdvcmtfaWTi8ySSCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:bamboo_mosaic", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT8AgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19tb3NhaWMECQBuYW1lX2hhc2izSEgiMKOp/AMKAG5ldHdvcmtfaWQZ/p8xCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:crimson_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTxAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fcGxhbmtzBAkAbmFtZV9oYXNoJc5IKqNXJnwDCgBuZXR3b3JrX2lkwtJDdQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:warped_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTyAQAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9wbGFua3MECQBuYW1lX2hhc2g3yGXEWhe6LgMKAG5ldHdvcmtfaWStTABvCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWSE4JosCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCwBjb2JibGVzdG9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWTUvV6XCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlEQBtb3NzeV9jb2JibGVzdG9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWT4opb2CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlBwBncmFuaXRlCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQAMQTVCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlBwBkaW9yaXRlCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQIbDOcCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCABhbmRlc2l0ZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWSZKhusCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCQBzYW5kc3RvbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWSp4zgCCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlDQByZWRfc2FuZHN0b25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRbqVHTCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCwBzdG9uZV9icmljawgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRr0ZT/CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlEQBtb3NzeV9zdG9uZV9icmljawgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRnLis3CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlBQBicmljawgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQNLzfSCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlDABuZXRoZXJfYnJpY2sIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQ5h0xwCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlEAByZWRfbmV0aGVyX2JyaWNrCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWS9J0B2CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCQBlbmRfYnJpY2sIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRPbkJeCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCgBwcmlzbWFyaW5lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:blackstone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQUAgAACAQAbmFtZRkAbWluZWNyYWZ0OmJsYWNrc3RvbmVfd2FsbAQJAG5hbWVfaGFzaMP8XppUSU1RAwoAbmV0d29ya19pZMbeBBsKBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:polished_blackstone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQoAgAACAQAbmFtZSIAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfd2FsbAQJAG5hbWVfaGFzaP6SwV08YwzAAwoAbmV0d29ya19pZAJLsz8KBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:polished_blackstone_brick_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQVAgAACAQAbmFtZSgAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tfd2FsbAQJAG5hbWVfaGFzaBBIDZbHxiEzAwoAbmV0d29ya19pZEbLV8cKBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:cobbled_deepslate_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR9AgAACAQAbmFtZSAAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlX3dhbGwECQBuYW1lX2hhc2iECY5oKxeT+gMKAG5ldHdvcmtfaWRCnPrFCgYAc3RhdGVzCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:deepslate_tile_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAgAACAQAbmFtZR0AbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlX3dhbGwECQBuYW1lX2hhc2jz7N+PeuEXgQMKAG5ldHdvcmtfaWTqw4s4CgYAc3RhdGVzCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:polished_deepslate_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSBAgAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZV93YWxsBAkAbmFtZV9oYXNoHxjTdj9pevMDCgBuZXR3b3JrX2lkIvBYYwoGAHN0YXRlcwgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:deepslate_brick_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSJAgAACAQAbmFtZR4AbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja193YWxsBAkAbmFtZV9oYXNoEs3EQrjroyEDCgBuZXR3b3JrX2lkwlrCGwoGAHN0YXRlcwgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:mud_brick_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTgAgAACAQAbmFtZRgAbWluZWNyYWZ0Om11ZF9icmlja193YWxsBAkAbmFtZV9oYXNov9b98ATpUSwDCgBuZXR3b3JrX2lkH/1WZQoGAHN0YXRlcwgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:oak_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRVAAAACAQAbmFtZRMAbWluZWNyYWZ0Om9ha19mZW5jZQQJAG5hbWVfaGFzaGEmid7AaCWRAwoAbmV0d29ya19pZDvPEXcKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:spruce_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRCAwAACAQAbmFtZRYAbWluZWNyYWZ0OnNwcnVjZV9mZW5jZQQJAG5hbWVfaGFzaPQCm+aX1ZQeAwoAbmV0d29ya19pZD1QUEoKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:birch_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ/AwAACAQAbmFtZRUAbWluZWNyYWZ0OmJpcmNoX2ZlbmNlBAkAbmFtZV9oYXNo6CJ2ATpANfgDCgBuZXR3b3JrX2lkmCUV2QoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:jungle_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRBAwAACAQAbmFtZRYAbWluZWNyYWZ0Omp1bmdsZV9mZW5jZQQJAG5hbWVfaGFzaOX4cD9uAmsdAwoAbmV0d29ya19pZHz1VxkKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:acacia_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ+AwAACAQAbmFtZRYAbWluZWNyYWZ0OmFjYWNpYV9mZW5jZQQJAG5hbWVfaGFzaGjn+RlKVDH6AwoAbmV0d29ya19pZNVGubwKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:dark_oak_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRAAwAACAQAbmFtZRgAbWluZWNyYWZ0OmRhcmtfb2FrX2ZlbmNlBAkAbmFtZV9oYXNoGPj0gCgM0c0DCgBuZXR3b3JrX2lk2w+gEwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:mangrove_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTqAgAACAQAbmFtZRgAbWluZWNyYWZ0Om1hbmdyb3ZlX2ZlbmNlBAkAbmFtZV9oYXNowwAd7tPu9bsDCgBuZXR3b3JrX2lkKEcd0goGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:cherry_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQTAwAACAQAbmFtZRYAbWluZWNyYWZ0OmNoZXJyeV9mZW5jZQQJAG5hbWVfaGFzaFmtUfHfTxcxAwoAbmV0d29ya19pZPCBxAIKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:bamboo_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQCAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJhbWJvb19mZW5jZQQJAG5hbWVfaGFzaCKRbxfXsfkiAwoAbmV0d29ya19pZJNXKFcKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:nether_brick_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRxAAAACAQAbmFtZRwAbWluZWNyYWZ0Om5ldGhlcl9icmlja19mZW5jZQQJAG5hbWVfaGFzaA6030ngawxcAwoAbmV0d29ya19pZLnjLF4KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:crimson_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT/AQAACAQAbmFtZRcAbWluZWNyYWZ0OmNyaW1zb25fZmVuY2UECQBuYW1lX2hhc2jhUhKv1HGj9AMKAG5ldHdvcmtfaWR3OH3OCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:warped_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQAAgAACAQAbmFtZRYAbWluZWNyYWZ0OndhcnBlZF9mZW5jZQQJAG5hbWVfaGFzaJfb3/YuKmOWAwoAbmV0d29ya19pZCpaGC8KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRrAAAACAQAbmFtZRQAbWluZWNyYWZ0OmZlbmNlX2dhdGUECQBuYW1lX2hhc2hTxpjEDmRzAwMKAG5ldHdvcmtfaWR+T9kTCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:spruce_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS3AAAACAQAbmFtZRsAbWluZWNyYWZ0OnNwcnVjZV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoanTVB84HRbkDCgBuZXR3b3JrX2lkEnw5egoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:birch_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS4AAAACAQAbmFtZRoAbWluZWNyYWZ0OmJpcmNoX2ZlbmNlX2dhdGUECQBuYW1lX2hhc2jmfPklI8azSwMKAG5ldHdvcmtfaWQL77/BCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:jungle_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS5AAAACAQAbmFtZRsAbWluZWNyYWZ0Omp1bmdsZV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNobYVQkfBomIcDCgBuZXR3b3JrX2lkA1zgtgoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:acacia_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS7AAAACAQAbmFtZRsAbWluZWNyYWZ0OmFjYWNpYV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoZnrLUx/XSekDCgBuZXR3b3JrX2lkHg/kTgoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:dark_oak_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS6AAAACAQAbmFtZR0AbWluZWNyYWZ0OmRhcmtfb2FrX2ZlbmNlX2dhdGUECQBuYW1lX2hhc2j2PTvdJJHcVQMKAG5ldHdvcmtfaWTwjOCeCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:mangrove_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTrAgAACAQAbmFtZR0AbWluZWNyYWZ0Om1hbmdyb3ZlX2ZlbmNlX2dhdGUECQBuYW1lX2hhc2i/kOhBKiI/dAMKAG5ldHdvcmtfaWSfweCSCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:cherry_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQUAwAACAQAbmFtZRsAbWluZWNyYWZ0OmNoZXJyeV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoKWLgCk0z+PsDCgBuZXR3b3JrX2lk/9bTZQoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:bamboo_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAwAACAQAbmFtZRsAbWluZWNyYWZ0OmJhbWJvb19mZW5jZV9nYXRlBAkAbmFtZV9oYXNopH1JrUgwdIADCgBuZXR3b3JrX2lkzIpPywoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:crimson_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQBAgAACAQAbmFtZRwAbWluZWNyYWZ0OmNyaW1zb25fZmVuY2VfZ2F0ZQQJAG5hbWVfaGFzaHE3Gfd0Z2d2AwoAbmV0d29ya19pZDQzVbEKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQsAaW5fd2FsbF9iaXQAAQgAb3Blbl9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:warped_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQCAgAACAQAbmFtZRsAbWluZWNyYWZ0OndhcnBlZF9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoy0oIBjDIG4kDCgBuZXR3b3JrX2lkkf+/3QoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:normal_stone_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAQAACAQAbmFtZR0AbWluZWNyYWZ0Om5vcm1hbF9zdG9uZV9zdGFpcnMECQBuYW1lX2hhc2hAEktZZOkGIwMKAG5ldHdvcmtfaWQeH1ALCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:stone_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRDAAAACAQAbmFtZRYAbWluZWNyYWZ0OnN0b25lX3N0YWlycwQJAG5hbWVfaGFzaNRjqVC5GRVDAwoAbmV0d29ya19pZDcCv+MKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:mossy_cobblestone_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSyAQAACAQAbmFtZSIAbWluZWNyYWZ0Om1vc3N5X2NvYmJsZXN0b25lX3N0YWlycwQJAG5hbWVfaGFzaMVSTq5z9n1RAwoAbmV0d29ya19pZFIfrhkKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:oak_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ1AAAACAQAbmFtZRQAbWluZWNyYWZ0Om9ha19zdGFpcnMECQBuYW1lX2hhc2jk/HFzdXy0FQMKAG5ldHdvcmtfaWQJjyzBCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:spruce_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSGAAAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9zdGFpcnMECQBuYW1lX2hhc2iznygw7uBPBQMKAG5ldHdvcmtfaWTv+is3CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:birch_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSHAAAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX3N0YWlycwQJAG5hbWVfaGFzaPfhbL619a3GAwoAbmV0d29ya19pZFyPlHAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:jungle_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSIAAAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9zdGFpcnMECQBuYW1lX2hhc2jodJsHUbOVxQMKAG5ldHdvcmtfaWR0z5d4CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:acacia_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSjAAAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9zdGFpcnMECQBuYW1lX2hhc2h3x1NmD43IqQMKAG5ldHdvcmtfaWS7Jwz6CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:dark_oak_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSkAAAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX3N0YWlycwQJAG5hbWVfaGFzaMfwkbYPbNmAAwoAbmV0d29ya19pZCmBYKAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:mangrove_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTnAgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX3N0YWlycwQJAG5hbWVfaGFzaNpUDY+uGMpyAwoAbmV0d29ya19pZChzUAsKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:cherry_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQcAwAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9zdGFpcnMECQBuYW1lX2hhc2jMtr0v9JY4zwMKAG5ldHdvcmtfaWRQwq31CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:bamboo_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT/AgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19zdGFpcnMECQBuYW1lX2hhc2jFOzWL8PalKwMKAG5ldHdvcmtfaWTVPh42CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:bamboo_mosaic_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQKAwAACAQAbmFtZR4AbWluZWNyYWZ0OmJhbWJvb19tb3NhaWNfc3RhaXJzBAkAbmFtZV9oYXNoNLPiveSHPaoDCgBuZXR3b3JrX2lk44PHjgoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:stone_brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRtAAAACAQAbmFtZRwAbWluZWNyYWZ0OnN0b25lX2JyaWNrX3N0YWlycwQJAG5hbWVfaGFzaN6tQViRo5cwAwoAbmV0d29ya19pZDMyMgIKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:mossy_stone_brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSuAQAACAQAbmFtZSIAbWluZWNyYWZ0Om1vc3N5X3N0b25lX2JyaWNrX3N0YWlycwQJAG5hbWVfaGFzaIB/Zv5YBPuYAwoAbmV0d29ya19pZANTOsMKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:sandstone_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSAAAAACAQAbmFtZRoAbWluZWNyYWZ0OnNhbmRzdG9uZV9zdGFpcnMECQBuYW1lX2hhc2hOyA0BoYUOPQMKAG5ldHdvcmtfaWSV/834CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:smooth_sandstone_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSwAQAACAQAbmFtZSEAbWluZWNyYWZ0OnNtb290aF9zYW5kc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNoB+CuCd8Ruz8DCgBuZXR3b3JrX2lksR+m8QoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:red_sandstone_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS0AAAACAQAbmFtZR4AbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNoPs0LpHPL24YDCgBuZXR3b3JrX2lkLYVt3woGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:smooth_red_sandstone_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAQAACAQAbmFtZSUAbWluZWNyYWZ0OnNtb290aF9yZWRfc2FuZHN0b25lX3N0YWlycwQJAG5hbWVfaGFzaBvjtQv5pf+MAwoAbmV0d29ya19pZMHNND8KBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:granite_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAQAACAQAbmFtZRgAbWluZWNyYWZ0OmdyYW5pdGVfc3RhaXJzBAkAbmFtZV9oYXNoGzpvtoqKQjgDCgBuZXR3b3JrX2lkPkcB1goGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:polished_granite_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSrAQAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2dyYW5pdGVfc3RhaXJzBAkAbmFtZV9oYXNo3PvbSfEQklIDCgBuZXR3b3JrX2lkMmEm3AoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:diorite_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSpAQAACAQAbmFtZRgAbWluZWNyYWZ0OmRpb3JpdGVfc3RhaXJzBAkAbmFtZV9oYXNoi73T8VQuZmcDCgBuZXR3b3JrX2lk6i6nBQoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:polished_diorite_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSsAQAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2Rpb3JpdGVfc3RhaXJzBAkAbmFtZV9oYXNoFKRJd5Wk5L0DCgBuZXR3b3JrX2lkbt2ioAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:andesite_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSqAQAACAQAbmFtZRkAbWluZWNyYWZ0OmFuZGVzaXRlX3N0YWlycwQJAG5hbWVfaGFzaO5w2FKBw76EAwoAbmV0d29ya19pZKhXEgUKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:polished_andesite_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWStAQAACAQAbmFtZSIAbWluZWNyYWZ0OnBvbGlzaGVkX2FuZGVzaXRlX3N0YWlycwQJAG5hbWVfaGFzaNcZZ/zmLInIAwoAbmV0d29ya19pZJTHrlEKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRsAAAACAQAbmFtZRYAbWluZWNyYWZ0OmJyaWNrX3N0YWlycwQJAG5hbWVfaGFzaMyt+cRDk5O2AwoAbmV0d29ya19pZNeMh58KBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:nether_brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRyAAAACAQAbmFtZR0AbWluZWNyYWZ0Om5ldGhlcl9icmlja19zdGFpcnMECQBuYW1lX2hhc2jRqIoOXgifBAMKAG5ldHdvcmtfaWQDiw5yCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:red_nether_brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS3AQAACAQAbmFtZSEAbWluZWNyYWZ0OnJlZF9uZXRoZXJfYnJpY2tfc3RhaXJzBAkAbmFtZV9oYXNogQvosSbcj7kDCgBuZXR3b3JrX2lkx2IMtAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:end_brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSxAQAACAQAbmFtZRoAbWluZWNyYWZ0OmVuZF9icmlja19zdGFpcnMECQBuYW1lX2hhc2hmlAk+QhsUsQMKAG5ldHdvcmtfaWTN7KFaCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:quartz_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWScAAAACAQAbmFtZRcAbWluZWNyYWZ0OnF1YXJ0el9zdGFpcnMECQBuYW1lX2hhc2hmvpvOqGi6egMKAG5ldHdvcmtfaWRmUTh7CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:smooth_quartz_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS4AQAACAQAbmFtZR4AbWluZWNyYWZ0OnNtb290aF9xdWFydHpfc3RhaXJzBAkAbmFtZV9oYXNoNZZ9rX0qZOsDCgBuZXR3b3JrX2lkzsgQyQoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:purpur_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTLAAAACAQAbmFtZRcAbWluZWNyYWZ0OnB1cnB1cl9zdGFpcnMECQBuYW1lX2hhc2ifwDxeezXD7gMKAG5ldHdvcmtfaWTT+rxiCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:prismarine_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQBAQAACAQAbmFtZRsAbWluZWNyYWZ0OnByaXNtYXJpbmVfc3RhaXJzBAkAbmFtZV9oYXNooTHSZ+IrYtcDCgBuZXR3b3JrX2lkxTJfeAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:dark_prismarine_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQCAQAACAQAbmFtZSAAbWluZWNyYWZ0OmRhcmtfcHJpc21hcmluZV9zdGFpcnMECQBuYW1lX2hhc2hIciLmam4o4AMKAG5ldHdvcmtfaWTVu7TCCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:prismarine_bricks_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAQAACAQAbmFtZSIAbWluZWNyYWZ0OnByaXNtYXJpbmVfYnJpY2tzX3N0YWlycwQJAG5hbWVfaGFzaNIjq1oBlZMMAwoAbmV0d29ya19pZGEFwLYKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:crimson_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT9AQAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fc3RhaXJzBAkAbmFtZV9oYXNoZJqIzCBpCq4DCgBuZXR3b3JrX2lktXE00AoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:warped_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT+AQAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9zdGFpcnMECQBuYW1lX2hhc2hOkY27jLD4RQMKAG5ldHdvcmtfaWQ+E5VrCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:blackstone_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQTAgAACAQAbmFtZRsAbWluZWNyYWZ0OmJsYWNrc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNokdoUb76p9McDCgBuZXR3b3JrX2lk5fWI5goGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:polished_blackstone_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQjAgAACAQAbmFtZSQAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNolCFtFIE8MmADCgBuZXR3b3JrX2lkGTf7sgoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:polished_blackstone_brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQSAgAACAQAbmFtZSoAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tfc3RhaXJzBAkAbmFtZV9oYXNonks6UlfpOmkDCgBuZXR3b3JrX2lkgYeOdAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:cut_copper_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAgAACAQAbmFtZRsAbWluZWNyYWZ0OmN1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNoHfoAXYq5G3MDCgBuZXR3b3JrX2lkeetf7woGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:exposed_cut_copper_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAgAACAQAbmFtZSMAbWluZWNyYWZ0OmV4cG9zZWRfY3V0X2NvcHBlcl9zdGFpcnMECQBuYW1lX2hhc2howneQGtZ9cgMKAG5ldHdvcmtfaWSg73zdCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:weathered_cut_copper_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAgAACAQAbmFtZSUAbWluZWNyYWZ0OndlYXRoZXJlZF9jdXRfY29wcGVyX3N0YWlycwQJAG5hbWVfaGFzaP+R5loXxrVgAwoAbmV0d29ya19pZOnbRf4KBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:oxidized_cut_copper_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRkAgAACAQAbmFtZSQAbWluZWNyYWZ0Om94aWRpemVkX2N1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNo6Jeoq5rsPxsDCgBuZXR3b3JrX2lkmRjDnQoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:waxed_cut_copper_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRlAgAACAQAbmFtZSEAbWluZWNyYWZ0OndheGVkX2N1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNoh07CQj0/SR8DCgBuZXR3b3JrX2lkmYqoqAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:waxed_exposed_cut_copper_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRmAgAACAQAbmFtZSkAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY3V0X2NvcHBlcl9zdGFpcnMECQBuYW1lX2hhc2guVct1ilmxTwMKAG5ldHdvcmtfaWQgCPROCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:waxed_weathered_cut_copper_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRnAgAACAQAbmFtZSsAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jdXRfY29wcGVyX3N0YWlycwQJAG5hbWVfaGFzaPXC8Sz/phCpAwoAbmV0d29ya19pZHlwHVsKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:waxed_oxidized_cut_copper_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS/AgAACAQAbmFtZSoAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2N1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNoaqGdkuhxVZUDCgBuZXR3b3JrX2lkYQXzzgoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:cobbled_deepslate_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR8AgAACAQAbmFtZSIAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlX3N0YWlycwQJAG5hbWVfaGFzaPIfa+TpyJcIAwoAbmV0d29ya19pZJUvOYIKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:deepslate_tile_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAgAACAQAbmFtZR8AbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlX3N0YWlycwQJAG5hbWVfaGFzaGFRFzB72mN2AwoAbmV0d29ya19pZJEOgIsKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:polished_deepslate_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSAAgAACAQAbmFtZSMAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZV9zdGFpcnMECQBuYW1lX2hhc2iNCYxVik9sGAMKAG5ldHdvcmtfaWSRVPnYCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:deepslate_brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSIAgAACAQAbmFtZSAAbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja19zdGFpcnMECQBuYW1lX2hhc2hIasOahEf83wMKAG5ldHdvcmtfaWQ1qEDCCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:mud_brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTfAgAACAQAbmFtZRoAbWluZWNyYWZ0Om11ZF9icmlja19zdGFpcnMECQBuYW1lX2hhc2gt3qxK1NWajAMKAG5ldHdvcmtfaWSm9N3MCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:wooden_door" + }, + { + "id": "minecraft:spruce_door" + }, + { + "id": "minecraft:birch_door" + }, + { + "id": "minecraft:jungle_door" + }, + { + "id": "minecraft:acacia_door" + }, + { + "id": "minecraft:dark_oak_door" + }, + { + "id": "minecraft:mangrove_door" + }, + { + "id": "minecraft:cherry_door" + }, + { + "id": "minecraft:bamboo_door" + }, + { + "id": "minecraft:iron_door" + }, + { + "id": "minecraft:crimson_door" + }, + { + "id": "minecraft:warped_door" + }, + { + "id": "minecraft:trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRgAAAACAQAbmFtZRIAbWluZWNyYWZ0OnRyYXBkb29yBAkAbmFtZV9oYXNotYiAJGtN0xADCgBuZXR3b3JrX2lkyTAWkAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:spruce_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSUAQAACAQAbmFtZRkAbWluZWNyYWZ0OnNwcnVjZV90cmFwZG9vcgQJAG5hbWVfaGFzaOwlfbgBkUW4AwoAbmV0d29ya19pZPHy1K0KBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:birch_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAQAACAQAbmFtZRgAbWluZWNyYWZ0OmJpcmNoX3RyYXBkb29yBAkAbmFtZV9oYXNoSLtLweOLJ7wDCgBuZXR3b3JrX2lkeJWDfgoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:jungle_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSTAQAACAQAbmFtZRkAbWluZWNyYWZ0Omp1bmdsZV90cmFwZG9vcgQJAG5hbWVfaGFzaDP/TnM9wyCIAwoAbmV0d29ya19pZEy2fJoKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:acacia_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSQAQAACAQAbmFtZRkAbWluZWNyYWZ0OmFjYWNpYV90cmFwZG9vcgQJAG5hbWVfaGFzaMj8xi3vmEKOAwoAbmV0d29ya19pZOHj8E8KBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:dark_oak_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSSAQAACAQAbmFtZRsAbWluZWNyYWZ0OmRhcmtfb2FrX3RyYXBkb29yBAkAbmFtZV9oYXNomB2GGJQ2aOMDCgBuZXR3b3JrX2lko5ZHTwoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:mangrove_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTvAgAACAQAbmFtZRsAbWluZWNyYWZ0Om1hbmdyb3ZlX3RyYXBkb29yBAkAbmFtZV9oYXNooV3kQsQUUmkDCgBuZXR3b3JrX2lkkF/mxAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:cherry_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQeAwAACAQAbmFtZRkAbWluZWNyYWZ0OmNoZXJyeV90cmFwZG9vcgQJAG5hbWVfaGFzaH/PefpfdHgtAwoAbmV0d29ya19pZOA7eNgKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:bamboo_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQHAwAACAQAbmFtZRkAbWluZWNyYWZ0OmJhbWJvb190cmFwZG9vcgQJAG5hbWVfaGFzaJrEOpsTwtKCAwoAbmV0d29ya19pZLvbPz8KBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:iron_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSnAAAACAQAbmFtZRcAbWluZWNyYWZ0Omlyb25fdHJhcGRvb3IECQBuYW1lX2hhc2gwA+IumsEiGQMKAG5ldHdvcmtfaWTvSVl/CgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAEPAHVwc2lkZV9kb3duX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:crimson_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT1AQAACAQAbmFtZRoAbWluZWNyYWZ0OmNyaW1zb25fdHJhcGRvb3IECQBuYW1lX2hhc2jHXufTnwUkYgMKAG5ldHdvcmtfaWQLjMYVCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAEPAHVwc2lkZV9kb3duX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:warped_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT2AQAACAQAbmFtZRkAbWluZWNyYWZ0OndhcnBlZF90cmFwZG9vcgQJAG5hbWVfaGFzaA20wG/+vkd6AwoAbmV0d29ya19pZHKR/hYKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:iron_bars", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRlAAAACAQAbmFtZRMAbWluZWNyYWZ0Omlyb25fYmFycwQJAG5hbWVfaGFzaPuefWSNAe56AwoAbmV0d29ya19pZN2LB5IKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQUAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmdsYXNzBAkAbmFtZV9oYXNowGJByfWff6gDCgBuZXR3b3JrX2lk0hdLNwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:white_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTxAAAACAQAbmFtZR0AbWluZWNyYWZ0OndoaXRlX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2iHubqoMbu9fAMKAG5ldHdvcmtfaWRndBrUCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:light_gray_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSnAwAACAQAbmFtZSIAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaKKa+LrRsHQhAwoAbmV0d29ya19pZEv2giYKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:gray_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSmAwAACAQAbmFtZRwAbWluZWNyYWZ0OmdyYXlfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaIETy7Y/HZREAwoAbmV0d29ya19pZDomVrUKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:black_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSuAwAACAQAbmFtZR0AbWluZWNyYWZ0OmJsYWNrX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2iV6BCwpfDMmwMKAG5ldHdvcmtfaWSV7doJCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:brown_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSrAwAACAQAbmFtZR0AbWluZWNyYWZ0OmJyb3duX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2igsEiq5np8JgMKAG5ldHdvcmtfaWRMzE/lCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:red_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWStAwAACAQAbmFtZRsAbWluZWNyYWZ0OnJlZF9zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNoCa2J12/lQoIDCgBuZXR3b3JrX2lk283lWAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:orange_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSgAwAACAQAbmFtZR4AbWluZWNyYWZ0Om9yYW5nZV9zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNozgjAuvzhxGsDCgBuZXR3b3JrX2lkW5CkhQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:yellow_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSjAwAACAQAbmFtZR4AbWluZWNyYWZ0OnllbGxvd19zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNo7EbHMd5WVugDCgBuZXR3b3JrX2lkkdDyXQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:lime_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSkAwAACAQAbmFtZRwAbWluZWNyYWZ0OmxpbWVfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaBtZA1nZtwcFAwoAbmV0d29ya19pZDxX85UKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:green_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSsAwAACAQAbmFtZR0AbWluZWNyYWZ0OmdyZWVuX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2h91ptDgbehWwMKAG5ldHdvcmtfaWTlDhnECgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:cyan_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAwAACAQAbmFtZRwAbWluZWNyYWZ0OmN5YW5fc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaBkIYQ8nQLqbAwoAbmV0d29ya19pZOL1lHsKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:light_blue_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSiAwAACAQAbmFtZSIAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaLt05n1G0fiSAwoAbmV0d29ya19pZNbwulIKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:blue_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSqAwAACAQAbmFtZRwAbWluZWNyYWZ0OmJsdWVfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaPhLocSfzduRAwoAbmV0d29ya19pZENsjFwKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:purple_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSpAwAACAQAbmFtZR4AbWluZWNyYWZ0OnB1cnBsZV9zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNoJk0DhRO0szUDCgBuZXR3b3JrX2lkD98ZxgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:magenta_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAwAACAQAbmFtZR8AbWluZWNyYWZ0Om1hZ2VudGFfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaFEDeFiJj3zSAwoAbmV0d29ya19pZG+iFRoKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:pink_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAwAACAQAbmFtZRwAbWluZWNyYWZ0OnBpbmtfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaDijTX87ywxhAwoAbmV0d29ya19pZKdEricKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:tinted_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRNAgAACAQAbmFtZRYAbWluZWNyYWZ0OnRpbnRlZF9nbGFzcwQJAG5hbWVfaGFzaAFZWSamk6KdAwoAbmV0d29ya19pZGSvWX8KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRmAAAACAQAbmFtZRQAbWluZWNyYWZ0OmdsYXNzX3BhbmUECQBuYW1lX2hhc2gRSBHwNMQ4gQMKAG5ldHdvcmtfaWRGwixuCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:white_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSgAAAACAQAbmFtZSIAbWluZWNyYWZ0OndoaXRlX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaHgxQmgJVtRrAwoAbmV0d29ya19pZBEr/DYKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:light_gray_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSJAwAACAQAbmFtZScAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNon0aQw9lNkSEDCgBuZXR3b3JrX2lk9dp5VgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:gray_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSIAwAACAQAbmFtZSEAbWluZWNyYWZ0OmdyYXlfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNors74IIw+2MMDCgBuZXR3b3JrX2lkmrGO5woGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:black_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSQAwAACAQAbmFtZSIAbWluZWNyYWZ0OmJsYWNrX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaOK/5ZRRd+M1AwoAbmV0d29ya19pZDv++oQKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:brown_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSNAwAACAQAbmFtZSIAbWluZWNyYWZ0OmJyb3duX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaLHeGJyRFTIWAwoAbmV0d29ya19pZMz9L0wKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:red_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSPAwAACAQAbmFtZSAAbWluZWNyYWZ0OnJlZF9zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2gGr4x6JheAywMKAG5ldHdvcmtfaWQBjCTmCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:orange_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSCAwAACAQAbmFtZSMAbWluZWNyYWZ0Om9yYW5nZV9zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2hbHxPD2gEbEAMKAG5ldHdvcmtfaWSt/7a5CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:yellow_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAwAACAQAbmFtZSMAbWluZWNyYWZ0OnllbGxvd19zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2g9tl4aOCyZBwMKAG5ldHdvcmtfaWTXRAS7CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:lime_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSGAwAACAQAbmFtZSEAbWluZWNyYWZ0OmxpbWVfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNo3CtUyLwoGegDCgBuZXR3b3JrX2lkYJDnggoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:green_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSOAwAACAQAbmFtZSIAbWluZWNyYWZ0OmdyZWVuX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaJo6YP7IMy9SAwoAbmV0d29ya19pZHOnixoKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:cyan_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSKAwAACAQAbmFtZSEAbWluZWNyYWZ0OmN5YW5fc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNoti97c6QrbLQDCgBuZXR3b3JrX2lkUqFUeQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:light_blue_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAwAACAQAbmFtZScAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNovDg/gQle104DCgBuZXR3b3JrX2lkFuy4MQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:blue_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSMAwAACAQAbmFtZSEAbWluZWNyYWZ0OmJsdWVfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNoGc57tiexbQMDCgBuZXR3b3JrX2lk1eBLUAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:purple_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAwAACAQAbmFtZSMAbWluZWNyYWZ0OnB1cnBsZV9zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2hDJHYdd0FdfQMKAG5ldHdvcmtfaWSNsdK5CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:magenta_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAwAACAQAbmFtZSQAbWluZWNyYWZ0Om1hZ2VudGFfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNo3pcOw5bs5XoDCgBuZXR3b3JrX2lkVbOR7AoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:pink_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSHAwAACAQAbmFtZSEAbWluZWNyYWZ0OnBpbmtfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNoWRhSACMWgswDCgBuZXR3b3JrX2lkIR92xwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:ladder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRBAAAACAQAbmFtZRAAbWluZWNyYWZ0OmxhZGRlcgQJAG5hbWVfaGFzaKBhqheJVOz+AwoAbmV0d29ya19pZCgvzlsKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:scaffolding", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSkAQAACAQAbmFtZRUAbWluZWNyYWZ0OnNjYWZmb2xkaW5nBAkAbmFtZV9oYXNoYrkevrqcljwDCgBuZXR3b3JrX2lkD13mlAoGAHN0YXRlcwMJAHN0YWJpbGl0eQAAAAABDwBzdGFiaWxpdHlfY2hlY2sAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:stone_block_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWTkNl0JCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQwAc21vb3RoX3N0b25lAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:stone_block_slab4", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkQJoxlgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNAUAc3RvbmUAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:stone_block_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWRHh04KCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQsAY29iYmxlc3RvbmUAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:stone_block_slab2", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkVRZB+woGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhEAbW9zc3lfY29iYmxlc3RvbmUAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:oak_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSeAAAACAQAbmFtZRIAbWluZWNyYWZ0Om9ha19zbGFiBAkAbmFtZV9oYXNoJp1Cp1M4jlwDCgBuZXR3b3JrX2lkZH6+owoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:spruce_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQjBAAACAQAbmFtZRUAbWluZWNyYWZ0OnNwcnVjZV9zbGFiBAkAbmFtZV9oYXNodQi70jB238cDCgBuZXR3b3JrX2lkrriOYQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:birch_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQkBAAACAQAbmFtZRQAbWluZWNyYWZ0OmJpcmNoX3NsYWIECQBuYW1lX2hhc2gZPpfMxoOsTAMKAG5ldHdvcmtfaWThR9jyCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:jungle_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQlBAAACAQAbmFtZRUAbWluZWNyYWZ0Omp1bmdsZV9zbGFiBAkAbmFtZV9oYXNo6gLs79NXak4DCgBuZXR3b3JrX2lk5ZiKgwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:acacia_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQmBAAACAQAbmFtZRUAbWluZWNyYWZ0OmFjYWNpYV9zbGFiBAkAbmFtZV9oYXNomSdFmDnv4OUDCgBuZXR3b3JrX2lkHttaXAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:dark_oak_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQnBAAACAQAbmFtZRcAbWluZWNyYWZ0OmRhcmtfb2FrX3NsYWIECQBuYW1lX2hhc2hJjTohRFyhIQMKAG5ldHdvcmtfaWRMzDTyCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:mangrove_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWToAgAACAQAbmFtZRcAbWluZWNyYWZ0Om1hbmdyb3ZlX3NsYWIECQBuYW1lX2hhc2jYCcmhJPeNMwMKAG5ldHdvcmtfaWQx6U1yCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:cherry_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQaAwAACAQAbmFtZRUAbWluZWNyYWZ0OmNoZXJyeV9zbGFiBAkAbmFtZV9oYXNoTt0MmVn/mqoDCgBuZXR3b3JrX2lk2VVsZQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:bamboo_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQAAwAACAQAbmFtZRUAbWluZWNyYWZ0OmJhbWJvb19zbGFiBAkAbmFtZV9oYXNoo1xuFqINeLYDCgBuZXR3b3JrX2lkVC+0twoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:bamboo_mosaic_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQLAwAACAQAbmFtZRwAbWluZWNyYWZ0OmJhbWJvb19tb3NhaWNfc2xhYgQJAG5hbWVfaGFzaNbVRBZ/ChI3AwoAbmV0d29ya19pZOLZHFMKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:stone_block_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWQSiInOCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQsAc3RvbmVfYnJpY2sAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:stone_block_slab4", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkoF89tgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNBEAbW9zc3lfc3RvbmVfYnJpY2sAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:stone_block_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWSkoAE4CgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQkAc2FuZHN0b25lAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:stone_block_slab4", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkWfF7pgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNA0AY3V0X3NhbmRzdG9uZQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:stone_block_slab2", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkbKRChAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAc21vb3RoX3NhbmRzdG9uZQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:stone_block_slab2", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkBlrvqAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMg0AcmVkX3NhbmRzdG9uZQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:stone_block_slab4", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkRWFXuwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNBEAY3V0X3JlZF9zYW5kc3RvbmUAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:stone_block_slab3", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkom8neQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxQAc21vb3RoX3JlZF9zYW5kc3RvbmUAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:stone_block_slab3", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkd1ZaWgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMwcAZ3Jhbml0ZQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:stone_block_slab3", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkISH4iwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxAAcG9saXNoZWRfZ3Jhbml0ZQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:stone_block_slab3", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkqxEDMwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMwcAZGlvcml0ZQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:stone_block_slab3", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkSYs86QoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxAAcG9saXNoZWRfZGlvcml0ZQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:stone_block_slab3", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkq6BU6goGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMwgAYW5kZXNpdGUAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:stone_block_slab3", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkTSXY8AoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxEAcG9saXNoZWRfYW5kZXNpdGUAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:stone_block_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWQiYHKTCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQUAYnJpY2sAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:stone_block_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWTk/0LfCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQwAbmV0aGVyX2JyaWNrAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:stone_block_slab2", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lk/hXQ7AoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAcmVkX25ldGhlcl9icmljawADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:stone_block_slab3", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkYJNxrwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMw8AZW5kX3N0b25lX2JyaWNrAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:stone_block_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWRlj0/sCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQYAcXVhcnR6AAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:stone_block_slab4", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkMae+2goGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNA0Ac21vb3RoX3F1YXJ0egADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:stone_block_slab2", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lk+kMHGAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMgYAcHVycHVyAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:stone_block_slab2", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkKOSOMAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAcHJpc21hcmluZV9yb3VnaAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:stone_block_slab2", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lk8igLCQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMg8AcHJpc21hcmluZV9kYXJrAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:stone_block_slab2", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkSFbyEwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAcHJpc21hcmluZV9icmljawADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:crimson_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQHAgAACAQAbmFtZRYAbWluZWNyYWZ0OmNyaW1zb25fc2xhYgQJAG5hbWVfaGFzaKZ+EfP0ZYOZAwoAbmV0d29ya19pZAxRUWAKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:warped_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQIAgAACAQAbmFtZRUAbWluZWNyYWZ0OndhcnBlZF9zbGFiBAkAbmFtZV9oYXNo/AT0e/Z9W7UDCgBuZXR3b3JrX2lk1yq11AoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:blackstone_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQZAgAACAQAbmFtZRkAbWluZWNyYWZ0OmJsYWNrc3RvbmVfc2xhYgQJAG5hbWVfaGFzaF/DD4ZUlNgtAwoAbmV0d29ya19pZGy1DjwKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:polished_blackstone_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQkAgAACAQAbmFtZSIAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfc2xhYgQJAG5hbWVfaGFzaDYnuUs86EWfAwoAbmV0d29ya19pZJj2bXIKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:polished_blackstone_brick_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQbAgAACAQAbmFtZSgAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tfc2xhYgQJAG5hbWVfaGFzaKySLqvHc4xXAwoAbmV0d29ya19pZOyWX94KBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:cut_copper_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRoAgAACAQAbmFtZRkAbWluZWNyYWZ0OmN1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaDsNpb2qs4iBAwoAbmV0d29ya19pZOTm2nsKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:exposed_cut_copper_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRpAgAACAQAbmFtZSEAbWluZWNyYWZ0OmV4cG9zZWRfY3V0X2NvcHBlcl9zbGFiBAkAbmFtZV9oYXNoahQ5OwIQb7kDCgBuZXR3b3JrX2lkrUlZLwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:weathered_cut_copper_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRqAgAACAQAbmFtZSMAbWluZWNyYWZ0OndlYXRoZXJlZF9jdXRfY29wcGVyX3NsYWIECQBuYW1lX2hhc2hBIuGIOVVXogMKAG5ldHdvcmtfaWQgnaDiCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:oxidized_cut_copper_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRrAgAACAQAbmFtZSIAbWluZWNyYWZ0Om94aWRpemVkX2N1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaOptj9ycfpaDAwoAbmV0d29ya19pZMzFSRgKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:waxed_cut_copper_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRsAgAACAQAbmFtZR8AbWluZWNyYWZ0OndheGVkX2N1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaAlx6DZOCTHzAwoAbmV0d29ya19pZFRBvDAKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:waxed_exposed_cut_copper_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRtAgAACAQAbmFtZScAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY3V0X2NvcHBlcl9zbGFiBAkAbmFtZV9oYXNo3KqS5OnhtRIDCgBuZXR3b3JrX2lkHTGcTgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:waxed_weathered_cut_copper_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRuAgAACAQAbmFtZSkAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jdXRfY29wcGVyX3NsYWIECQBuYW1lX2hhc2gzZ1oX0HCFtwMKAG5ldHdvcmtfaWSgJR+XCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:waxed_oxidized_cut_copper_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTAAgAACAQAbmFtZSgAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2N1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaMjjTnLu1KcqAwoAbmV0d29ya19pZIxsnFYKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:cobbled_deepslate_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR7AgAACAQAbmFtZSAAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlX3NsYWIECQBuYW1lX2hhc2gwJIVWK1TM2QMKAG5ldHdvcmtfaWTYAoX5CgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:polished_deepslate_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR/AgAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZV9zbGFiBAkAbmFtZV9oYXNoC/Adiz8k6RYDCgBuZXR3b3JrX2lkuFYMAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:deepslate_tile_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAgAACAQAbmFtZR0AbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlX3NsYWIECQBuYW1lX2hhc2hPydV6emzIXAMKAG5ldHdvcmtfaWQwlbFCCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:deepslate_brick_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSHAgAACAQAbmFtZR4AbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja19zbGFiBAkAbmFtZV9oYXNoSv62V7iw10UDCgBuZXR3b3JrX2lkWMoragoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:mud_brick_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTdAgAACAQAbmFtZRgAbWluZWNyYWZ0Om11ZF9icmlja19zbGFiBAkAbmFtZV9oYXNoq/tGBQWkv08DCgBuZXR3b3JrX2lkl4nnMwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:brick_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQtAAAACAQAbmFtZRUAbWluZWNyYWZ0OmJyaWNrX2Jsb2NrBAkAbmFtZV9oYXNo5Qc2E005S3oDCgBuZXR3b3JrX2lkqeGWRgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:chiseled_nether_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQtAgAACAQAbmFtZSAAbWluZWNyYWZ0OmNoaXNlbGVkX25ldGhlcl9icmlja3MECQBuYW1lX2hhc2g31SBPTcUK1QMKAG5ldHdvcmtfaWS8TJ+TCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:cracked_nether_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQuAgAACAQAbmFtZR8AbWluZWNyYWZ0OmNyYWNrZWRfbmV0aGVyX2JyaWNrcwQJAG5hbWVfaGFzaAdC6eKzXT5tAwoAbmV0d29ya19pZIUSejwKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:quartz_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQvAgAACAQAbmFtZRcAbWluZWNyYWZ0OnF1YXJ0el9icmlja3MECQBuYW1lX2hhc2jSZO590dd8sAMKAG5ldHdvcmtfaWSc5xCLCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:stonebrick", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAAAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWQ5kni1CgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQcAZGVmYXVsdAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:stonebrick", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAAAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWTDw813CgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQUAbW9zc3kAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:stonebrick", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAAAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWSTvQGECgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQcAY3JhY2tlZAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:stonebrick", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAAAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWQIM0OwCgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQgAY2hpc2VsZWQAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:end_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTOAAAACAQAbmFtZRQAbWluZWNyYWZ0OmVuZF9icmlja3MECQBuYW1lX2hhc2hIUFfxNLZaFgMKAG5ldHdvcmtfaWQ/vDihCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:prismarine", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAAAACAQAbmFtZRQAbWluZWNyYWZ0OnByaXNtYXJpbmUECQBuYW1lX2hhc2jcnQCHi9CspQMKAG5ldHdvcmtfaWSH021WCgYAc3RhdGVzCBUAcHJpc21hcmluZV9ibG9ja190eXBlBgBicmlja3MAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:polished_blackstone_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQRAgAACAQAbmFtZSQAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tzBAkAbmFtZV9oYXNoIHgsgIdzKXcDCgBuZXR3b3JrX2lkUw9b3woGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:cracked_polished_blackstone_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQXAgAACAQAbmFtZSwAbWluZWNyYWZ0OmNyYWNrZWRfcG9saXNoZWRfYmxhY2tzdG9uZV9icmlja3MECQBuYW1lX2hhc2jQIO1GQDk80AMKAG5ldHdvcmtfaWQ3UlRYCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:gilded_blackstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAgAACAQAbmFtZRsAbWluZWNyYWZ0OmdpbGRlZF9ibGFja3N0b25lBAkAbmFtZV9oYXNoNoWt1ocG0HEDCgBuZXR3b3JrX2lktL8gUwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:chiseled_polished_blackstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQWAgAACAQAbmFtZSYAbWluZWNyYWZ0OmNoaXNlbGVkX3BvbGlzaGVkX2JsYWNrc3RvbmUECQBuYW1lX2hhc2gzFa+kEjCJgAMKAG5ldHdvcmtfaWR2NJX2CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:deepslate_tiles", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSCAgAACAQAbmFtZRkAbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlcwQJAG5hbWVfaGFzaGcLLx3NXAFvAwoAbmV0d29ya19pZI/G/xYKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:cracked_deepslate_tiles", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSYAgAACAQAbmFtZSEAbWluZWNyYWZ0OmNyYWNrZWRfZGVlcHNsYXRlX3RpbGVzBAkAbmFtZV9oYXNo9zWgkFuMM1QDCgBuZXR3b3JrX2lkGwY6OgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:deepslate_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSGAgAACAQAbmFtZRoAbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja3MECQBuYW1lX2hhc2gucvFmPdZxigMKAG5ldHdvcmtfaWSH4HDPCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:cracked_deepslate_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSZAgAACAQAbmFtZSIAbWluZWNyYWZ0OmNyYWNrZWRfZGVlcHNsYXRlX2JyaWNrcwQJAG5hbWVfaGFzaN40aqhh9WqHAwoAbmV0d29ya19pZO9GPBQKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:chiseled_deepslate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSKAgAACAQAbmFtZRwAbWluZWNyYWZ0OmNoaXNlbGVkX2RlZXBzbGF0ZQQJAG5hbWVfaGFzaEU7/uRG8HSBAwoAbmV0d29ya19pZEqmI0EKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:cobblestone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQEAAAACAQAbmFtZRUAbWluZWNyYWZ0OmNvYmJsZXN0b25lBAkAbmFtZV9oYXNoPoK7mGlSUz4DCgBuZXR3b3JrX2lkLm7RZwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:mossy_cobblestone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQwAAAACAQAbmFtZRsAbWluZWNyYWZ0Om1vc3N5X2NvYmJsZXN0b25lBAkAbmFtZV9oYXNoGJ67FCbkChMDCgBuZXR3b3JrX2lk/pYs1AoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:cobbled_deepslate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR6AgAACAQAbmFtZRsAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlBAkAbmFtZV9oYXNoLUz9Y/ywmLwDCgBuZXR3b3JrX2lkNwzZ+AoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:smooth_stone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AQAACAQAbmFtZRYAbWluZWNyYWZ0OnNtb290aF9zdG9uZQQJAG5hbWVfaGFzaMwf87/JaTNvAwoAbmV0d29ya19pZLkZICEKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:sandstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZB2wApMKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGUHAGRlZmF1bHQAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:sandstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZB7E+eQKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGULAGhlaXJvZ2x5cGhzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:sandstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZFQnDaEKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGUDAGN1dAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:sandstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZPO4A3IKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGUGAHNtb290aAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:red_sandstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWRhNYiFCgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlBwBkZWZhdWx0AAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:red_sandstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWTqXJr1CgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlCwBoZWlyb2dseXBocwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:red_sandstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWTQRGkFCgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlAwBjdXQAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:red_sandstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWTvAHWDCgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlBgBzbW9vdGgAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:coal_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWStAAAACAQAbmFtZRQAbWluZWNyYWZ0OmNvYWxfYmxvY2sECQBuYW1lX2hhc2jH8QQP3t5PiAMKAG5ldHdvcmtfaWRo+sR+CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:dried_kelp_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSKAQAACAQAbmFtZRoAbWluZWNyYWZ0OmRyaWVkX2tlbHBfYmxvY2sECQBuYW1lX2hhc2iRoucexkrl8wMKAG5ldHdvcmtfaWQQCCrvCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:gold_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQpAAAACAQAbmFtZRQAbWluZWNyYWZ0OmdvbGRfYmxvY2sECQBuYW1lX2hhc2iYLshvjtXzFwMKAG5ldHdvcmtfaWTDJGBcCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:iron_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQqAAAACAQAbmFtZRQAbWluZWNyYWZ0Omlyb25fYmxvY2sECQBuYW1lX2hhc2jYINmJQbvV/gMKAG5ldHdvcmtfaWRf7AbICgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:copper_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRTAgAACAQAbmFtZRYAbWluZWNyYWZ0OmNvcHBlcl9ibG9jawQJAG5hbWVfaGFzaDVxnehsGaZ1AwoAbmV0d29ya19pZIiUodwKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:exposed_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRUAgAACAQAbmFtZRgAbWluZWNyYWZ0OmV4cG9zZWRfY29wcGVyBAkAbmFtZV9oYXNoQH3Fukmu3CEDCgBuZXR3b3JrX2lk72jFIwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:weathered_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRVAgAACAQAbmFtZRoAbWluZWNyYWZ0OndlYXRoZXJlZF9jb3BwZXIECQBuYW1lX2hhc2hJCQXbvobv+gMKAG5ldHdvcmtfaWQwM0lJCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:oxidized_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRWAgAACAQAbmFtZRkAbWluZWNyYWZ0Om94aWRpemVkX2NvcHBlcgQJAG5hbWVfaGFzaMDtJqR0G5Y7AwoAbmV0d29ya19pZGjN8bUKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:waxed_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRXAgAACAQAbmFtZRYAbWluZWNyYWZ0OndheGVkX2NvcHBlcgQJAG5hbWVfaGFzaPF+FG6Eh5fsAwoAbmV0d29ya19pZIjtz/0KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:waxed_exposed_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRYAgAACAQAbmFtZR4AbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY29wcGVyBAkAbmFtZV9oYXNoig8IOc+SCikDCgBuZXR3b3JrX2lklz8yWQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:waxed_weathered_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRZAgAACAQAbmFtZSAAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jb3BwZXIECQBuYW1lX2hhc2gjtPq8MOdvKgMKAG5ldHdvcmtfaWSQ9Ln9CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:waxed_oxidized_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS9AgAACAQAbmFtZR8AbWluZWNyYWZ0OndheGVkX294aWRpemVkX2NvcHBlcgQJAG5hbWVfaGFzaMaORhsO+LzjAwoAbmV0d29ya19pZJhGfLEKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:cut_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRaAgAACAQAbmFtZRQAbWluZWNyYWZ0OmN1dF9jb3BwZXIECQBuYW1lX2hhc2hAfN3NGax3eAMKAG5ldHdvcmtfaWTnFBtYCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:exposed_cut_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRbAgAACAQAbmFtZRwAbWluZWNyYWZ0OmV4cG9zZWRfY3V0X2NvcHBlcgQJAG5hbWVfaGFzaA85G3yv/w6pAwoAbmV0d29ya19pZMQhr0QKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:weathered_cut_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRcAgAACAQAbmFtZR4AbWluZWNyYWZ0OndlYXRoZXJlZF9jdXRfY29wcGVyBAkAbmFtZV9oYXNoVgRV0fBaz88DCgBuZXR3b3JrX2lk/0cYugoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:oxidized_cut_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRdAgAACAQAbmFtZR0AbWluZWNyYWZ0Om94aWRpemVkX2N1dF9jb3BwZXIECQBuYW1lX2hhc2iP8WmFWOkriwMKAG5ldHdvcmtfaWQPdce7CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:waxed_cut_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWReAgAACAQAbmFtZRoAbWluZWNyYWZ0OndheGVkX2N1dF9jb3BwZXIECQBuYW1lX2hhc2jumiwOZIqv2AMKAG5ldHdvcmtfaWQvuxx9CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:waxed_exposed_cut_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRfAgAACAQAbmFtZSIAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY3V0X2NvcHBlcgQJAG5hbWVfaGFzaPE/OfK6IoVMAwoAbmV0d29ya19pZHy5HkcKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:waxed_weathered_cut_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRgAgAACAQAbmFtZSQAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jdXRfY29wcGVyBAkAbmFtZV9oYXNoCA1xDp11bnwDCgBuZXR3b3JrX2lkDyEDVQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:waxed_oxidized_cut_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS+AgAACAQAbmFtZSMAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2N1dF9jb3BwZXIECQBuYW1lX2hhc2i1pZAsZYHLDAMKAG5ldHdvcmtfaWQ/wSkCCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:emerald_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAAAACAQAbmFtZRcAbWluZWNyYWZ0OmVtZXJhbGRfYmxvY2sECQBuYW1lX2hhc2hK6QunqJznNAMKAG5ldHdvcmtfaWRk5+otCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:diamond_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ5AAAACAQAbmFtZRcAbWluZWNyYWZ0OmRpYW1vbmRfYmxvY2sECQBuYW1lX2hhc2iGKrxuvkytFQMKAG5ldHdvcmtfaWQQeQZXCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:lapis_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQWAAAACAQAbmFtZRUAbWluZWNyYWZ0OmxhcGlzX2Jsb2NrBAkAbmFtZV9oYXNoDZ44xdb2zVoDCgBuZXR3b3JrX2lktVy0BAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:raw_iron_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTCAgAACAQAbmFtZRgAbWluZWNyYWZ0OnJhd19pcm9uX2Jsb2NrBAkAbmFtZV9oYXNo9XyzNIQXxvwDCgBuZXR3b3JrX2lknms1QAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:raw_copper_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTDAgAACAQAbmFtZRoAbWluZWNyYWZ0OnJhd19jb3BwZXJfYmxvY2sECQBuYW1lX2hhc2hw1KG0TNUGgwMKAG5ldHdvcmtfaWS1vGo/CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:raw_gold_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTEAgAACAQAbmFtZRgAbWluZWNyYWZ0OnJhd19nb2xkX2Jsb2NrBAkAbmFtZV9oYXNo6YuwuLwfOBwDCgBuZXR3b3JrX2lkLiQ5gQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:quartz_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAAAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZEupC1AKBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQcAZGVmYXVsdAgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:quartz_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAAAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZM97+l0KBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQUAbGluZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:quartz_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAAAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZCbTfssKBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQgAY2hpc2VsZWQICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:quartz_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAAAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZJss8V0KBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQYAc21vb3RoCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:prismarine", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAAAACAQAbmFtZRQAbWluZWNyYWZ0OnByaXNtYXJpbmUECQBuYW1lX2hhc2jcnQCHi9CspQMKAG5ldHdvcmtfaWRFIsoGCgYAc3RhdGVzCBUAcHJpc21hcmluZV9ibG9ja190eXBlBwBkZWZhdWx0AAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:prismarine", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAAAACAQAbmFtZRQAbWluZWNyYWZ0OnByaXNtYXJpbmUECQBuYW1lX2hhc2jcnQCHi9CspQMKAG5ldHdvcmtfaWTDNWOvCgYAc3RhdGVzCBUAcHJpc21hcmluZV9ibG9ja190eXBlBABkYXJrAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:slime", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAAAACAQAbmFtZQ8AbWluZWNyYWZ0OnNsaW1lBAkAbmFtZV9oYXNoHJiEEJx+JlkDCgBuZXR3b3JrX2lkfgfVzAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:honey_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTbAQAACAQAbmFtZRUAbWluZWNyYWZ0OmhvbmV5X2Jsb2NrBAkAbmFtZV9oYXNo9zLYSUlelywDCgBuZXR3b3JrX2lko+dyWgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:honeycomb_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTcAQAACAQAbmFtZRkAbWluZWNyYWZ0OmhvbmV5Y29tYl9ibG9jawQJAG5hbWVfaGFzaASIPuOCYd1oAwoAbmV0d29ya19pZKys4n4KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:hay_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSqAAAACAQAbmFtZRMAbWluZWNyYWZ0OmhheV9ibG9jawQJAG5hbWVfaGFzaIB2VxKxX8EpAwoAbmV0d29ya19pZKuQSloKBgBzdGF0ZXMDCgBkZXByZWNhdGVkAAAAAAgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:bone_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTYAAAACAQAbmFtZRQAbWluZWNyYWZ0OmJvbmVfYmxvY2sECQBuYW1lX2hhc2i4ZX576W9AWgMKAG5ldHdvcmtfaWTWGacQCgYAc3RhdGVzAwoAZGVwcmVjYXRlZAAAAAAICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:nether_brick", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRwAAAACAQAbmFtZRYAbWluZWNyYWZ0Om5ldGhlcl9icmljawQJAG5hbWVfaGFzaMxcRiheU+nXAwoAbmV0d29ya19pZMkmzloKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:red_nether_brick", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTXAAAACAQAbmFtZRoAbWluZWNyYWZ0OnJlZF9uZXRoZXJfYnJpY2sECQBuYW1lX2hhc2j8pRO4LfoECAMKAG5ldHdvcmtfaWRpdF0YCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:netherite_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQNAgAACAQAbmFtZRkAbWluZWNyYWZ0Om5ldGhlcml0ZV9ibG9jawQJAG5hbWVfaGFzaMghh6Zib/ZKAwoAbmV0d29ya19pZIz0mq0KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:lodestone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTdAQAACAQAbmFtZRMAbWluZWNyYWZ0OmxvZGVzdG9uZQQJAG5hbWVfaGFzaJ2gmHOTlXv8AwoAbmV0d29ya19pZEfgB4wKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:white_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQjAAAACAQAbmFtZRQAbWluZWNyYWZ0OndoaXRlX3dvb2wECQBuYW1lX2hhc2jRWB7vaIEDiQMKAG5ldHdvcmtfaWSO8paQCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:light_gray_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQnAwAACAQAbmFtZRkAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfd29vbAQJAG5hbWVfaGFzaOpdQ1a2v4b3AwoAbmV0d29ya19pZIqZCYEKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:gray_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQoAwAACAQAbmFtZRMAbWluZWNyYWZ0OmdyYXlfd29vbAQJAG5hbWVfaGFzaLsc1Lp1xdIOAwoAbmV0d29ya19pZFUs+HgKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:black_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQpAwAACAQAbmFtZRQAbWluZWNyYWZ0OmJsYWNrX3dvb2wECQBuYW1lX2hhc2hP2HC6o0X4HAMKAG5ldHdvcmtfaWRUbORcCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:brown_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQqAwAACAQAbmFtZRQAbWluZWNyYWZ0OmJyb3duX3dvb2wECQBuYW1lX2hhc2ig5IW89PrREwMKAG5ldHdvcmtfaWRjT9j8CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:red_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQrAwAACAQAbmFtZRIAbWluZWNyYWZ0OnJlZF93b29sBAkAbmFtZV9oYXNoY4TBDq+mFgUDCgBuZXR3b3JrX2lktn9lcAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:orange_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAwAACAQAbmFtZRUAbWluZWNyYWZ0Om9yYW5nZV93b29sBAkAbmFtZV9oYXNoFstfrTZfSCgDCgBuZXR3b3JrX2lk+rqywwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:yellow_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQtAwAACAQAbmFtZRUAbWluZWNyYWZ0OnllbGxvd193b29sBAkAbmFtZV9oYXNoTFyus2RHegcDCgBuZXR3b3JrX2lkkKBhXAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:lime_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQuAwAACAQAbmFtZRMAbWluZWNyYWZ0OmxpbWVfd29vbAQJAG5hbWVfaGFzaNVnnzKiMxmeAwoAbmV0d29ya19pZG9b32kKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:green_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQvAwAACAQAbmFtZRQAbWluZWNyYWZ0OmdyZWVuX3dvb2wECQBuYW1lX2hhc2i3mElRYHIcSQMKAG5ldHdvcmtfaWSssprwCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:cyan_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQwAwAACAQAbmFtZRMAbWluZWNyYWZ0OmN5YW5fd29vbAQJAG5hbWVfaGFzaBNDfvHn8dqFAwoAbmV0d29ya19pZK0hAbgKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:light_blue_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQxAwAACAQAbmFtZRkAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfd29vbAQJAG5hbWVfaGFzaLWFAUfyxFPNAwoAbmV0d29ya19pZL2oEugKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:blue_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQyAwAACAQAbmFtZRMAbWluZWNyYWZ0OmJsdWVfd29vbAQJAG5hbWVfaGFzaLjHyxxbTWCLAwoAbmV0d29ya19pZPaLdFQKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:purple_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQzAwAACAQAbmFtZRUAbWluZWNyYWZ0OnB1cnBsZV93b29sBAkAbmFtZV9oYXNojvFtqzjAf/4DCgBuZXR3b3JrX2lklqASNQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:magenta_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ0AwAACAQAbmFtZRYAbWluZWNyYWZ0Om1hZ2VudGFfd29vbAQJAG5hbWVfaGFzaGuOHvf+Pd4yAwoAbmV0d29ya19pZI4UoDQKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:pink_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ1AwAACAQAbmFtZRMAbWluZWNyYWZ0OnBpbmtfd29vbAQJAG5hbWVfaGFzaPiVA2pFeoFLAwoAbmV0d29ya19pZOZRO6oKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:white_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSrAAAACAQAbmFtZRYAbWluZWNyYWZ0OndoaXRlX2NhcnBldAQJAG5hbWVfaGFzaNeMHTI1fWPXAwoAbmV0d29ya19pZEahDFcKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:light_gray_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRbAwAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY2FycGV0BAkAbmFtZV9oYXNoHPw6ArBAsP0DCgBuZXR3b3JrX2lkQoAeUAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:gray_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRaAwAACAQAbmFtZRUAbWluZWNyYWZ0OmdyYXlfY2FycGV0BAkAbmFtZV9oYXNoZVR0OI+1VRADCgBuZXR3b3JrX2lkETF4WwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:black_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJsYWNrX2NhcnBldAQJAG5hbWVfaGFzaOk7LP9NptyhAwoAbmV0d29ya19pZFjmXtIKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:brown_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRfAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJyb3duX2NhcnBldAQJAG5hbWVfaGFzaNaXFyOsAvIvAwoAbmV0d29ya19pZHPjFuoKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:red_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAwAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9jYXJwZXQECQBuYW1lX2hhc2i9eSKBf6SO3wMKAG5ldHdvcmtfaWQuhI/KCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:orange_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRUAwAACAQAbmFtZRcAbWluZWNyYWZ0Om9yYW5nZV9jYXJwZXQECQBuYW1lX2hhc2hIUkO4HlAdygMKAG5ldHdvcmtfaWSyKV9OCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:yellow_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRXAwAACAQAbmFtZRcAbWluZWNyYWZ0OnllbGxvd19jYXJwZXQECQBuYW1lX2hhc2hSDKX3scCamwMKAG5ldHdvcmtfaWT8nq+ECgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:lime_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRYAwAACAQAbmFtZRUAbWluZWNyYWZ0OmxpbWVfY2FycGV0BAkAbmFtZV9oYXNo+6KFOpzsib4DCgBuZXR3b3JrX2lkT+DS4woGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:green_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRgAwAACAQAbmFtZRYAbWluZWNyYWZ0OmdyZWVuX2NhcnBldAQJAG5hbWVfaGFzaCHPMP9ltqFJAwoAbmV0d29ya19pZBgwAvAKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:cyan_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRcAwAACAQAbmFtZRUAbWluZWNyYWZ0OmN5YW5fY2FycGV0BAkAbmFtZV9oYXNobXf62dQBJj8DCgBuZXR3b3JrX2lkKVppLgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:light_blue_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRWAwAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY2FycGV0BAkAbmFtZV9oYXNo20l4oktdZ3sDCgBuZXR3b3JrX2lkjdeMiwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:blue_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWReAwAACAQAbmFtZRUAbWluZWNyYWZ0OmJsdWVfY2FycGV0BAkAbmFtZV9oYXNo3p3lsW0eQwsDCgBuZXR3b3JrX2lkAovdPQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:purple_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRdAwAACAQAbmFtZRcAbWluZWNyYWZ0OnB1cnBsZV9jYXJwZXQECQBuYW1lX2hhc2jwIA9pW/qp7QMKAG5ldHdvcmtfaWTqJqhjCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:magenta_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRVAwAACAQAbmFtZRgAbWluZWNyYWZ0Om1hZ2VudGFfY2FycGV0BAkAbmFtZV9oYXNoFXT36YNNZhMDCgBuZXR3b3JrX2lk+tqsGAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:pink_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRZAwAACAQAbmFtZRUAbWluZWNyYWZ0OnBpbmtfY2FycGV0BAkAbmFtZV9oYXNoHll72oqk+OoDCgBuZXR3b3JrX2lkrnBYDwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:white_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTtAAAACAQAbmFtZR8AbWluZWNyYWZ0OndoaXRlX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaFUk9iXVjwV8AwoAbmV0d29ya19pZJPZY8AKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:light_gray_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTLAwAACAQAbmFtZSQAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNo7EUk30hmUtYDCgBuZXR3b3JrX2lkh8jVIwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:gray_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTKAwAACAQAbmFtZR4AbWluZWNyYWZ0OmdyYXlfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoW77af6WihdwDCgBuZXR3b3JrX2lkSsqC1woGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:black_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTSAwAACAQAbmFtZR8AbWluZWNyYWZ0OmJsYWNrX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaAfWYp0xtgcfAwoAbmV0d29ya19pZMWTC8EKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:brown_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTPAwAACAQAbmFtZR8AbWluZWNyYWZ0OmJyb3duX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaB74EeiLO46XAwoAbmV0d29ya19pZEDHKqwKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:red_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTRAwAACAQAbmFtZR0AbWluZWNyYWZ0OnJlZF9jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2gjFut6Z/VH1gMKAG5ldHdvcmtfaWSvcmwYCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:orange_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTEAwAACAQAbmFtZSAAbWluZWNyYWZ0Om9yYW5nZV9jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2gADDj2IJiw+gMKAG5ldHdvcmtfaWTHph0FCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:yellow_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTHAwAACAQAbmFtZSAAbWluZWNyYWZ0OnllbGxvd19jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2iy6qKNn3ob5wMKAG5ldHdvcmtfaWQZAI39CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:lime_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTIAwAACAQAbmFtZR4AbWluZWNyYWZ0OmxpbWVfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNo4dYIPslbXPUDCgBuZXR3b3JrX2lk2O8X0AoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:green_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTQAwAACAQAbmFtZR8AbWluZWNyYWZ0OmdyZWVuX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaM/c9x2aJh3HAwoAbmV0d29ya19pZA0VfBMKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:cyan_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTMAwAACAQAbmFtZR4AbWluZWNyYWZ0OmN5YW5fY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNok+xKAe7XXjoDCgBuZXR3b3JrX2lkmkn6uwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:light_blue_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTGAwAACAQAbmFtZSQAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNogScpIQceyAEDCgBuZXR3b3JrX2lkOmVSbgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:blue_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTOAwAACAQAbmFtZR4AbWluZWNyYWZ0OmJsdWVfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoFp7mmeL86r0DCgBuZXR3b3JrX2lkS3b3RQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:purple_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTNAwAACAQAbmFtZSAAbWluZWNyYWZ0OnB1cnBsZV9jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2iYcVU04hoStwMKAG5ldHdvcmtfaWQXimEjCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:magenta_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTFAwAACAQAbmFtZSEAbWluZWNyYWZ0Om1hZ2VudGFfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoy/70q6VPsWgDCgBuZXR3b3JrX2lkf9mxQwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:pink_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAwAACAQAbmFtZR4AbWluZWNyYWZ0OnBpbmtfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoVikSAf8DwV0DCgBuZXR3b3JrX2lku2MivwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:white_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTsAAAACAQAbmFtZRgAbWluZWNyYWZ0OndoaXRlX2NvbmNyZXRlBAkAbmFtZV9oYXNo6zAp7lsLlvkDCgBuZXR3b3JrX2lk3MAYQAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:light_gray_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR6AwAACAQAbmFtZR0AbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY29uY3JldGUECQBuYW1lX2hhc2hEtet5wuDIKAMKAG5ldHdvcmtfaWQISs02CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:gray_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR5AwAACAQAbmFtZRcAbWluZWNyYWZ0OmdyYXlfY29uY3JldGUECQBuYW1lX2hhc2j92INnb0a83AMKAG5ldHdvcmtfaWQj8RHwCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:black_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSBAwAACAQAbmFtZRgAbWluZWNyYWZ0OmJsYWNrX2NvbmNyZXRlBAkAbmFtZV9oYXNo2X7NDIQmZ70DCgBuZXR3b3JrX2lk2uiVDQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:brown_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR+AwAACAQAbmFtZRgAbWluZWNyYWZ0OmJyb3duX2NvbmNyZXRlBAkAbmFtZV9oYXNoeka02BwXf6oDCgBuZXR3b3JrX2lkYf+xDQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:red_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSAAwAACAQAbmFtZRYAbWluZWNyYWZ0OnJlZF9jb25jcmV0ZQQJAG5hbWVfaGFzaPWmNowLGubqAwoAbmV0d29ya19pZKwyx58KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:orange_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRzAwAACAQAbmFtZRkAbWluZWNyYWZ0Om9yYW5nZV9jb25jcmV0ZQQJAG5hbWVfaGFzaAgE8XmaAi6+AwoAbmV0d29ya19pZMDQNz8KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:yellow_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR2AwAACAQAbmFtZRkAbWluZWNyYWZ0OnllbGxvd19jb25jcmV0ZQQJAG5hbWVfaGFzaE6ONfJPBd0+AwoAbmV0d29ya19pZMarutwKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:lime_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR3AwAACAQAbmFtZRcAbWluZWNyYWZ0OmxpbWVfY29uY3JldGUECQBuYW1lX2hhc2gnd8JW6wmJcAMKAG5ldHdvcmtfaWTd47aoCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:green_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR/AwAACAQAbmFtZRgAbWluZWNyYWZ0OmdyZWVuX2NvbmNyZXRlBAkAbmFtZV9oYXNokbFxRKchQZkDCgBuZXR3b3JrX2lkmhZWUgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:cyan_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR7AwAACAQAbmFtZRcAbWluZWNyYWZ0OmN5YW5fY29uY3JldGUECQBuYW1lX2hhc2hFRrWJ33qj1wMKAG5ldHdvcmtfaWQbi5b8CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:light_blue_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR1AwAACAQAbmFtZR0AbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY29uY3JldGUECQBuYW1lX2hhc2gHAe0kl0SE4AMKAG5ldHdvcmtfaWRL/GbSCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:blue_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR9AwAACAQAbmFtZRcAbWluZWNyYWZ0OmJsdWVfY29uY3JldGUECQBuYW1lX2hhc2hiay301nnj1wMKAG5ldHdvcmtfaWRMvFXNCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:purple_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR8AwAACAQAbmFtZRkAbWluZWNyYWZ0OnB1cnBsZV9jb25jcmV0ZQQJAG5hbWVfaGFzaHBHflsPIwdXAwoAbmV0d29ya19pZCyKA5gKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:magenta_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR0AwAACAQAbmFtZRoAbWluZWNyYWZ0Om1hZ2VudGFfY29uY3JldGUECQBuYW1lX2hhc2gN7LuB/OvdZAMKAG5ldHdvcmtfaWTc6ZOdCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:pink_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR4AwAACAQAbmFtZRcAbWluZWNyYWZ0OnBpbmtfY29uY3JldGUECQBuYW1lX2hhc2ii2G5F0u3SOAMKAG5ldHdvcmtfaWSszGgrCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:clay", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRSAAAACAQAbmFtZQ4AbWluZWNyYWZ0OmNsYXkECQBuYW1lX2hhc2j/S6sKXRcpzwMKAG5ldHdvcmtfaWRmsb8nCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:hardened_clay", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSsAAAACAQAbmFtZRcAbWluZWNyYWZ0OmhhcmRlbmVkX2NsYXkECQBuYW1lX2hhc2jrnRwCJ0krJAMKAG5ldHdvcmtfaWRBCOrrCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:white_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSfAAAACAQAbmFtZRoAbWluZWNyYWZ0OndoaXRlX3RlcnJhY290dGEECQBuYW1lX2hhc2j3RSdgmnAIewMKAG5ldHdvcmtfaWSimKw+CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:light_gray_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTaAwAACAQAbmFtZR8AbWluZWNyYWZ0OmxpZ2h0X2dyYXlfdGVycmFjb3R0YQQJAG5hbWVfaGFzaAz1Ri3wIxomAwoAbmV0d29ya19pZH5qgOcKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:gray_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTZAwAACAQAbmFtZRkAbWluZWNyYWZ0OmdyYXlfdGVycmFjb3R0YQQJAG5hbWVfaGFzaAXdSLAaNZ9vAwoAbmV0d29ya19pZM1QDV0KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:black_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWThAwAACAQAbmFtZRoAbWluZWNyYWZ0OmJsYWNrX3RlcnJhY290dGEECQBuYW1lX2hhc2jxssdv5vlbpgMKAG5ldHdvcmtfaWRE3Ru/CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:brown_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTeAwAACAQAbmFtZRoAbWluZWNyYWZ0OmJyb3duX3RlcnJhY290dGEECQBuYW1lX2hhc2gG4kPenmOF9gMKAG5ldHdvcmtfaWQ/i0iNCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:red_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTgAwAACAQAbmFtZRgAbWluZWNyYWZ0OnJlZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNo7fX56HXFejEDCgBuZXR3b3JrX2lk8tTF8QoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:orange_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAwAACAQAbmFtZRsAbWluZWNyYWZ0Om9yYW5nZV90ZXJyYWNvdHRhBAkAbmFtZV9oYXNo0Hjmql3sruMDCgBuZXR3b3JrX2lklmqmkAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:yellow_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTWAwAACAQAbmFtZRsAbWluZWNyYWZ0OnllbGxvd190ZXJyYWNvdHRhBAkAbmFtZV9oYXNoqkyKKrmA3VcDCgBuZXR3b3JrX2lkaM/orAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:lime_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTXAwAACAQAbmFtZRkAbWluZWNyYWZ0OmxpbWVfdGVycmFjb3R0YQQJAG5hbWVfaGFzaANjADFOF9v7AwoAbmV0d29ya19pZJt0XsgKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:green_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTfAwAACAQAbmFtZRoAbWluZWNyYWZ0OmdyZWVuX3RlcnJhY290dGEECQBuYW1lX2hhc2j5Ybq36yYwRQMKAG5ldHdvcmtfaWQ8kGdHCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:cyan_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTbAwAACAQAbmFtZRkAbWluZWNyYWZ0OmN5YW5fdGVycmFjb3R0YQQJAG5hbWVfaGFzaN09COzMuHwAAwoAbmV0d29ya19pZIWPCzoKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:light_blue_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTVAwAACAQAbmFtZR8AbWluZWNyYWZ0OmxpZ2h0X2JsdWVfdGVycmFjb3R0YQQJAG5hbWVfaGFzaOMytez7cOZiAwoAbmV0d29ya19pZFHK1UsKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:blue_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTdAwAACAQAbmFtZRkAbWluZWNyYWZ0OmJsdWVfdGVycmFjb3R0YQQJAG5hbWVfaGFzaF6inyTK5RpAAwoAbmV0d29ya19pZF5mVZIKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:purple_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTcAwAACAQAbmFtZRsAbWluZWNyYWZ0OnB1cnBsZV90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoKF7YG61yTbEDCgBuZXR3b3JrX2lkhtRDlwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:magenta_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTUAwAACAQAbmFtZRwAbWluZWNyYWZ0Om1hZ2VudGFfdGVycmFjb3R0YQQJAG5hbWVfaGFzaLWvtpAVtztyAwoAbmV0d29ya19pZN5SoakKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:pink_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTYAwAACAQAbmFtZRkAbWluZWNyYWZ0OnBpbmtfdGVycmFjb3R0YQQJAG5hbWVfaGFzaJ7mzvyzSQZTAwoAbmV0d29ya19pZDJWe4YKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:white_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTcAAAACAQAbmFtZSEAbWluZWNyYWZ0OndoaXRlX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoiVzCdoHAJo0DCgBuZXR3b3JrX2lkIlj9AAoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:silver_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTkAAAACAQAbmFtZSIAbWluZWNyYWZ0OnNpbHZlcl9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaAVsA0CnhzA4AwoAbmV0d29ya19pZPnxtJEKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:gray_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTjAAAACAQAbmFtZSAAbWluZWNyYWZ0OmdyYXlfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2jvLZt9u/lF/AMKAG5ldHdvcmtfaWQVU8eFCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:black_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTrAAAACAQAbmFtZSEAbWluZWNyYWZ0OmJsYWNrX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoe8I4xAXbO5UDCgBuZXR3b3JrX2lk2Icb9AoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:brown_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWToAAAACAQAbmFtZSEAbWluZWNyYWZ0OmJyb3duX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoSiNZOobbpjoDCgBuZXR3b3JrX2lkJy0jwgoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:red_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTqAAAACAQAbmFtZR8AbWluZWNyYWZ0OnJlZF9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaBdWFGLmCLFVAwoAbmV0d29ya19pZMYBJSEKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:orange_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTdAAAACAQAbmFtZSIAbWluZWNyYWZ0Om9yYW5nZV9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaMyJMrnPr7szAwoAbmV0d29ya19pZN6+7TUKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:yellow_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTgAAAACAQAbmFtZSIAbWluZWNyYWZ0OnllbGxvd19nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaN6NaIhf6m0uAwoAbmV0d29ya19pZKRHXeoKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:lime_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWThAAAACAQAbmFtZSAAbWluZWNyYWZ0OmxpbWVfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2iF3E68/rB2EAMKAG5ldHdvcmtfaWSP7qQWCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:green_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTpAAAACAQAbmFtZSEAbWluZWNyYWZ0OmdyZWVuX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNow5mo8aQDFboDCgBuZXR3b3JrX2lkoF11kgoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:cyan_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTlAAAACAQAbmFtZSAAbWluZWNyYWZ0OmN5YW5fZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2gnNB+cCFRJhwMKAG5ldHdvcmtfaWT9buMtCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:light_blue_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTfAAAACAQAbmFtZSYAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2gladnCDBKCigMKAG5ldHdvcmtfaWS5CszFCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:blue_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTnAAAACAQAbmFtZSAAbWluZWNyYWZ0OmJsdWVfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2giOZK+2nB1igMKAG5ldHdvcmtfaWR+e22CCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:purple_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTbAAAACAQAbmFtZSIAbWluZWNyYWZ0OnB1cnBsZV9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaIQU03txeAfHAwoAbmV0d29ya19pZLKbSE4KBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:magenta_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTeAAAACAQAbmFtZSMAbWluZWNyYWZ0Om1hZ2VudGFfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2i/SNqDJbfjMgMKAG5ldHdvcmtfaWQKf9UvCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:pink_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTiAAAACAQAbmFtZSAAbWluZWNyYWZ0OnBpbmtfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2hik8DVt4g+twMKAG5ldHdvcmtfaWTKzav2CgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:purpur_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAAAACAQAbmFtZRYAbWluZWNyYWZ0OnB1cnB1cl9ibG9jawQJAG5hbWVfaGFzaAgLwnUZGlzsAwoAbmV0d29ya19pZLD8ox4KBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQcAZGVmYXVsdAgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:purpur_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAAAACAQAbmFtZRYAbWluZWNyYWZ0OnB1cnB1cl9ibG9jawQJAG5hbWVfaGFzaAgLwnUZGlzsAwoAbmV0d29ya19pZPSAFFsKBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQUAbGluZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:packed_mud", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTcAgAACAQAbmFtZRQAbWluZWNyYWZ0OnBhY2tlZF9tdWQECQBuYW1lX2hhc2gHOMa121h4FgMKAG5ldHdvcmtfaWTUb6LyCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:mud_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTaAgAACAQAbmFtZRQAbWluZWNyYWZ0Om11ZF9icmlja3MECQBuYW1lX2hhc2iDL/SVl/PewQMKAG5ldHdvcmtfaWSkBjaDCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:nether_wart_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTWAAAACAQAbmFtZRsAbWluZWNyYWZ0Om5ldGhlcl93YXJ0X2Jsb2NrBAkAbmFtZV9oYXNo9XGS4GNnlV4DCgBuZXR3b3JrX2lkh3apIgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:warped_wart_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTiAQAACAQAbmFtZRsAbWluZWNyYWZ0OndhcnBlZF93YXJ0X2Jsb2NrBAkAbmFtZV9oYXNo9IqDS9yUPJoDCgBuZXR3b3JrX2lkMpKAbAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:shroomlight", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTlAQAACAQAbmFtZRUAbWluZWNyYWZ0OnNocm9vbWxpZ2h0BAkAbmFtZV9oYXNoZHCHcHX/HYADCgBuZXR3b3JrX2lkLG2JiwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:crimson_nylium", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTnAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fbnlsaXVtBAkAbmFtZV9oYXNoOr6DJYW2bFYDCgBuZXR3b3JrX2lkuWpRDgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:warped_nylium", + "block_state_b64": "CgAAAwgAYmxvY2tfaWToAQAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9ueWxpdW0ECQBuYW1lX2hhc2g0Zf89cfr3rwMKAG5ldHdvcmtfaWSu/kekCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:netherrack", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRXAAAACAQAbmFtZRQAbWluZWNyYWZ0Om5ldGhlcnJhY2sECQBuYW1lX2hhc2i/r5ZyRsvPyQMKAG5ldHdvcmtfaWTAiTOACgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:basalt", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTpAQAACAQAbmFtZRAAbWluZWNyYWZ0OmJhc2FsdAQJAG5hbWVfaGFzaH+UQO2yWodiAwoAbmV0d29ya19pZBPNSV4KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:polished_basalt", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTqAQAACAQAbmFtZRkAbWluZWNyYWZ0OnBvbGlzaGVkX2Jhc2FsdAQJAG5hbWVfaGFzaMS+L0gMnRcBAwoAbmV0d29ya19pZF+/mHwKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:smooth_basalt", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR4AgAACAQAbmFtZRcAbWluZWNyYWZ0OnNtb290aF9iYXNhbHQECQBuYW1lX2hhc2jKPUdz89kuNAMKAG5ldHdvcmtfaWTkb/oVCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:soul_soil", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTrAQAACAQAbmFtZRMAbWluZWNyYWZ0OnNvdWxfc29pbAQJAG5hbWVfaGFzaC1/87ccutuTAwoAbmV0d29ya19pZKc63SMKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:dirt", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAAAACAQAbmFtZQ4AbWluZWNyYWZ0OmRpcnQECQBuYW1lX2hhc2hXp6jnXAe+kQMKAG5ldHdvcmtfaWQmkQtoCgYAc3RhdGVzCAkAZGlydF90eXBlBgBub3JtYWwAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:dirt", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAAAACAQAbmFtZQ4AbWluZWNyYWZ0OmRpcnQECQBuYW1lX2hhc2hXp6jnXAe+kQMKAG5ldHdvcmtfaWQId9pLCgYAc3RhdGVzCAkAZGlydF90eXBlBgBjb2Fyc2UAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:farmland", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ8AAAACAQAbmFtZRIAbWluZWNyYWZ0OmZhcm1sYW5kBAkAbmFtZV9oYXNoxyQ5ag7LolADCgBuZXR3b3JrX2lkX618FQoGAHN0YXRlcwMSAG1vaXN0dXJpemVkX2Ftb3VudAAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:grass_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQCAAAACAQAbmFtZRUAbWluZWNyYWZ0OmdyYXNzX2Jsb2NrBAkAbmFtZV9oYXNojPyGp3/CSZwDCgBuZXR3b3JrX2lktCgx3goGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:grass_path", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTGAAAACAQAbmFtZRQAbWluZWNyYWZ0OmdyYXNzX3BhdGgECQBuYW1lX2hhc2i0/KZV8Qsy+gMKAG5ldHdvcmtfaWT7CcdzCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:podzol", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTzAAAACAQAbmFtZRAAbWluZWNyYWZ0OnBvZHpvbAQJAG5hbWVfaGFzaBzqokRjH4Z1AwoAbmV0d29ya19pZPPS/GUKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:mycelium", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRuAAAACAQAbmFtZRIAbWluZWNyYWZ0Om15Y2VsaXVtBAkAbmFtZV9oYXNojTN09cKickIDCgBuZXR3b3JrX2lkLNPxXQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:mud", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTYAgAACAQAbmFtZQ0AbWluZWNyYWZ0Om11ZAQJAG5hbWVfaGFzaPb/3P+uLy+9AwoAbmV0d29ya19pZPIUlUkKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:stone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQBAAAACAQAbmFtZQ8AbWluZWNyYWZ0OnN0b25lBAkAbmFtZV9oYXNoE3mqhJxzJycDCgBuZXR3b3JrX2lkIQ4xgAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:iron_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQPAAAACAQAbmFtZRIAbWluZWNyYWZ0Omlyb25fb3JlBAkAbmFtZV9oYXNoS7BYtLnfx3gDCgBuZXR3b3JrX2lk3loneQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:gold_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQOAAAACAQAbmFtZRIAbWluZWNyYWZ0OmdvbGRfb3JlBAkAbmFtZV9oYXNoC5Y+DUGXLC4DCgBuZXR3b3JrX2lkNhvMfwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:diamond_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ4AAAACAQAbmFtZRUAbWluZWNyYWZ0OmRpYW1vbmRfb3JlBAkAbmFtZV9oYXNokUOJ2wZZrGQDCgBuZXR3b3JrX2lk/dChVAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:lapis_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQVAAAACAQAbmFtZRMAbWluZWNyYWZ0OmxhcGlzX29yZQQJAG5hbWVfaGFzaMrmrUrSzb7qAwoAbmV0d29ya19pZMg+qK4KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:redstone_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRJAAAACAQAbmFtZRYAbWluZWNyYWZ0OnJlZHN0b25lX29yZQQJAG5hbWVfaGFzaFHVnp8Wc4JbAwoAbmV0d29ya19pZKDYvQoKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:coal_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQQAAAACAQAbmFtZRIAbWluZWNyYWZ0OmNvYWxfb3JlBAkAbmFtZV9oYXNo1OjA+Iuy51oDCgBuZXR3b3JrX2lk+R/aKAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:copper_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ2AgAACAQAbmFtZRQAbWluZWNyYWZ0OmNvcHBlcl9vcmUECQBuYW1lX2hhc2iSZduSntOzOwMKAG5ldHdvcmtfaWQtIuCnCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:emerald_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSBAAAACAQAbmFtZRUAbWluZWNyYWZ0OmVtZXJhbGRfb3JlBAkAbmFtZV9oYXNoJTovr+VgINsDCgBuZXR3b3JrX2lknbkqCgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:quartz_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSZAAAACAQAbmFtZRQAbWluZWNyYWZ0OnF1YXJ0el9vcmUECQBuYW1lX2hhc2g0yNHLMK9TaQMKAG5ldHdvcmtfaWSzN7nzCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:nether_gold_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQfAgAACAQAbmFtZRkAbWluZWNyYWZ0Om5ldGhlcl9nb2xkX29yZQQJAG5hbWVfaGFzaEJZ7segIBgBAwoAbmV0d29ya19pZNI9pDgKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:ancient_debris", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQOAgAACAQAbmFtZRgAbWluZWNyYWZ0OmFuY2llbnRfZGVicmlzBAkAbmFtZV9oYXNoNrbxMc9AwKcDCgBuZXR3b3JrX2lkrSNjEAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:deepslate_iron_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSQAgAACAQAbmFtZRwAbWluZWNyYWZ0OmRlZXBzbGF0ZV9pcm9uX29yZQQJAG5hbWVfaGFzaB/fDL9pgvXXAwoAbmV0d29ya19pZFA0bz4KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:deepslate_gold_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAgAACAQAbmFtZRwAbWluZWNyYWZ0OmRlZXBzbGF0ZV9nb2xkX29yZQQJAG5hbWVfaGFzaF9G7WYhKFinAwoAbmV0d29ya19pZHQTfBUKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:deepslate_diamond_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSUAgAACAQAbmFtZR8AbWluZWNyYWZ0OmRlZXBzbGF0ZV9kaWFtb25kX29yZQQJAG5hbWVfaGFzaEUH5USh+iD3AwoAbmV0d29ya19pZHP6VzAKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:deepslate_lapis_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSPAgAACAQAbmFtZR0AbWluZWNyYWZ0OmRlZXBzbGF0ZV9sYXBpc19vcmUECQBuYW1lX2hhc2j+yFxU/KZs1gMKAG5ldHdvcmtfaWRKINzICgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:deepslate_redstone_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSSAgAACAQAbmFtZSAAbWluZWNyYWZ0OmRlZXBzbGF0ZV9yZWRzdG9uZV9vcmUECQBuYW1lX2hhc2iVgM3wWWD6ugMKAG5ldHdvcmtfaWReBdYRCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:deepslate_emerald_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSWAgAACAQAbmFtZR8AbWluZWNyYWZ0OmRlZXBzbGF0ZV9lbWVyYWxkX29yZQQJAG5hbWVfaGFzaNlfo5HTwS6wAwoAbmV0d29ya19pZNeie6sKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:deepslate_coal_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSVAgAACAQAbmFtZRwAbWluZWNyYWZ0OmRlZXBzbGF0ZV9jb2FsX29yZQQJAG5hbWVfaGFzaIjikmcbRrPPAwoAbmV0d29ya19pZD9TiygKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:deepslate_copper_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSXAgAACAQAbmFtZR4AbWluZWNyYWZ0OmRlZXBzbGF0ZV9jb3BwZXJfb3JlBAkAbmFtZV9oYXNottjV4Ev5LAQDCgBuZXR3b3JrX2lkP23rgQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:gravel", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQNAAAACAQAbmFtZRAAbWluZWNyYWZ0OmdyYXZlbAQJAG5hbWVfaGFzaOFxz8XJd2r/AwoAbmV0d29ya19pZBpfI1sKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:granite", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRNAwAACAQAbmFtZREAbWluZWNyYWZ0OmdyYW5pdGUECQBuYW1lX2hhc2iq+Dur2pw4AwMKAG5ldHdvcmtfaWT2NMfJCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:diorite", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRPAwAACAQAbmFtZREAbWluZWNyYWZ0OmRpb3JpdGUECQBuYW1lX2hhc2iaFsq2iinZBQMKAG5ldHdvcmtfaWQqGE6XCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:andesite", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRRAwAACAQAbmFtZRIAbWluZWNyYWZ0OmFuZGVzaXRlBAkAbmFtZV9oYXNosaLIEnQQoSYDCgBuZXR3b3JrX2lkEApRZAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:blackstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQQAgAACAQAbmFtZRQAbWluZWNyYWZ0OmJsYWNrc3RvbmUECQBuYW1lX2hhc2iMFYziD80D6QMKAG5ldHdvcmtfaWSrUryHCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:deepslate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR5AgAACAQAbmFtZRMAbWluZWNyYWZ0OmRlZXBzbGF0ZQQJAG5hbWVfaGFzaKX5pAblxz8TAwoAbmV0d29ya19pZOJoQjsKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:polished_granite", + "block_state_b64": "CgAAAwgAYmxvY2tfaWROAwAACAQAbmFtZRoAbWluZWNyYWZ0OnBvbGlzaGVkX2dyYW5pdGUECQBuYW1lX2hhc2iLiEfys8pFIAMKAG5ldHdvcmtfaWTCxxcHCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:polished_diorite", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRQAwAACAQAbmFtZRoAbWluZWNyYWZ0OnBvbGlzaGVkX2Rpb3JpdGUECQBuYW1lX2hhc2hTxY4fKmNmlAMKAG5ldHdvcmtfaWTmtjdRCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:polished_andesite", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRSAwAACAQAbmFtZRsAbWluZWNyYWZ0OnBvbGlzaGVkX2FuZGVzaXRlBAkAbmFtZV9oYXNovl28uFk4HuQDCgBuZXR3b3JrX2lklFjuCwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:polished_blackstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQiAgAACAQAbmFtZR0AbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmUECQBuYW1lX2hhc2jT9fHCl6vWQQMKAG5ldHdvcmtfaWR/Ho6oCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:polished_deepslate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR+AgAACAQAbmFtZRwAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZQQJAG5hbWVfaGFzaHC1edoaWF3uAwoAbmV0d29ya19pZCPeQsEKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:sand", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQMAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnNhbmQECQBuYW1lX2hhc2i6lthXXbAyWAMKAG5ldHdvcmtfaWTekU/mCgYAc3RhdGVzCAkAc2FuZF90eXBlBgBub3JtYWwAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:sand", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQMAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnNhbmQECQBuYW1lX2hhc2i6lthXXbAyWAMKAG5ldHdvcmtfaWSTgcqmCgYAc3RhdGVzCAkAc2FuZF90eXBlAwByZWQAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:cactus", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRRAAAACAQAbmFtZRAAbWluZWNyYWZ0OmNhY3R1cwQJAG5hbWVfaGFzaCG9zL0N4wvGAwoAbmV0d29ya19pZDeCERAKBgBzdGF0ZXMDAwBhZ2UAAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:oak_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQRAAAACAQAbmFtZREAbWluZWNyYWZ0Om9ha19sb2cECQBuYW1lX2hhc2ho6TS+K7PZFQMKAG5ldHdvcmtfaWQjfjoxCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:stripped_oak_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQJAQAACAQAbmFtZRoAbWluZWNyYWZ0OnN0cmlwcGVkX29ha19sb2cECQBuYW1lX2hhc2h8dqh+OOHU4wMKAG5ldHdvcmtfaWSYKjdrCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:spruce_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ4AwAACAQAbmFtZRQAbWluZWNyYWZ0OnNwcnVjZV9sb2cECQBuYW1lX2hhc2hZ03qaLoF3WgMKAG5ldHdvcmtfaWRlFD8eCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:stripped_spruce_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQEAQAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX3NwcnVjZV9sb2cECQBuYW1lX2hhc2iNrhKjS5IyrgMKAG5ldHdvcmtfaWRQcEC3CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:birch_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ5AwAACAQAbmFtZRMAbWluZWNyYWZ0OmJpcmNoX2xvZwQJAG5hbWVfaGFzaBUzT3NxsZAnAwoAbmV0d29ya19pZBKN3VQKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:stripped_birch_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQFAQAACAQAbmFtZRwAbWluZWNyYWZ0OnN0cmlwcGVkX2JpcmNoX2xvZwQJAG5hbWVfaGFzaCFKS4AeuSidAwoAbmV0d29ya19pZN0IONIKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:jungle_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ6AwAACAQAbmFtZRQAbWluZWNyYWZ0Omp1bmdsZV9sb2cECQBuYW1lX2hhc2gkwW0KNulqDgMKAG5ldHdvcmtfaWQaziU/CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:stripped_jungle_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAQAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2p1bmdsZV9sb2cECQBuYW1lX2hhc2hAwMsgOk02JAMKAG5ldHdvcmtfaWQvls0eCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:acacia_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSiAAAACAQAbmFtZRQAbWluZWNyYWZ0OmFjYWNpYV9sb2cECQBuYW1lX2hhc2iV48VpYhjoYQMKAG5ldHdvcmtfaWRxEqe0CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:stripped_acacia_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQHAQAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2FjYWNpYV9sb2cECQBuYW1lX2hhc2hJb0lQqnEqlgMKAG5ldHdvcmtfaWRg3IdRCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:dark_oak_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ7AwAACAQAbmFtZRYAbWluZWNyYWZ0OmRhcmtfb2FrX2xvZwQJAG5hbWVfaGFzaIWfVRd0XUo3AwoAbmV0d29ya19pZPMM7LYKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:stripped_dark_oak_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQIAQAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX2Rhcmtfb2FrX2xvZwQJAG5hbWVfaGFzaPFTdxRdPwkOAwoAbmV0d29ya19pZDIzenIKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:mangrove_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTjAgAACAQAbmFtZRYAbWluZWNyYWZ0Om1hbmdyb3ZlX2xvZwQJAG5hbWVfaGFzaHZe6DzPZBobAwoAbmV0d29ya19pZG6DuYkKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:stripped_mangrove_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTkAgAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX21hbmdyb3ZlX2xvZwQJAG5hbWVfaGFzaLqIBo4hwA//AwoAbmV0d29ya19pZPtRn7UKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:cherry_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQXAwAACAQAbmFtZRQAbWluZWNyYWZ0OmNoZXJyeV9sb2cECQBuYW1lX2hhc2hwFlaioppB1wMKAG5ldHdvcmtfaWS2sdXECgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:stripped_cherry_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQWAwAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2NoZXJyeV9sb2cECQBuYW1lX2hhc2i85H6G+WhXaAMKAG5ldHdvcmtfaWRjzoglCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:crimson_stem", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTgAQAACAQAbmFtZRYAbWluZWNyYWZ0OmNyaW1zb25fc3RlbQQJAG5hbWVfaGFzaM0FzfL0UTKZAwoAbmV0d29ya19pZKvzID0KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:stripped_crimson_stem", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTvAQAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX2NyaW1zb25fc3RlbQQJAG5hbWVfaGFzaDlA6nood57EAwoAbmV0d29ya19pZHrIqjIKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:warped_stem", + "block_state_b64": "CgAAAwgAYmxvY2tfaWThAQAACAQAbmFtZRUAbWluZWNyYWZ0OndhcnBlZF9zdGVtBAkAbmFtZV9oYXNon7cKfPZxdrUDCgBuZXR3b3JrX2lkerWyMwoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:stripped_warped_stem", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTwAQAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX3dhcnBlZF9zdGVtBAkAbmFtZV9oYXNoEw+y0dDPSd8DCgBuZXR3b3JrX2lkIQ9vBAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:oak_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAQAACAQAbmFtZRIAbWluZWNyYWZ0Om9ha193b29kBAkAbmFtZV9oYXNoqQIkuVPyJX0DCgBuZXR3b3JrX2lku2G1YAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:spruce_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQtBAAACAQAbmFtZRUAbWluZWNyYWZ0OnNwcnVjZV93b29kBAkAbmFtZV9oYXNoTrIJ5TAQ+OgDCgBuZXR3b3JrX2lkaXLxCwoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:birch_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQuBAAACAQAbmFtZRQAbWluZWNyYWZ0OmJpcmNoX3dvb2QECQBuYW1lX2hhc2iqVjG4xt0cKQMKAG5ldHdvcmtfaWS06c5VCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:jungle_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQvBAAACAQAbmFtZRUAbWluZWNyYWZ0Omp1bmdsZV93b29kBAkAbmFtZV9oYXNo9bYW29ORWCoDCgBuZXR3b3JrX2lkyFyKLQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:acacia_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQwBAAACAQAbmFtZRUAbWluZWNyYWZ0OmFjYWNpYV93b29kBAkAbmFtZV9oYXNoKkDfgzlJUcIDCgBuZXR3b3JrX2lkuTWlcgoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:dark_oak_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQxBAAACAQAbmFtZRcAbWluZWNyYWZ0OmRhcmtfb2FrX3dvb2QECQBuYW1lX2hhc2jaKv4ORLadAAMKAG5ldHdvcmtfaWSDrNQ8CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:stripped_oak_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQyBAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0cmlwcGVkX29ha193b29kBAkAbmFtZV9oYXNovW6KCv+VZnsDCgBuZXR3b3JrX2lkkhWGegoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:stripped_spruce_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQzBAAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX3NwcnVjZV93b29kBAkAbmFtZV9oYXNoMnuUk4Xo6icDCgBuZXR3b3JrX2lkes2ydAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:stripped_birch_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ0BAAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2JpcmNoX3dvb2QECQBuYW1lX2hhc2hm88R604TKbAMKAG5ldHdvcmtfaWRleEMJCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:stripped_jungle_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ1BAAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX2p1bmdsZV93b29kBAkAbmFtZV9oYXNoUVs6KsZQRBoDCgBuZXR3b3JrX2lk92k8HQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:stripped_acacia_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ2BAAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX2FjYWNpYV93b29kBAkAbmFtZV9oYXNo/kOPN2bCJhUDCgBuZXR3b3JrX2lktl6LwQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:stripped_dark_oak_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ3BAAACAQAbmFtZSAAbWluZWNyYWZ0OnN0cmlwcGVkX2Rhcmtfb2FrX3dvb2QECQBuYW1lX2hhc2h2jFDfKVFgfAMKAG5ldHdvcmtfaWTgZQ5VCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:mangrove_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTwAgAACAQAbmFtZRcAbWluZWNyYWZ0Om1hbmdyb3ZlX3dvb2QECQBuYW1lX2hhc2iXVxG0JG2fVAMKAG5ldHdvcmtfaWTok1JCCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:stripped_mangrove_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTxAgAACAQAbmFtZSAAbWluZWNyYWZ0OnN0cmlwcGVkX21hbmdyb3ZlX3dvb2QECQBuYW1lX2hhc2h7CkbaBF7/WAMKAG5ldHdvcmtfaWQLAX88CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:cherry_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQhAwAACAQAbmFtZRUAbWluZWNyYWZ0OmNoZXJyeV93b29kBAkAbmFtZV9oYXNoAW8srlmpBM8DCgBuZXR3b3JrX2lkEALMfAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AQwAc3RyaXBwZWRfYml0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:stripped_cherry_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQgAwAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX2NoZXJyeV93b29kBAkAbmFtZV9oYXNo/e7KXv+CB38DCgBuZXR3b3JrX2lkg5aVtQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:crimson_hyphae", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQqAgAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25faHlwaGFlBAkAbmFtZV9oYXNouRmKmfSqEWADCgBuZXR3b3JrX2lk+Tm5rQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:stripped_crimson_hyphae", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQrAgAACAQAbmFtZSEAbWluZWNyYWZ0OnN0cmlwcGVkX2NyaW1zb25faHlwaGFlBAkAbmFtZV9oYXNoFffwmABq4LUDCgBuZXR3b3JrX2lkZAlUbgoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:warped_hyphae", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQpAgAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9oeXBoYWUECQBuYW1lX2hhc2hn8plQUr6pmQMKAG5ldHdvcmtfaWRU2AIBCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:stripped_warped_hyphae", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAgAACAQAbmFtZSAAbWluZWNyYWZ0OnN0cmlwcGVkX3dhcnBlZF9oeXBoYWUECQBuYW1lX2hhc2irKq+HYPSgjQMKAG5ldHdvcmtfaWSbrOPDCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:bamboo_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQOAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJhbWJvb19ibG9jawQJAG5hbWVfaGFzaAbDeur6stIBAwoAbmV0d29ya19pZCJAwn0KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:stripped_bamboo_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQPAwAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX2JhbWJvb19ibG9jawQJAG5hbWVfaGFzaJpwytpZOZM9AwoAbmV0d29ya19pZKuRbNEKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:oak_leaves", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQSAAAACAQAbmFtZRQAbWluZWNyYWZ0Om9ha19sZWF2ZXMECQBuYW1lX2hhc2h6O4xGqA2oKgMKAG5ldHdvcmtfaWT98c59CgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:spruce_leaves", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQfBAAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9sZWF2ZXMECQBuYW1lX2hhc2i9x1CtNAuqZwMKAG5ldHdvcmtfaWSzF7pTCgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:birch_leaves", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQgBAAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX2xlYXZlcwQJAG5hbWVfaGFzaBlAGHaoaLZSAwoAbmV0d29ya19pZOjtvWcKBgBzdGF0ZXMBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:jungle_leaves", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQhBAAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9sZWF2ZXMECQBuYW1lX2hhc2iW1uAH07zGhgMKAG5ldHdvcmtfaWSA5KX0CgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:acacia_leaves", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAAAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9sZWF2ZXMECQBuYW1lX2hhc2iZJf8dAgDRNQMKAG5ldHdvcmtfaWQ/G7VuCgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:dark_oak_leaves", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQiBAAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX2xlYXZlcwQJAG5hbWVfaGFzaCk7rDipWFSjAwoAbmV0d29ya19pZJ2AkbYKBgBzdGF0ZXMBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:mangrove_leaves", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTXAgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX2xlYXZlcwQJAG5hbWVfaGFzaKyI/dWvhEG8AwoAbmV0d29ya19pZPQxCZ8KBgBzdGF0ZXMBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:cherry_leaves", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQjAwAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9sZWF2ZXMECQBuYW1lX2hhc2giTs9ChhYBlQMKAG5ldHdvcmtfaWR8bPpwCgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:azalea_leaves", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRDAgAACAQAbmFtZRcAbWluZWNyYWZ0OmF6YWxlYV9sZWF2ZXMECQBuYW1lX2hhc2iXFhD57wFS7AMKAG5ldHdvcmtfaWTNB/9ECgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:azalea_leaves_flowered", + "block_state_b64": "CgAAAwgAYmxvY2tfaWREAgAACAQAbmFtZSAAbWluZWNyYWZ0OmF6YWxlYV9sZWF2ZXNfZmxvd2VyZWQECQBuYW1lX2hhc2gs8jxlS/pMrwMKAG5ldHdvcmtfaWQ7W4PyCgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:sapling", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAAAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWQmoOEvCgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUDAG9hawADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:sapling", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAAAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWQO8pAmCgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUGAHNwcnVjZQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:sapling", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAAAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWQDHhokCgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUFAGJpcmNoAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:sapling", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAAAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWTdQrcyCgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUGAGp1bmdsZQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:sapling", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAAAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWRCDffNCgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUGAGFjYWNpYQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:sapling", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAAAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWR0BRzPCgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUIAGRhcmtfb2FrAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:mangrove_propagule", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTZAgAACAQAbmFtZRwAbWluZWNyYWZ0Om1hbmdyb3ZlX3Byb3BhZ3VsZQQJAG5hbWVfaGFzaJGeox6hkfLFAwoAbmV0d29ya19pZAIpvpYKBgBzdGF0ZXMBBwBoYW5naW5nAAMPAHByb3BhZ3VsZV9zdGFnZQAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:cherry_sapling", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQiAwAACAQAbmFtZRgAbWluZWNyYWZ0OmNoZXJyeV9zYXBsaW5nBAkAbmFtZV9oYXNoGrPpNMf1LtcDCgBuZXR3b3JrX2lkypakXQoGAHN0YXRlcwEHAGFnZV9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:bee_nest", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTZAQAACAQAbmFtZRIAbWluZWNyYWZ0OmJlZV9uZXN0BAkAbmFtZV9oYXNo2R2WBxUHEZIDCgBuZXR3b3JrX2lkiXWLEAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAADCwBob25leV9sZXZlbAAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:wheat_seeds" + }, + { + "id": "minecraft:pumpkin_seeds" + }, + { + "id": "minecraft:melon_seeds" + }, + { + "id": "minecraft:beetroot_seeds" + }, + { + "id": "minecraft:torchflower_seeds" + }, + { + "id": "minecraft:pitcher_pod" + }, + { + "id": "minecraft:wheat" + }, + { + "id": "minecraft:beetroot" + }, + { + "id": "minecraft:potato" + }, + { + "id": "minecraft:poisonous_potato" + }, + { + "id": "minecraft:carrot" + }, + { + "id": "minecraft:golden_carrot" + }, + { + "id": "minecraft:apple" + }, + { + "id": "minecraft:golden_apple" + }, + { + "id": "minecraft:enchanted_golden_apple" + }, + { + "id": "minecraft:melon_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRnAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1lbG9uX2Jsb2NrBAkAbmFtZV9oYXNoXxSm0iYpAx8DCgBuZXR3b3JrX2lkC9rqygoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:melon_slice" + }, + { + "id": "minecraft:glistering_melon_slice" + }, + { + "id": "minecraft:sweet_berries" + }, + { + "id": "minecraft:glow_berries" + }, + { + "id": "minecraft:pumpkin", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRWAAAACAQAbmFtZREAbWluZWNyYWZ0OnB1bXBraW4ECQBuYW1lX2hhc2gc8A3jaSzWbgMKAG5ldHdvcmtfaWRFGA+xCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:carved_pumpkin", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSaAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNhcnZlZF9wdW1wa2luBAkAbmFtZV9oYXNoPu1T0MJuG90DCgBuZXR3b3JrX2lkXNNn5QoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:lit_pumpkin", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRbAAAACAQAbmFtZRUAbWluZWNyYWZ0OmxpdF9wdW1wa2luBAkAbmFtZV9oYXNo7gWtEm2uPL0DCgBuZXR3b3JrX2lki8sU4AoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:honeycomb" + }, + { + "id": "minecraft:tallgrass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQfAAAACAQAbmFtZRMAbWluZWNyYWZ0OnRhbGxncmFzcwQJAG5hbWVfaGFzaC3PXpAXXYswAwoAbmV0d29ya19pZOh33DMKBgBzdGF0ZXMIDwB0YWxsX2dyYXNzX3R5cGUEAGZlcm4AAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:double_plant", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZMx1sfgKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQQAZmVybgEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:tallgrass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQfAAAACAQAbmFtZRMAbWluZWNyYWZ0OnRhbGxncmFzcwQJAG5hbWVfaGFzaC3PXpAXXYswAwoAbmV0d29ya19pZErptfIKBgBzdGF0ZXMIDwB0YWxsX2dyYXNzX3R5cGUEAHRhbGwAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:double_plant", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZAbadmIKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQUAZ3Jhc3MBDwB1cHBlcl9ibG9ja19iaXQAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:nether_sprouts" + }, + { + "id": "minecraft:fire_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRGAwAACAQAbmFtZRQAbWluZWNyYWZ0OmZpcmVfY29yYWwECQBuYW1lX2hhc2hOHyyECVQVJwMKAG5ldHdvcmtfaWS9vF0UCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:brain_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWREAwAACAQAbmFtZRUAbWluZWNyYWZ0OmJyYWluX2NvcmFsBAkAbmFtZV9oYXNoRiWlLCwA2ycDCgBuZXR3b3JrX2lkrjAuhgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:bubble_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRFAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJ1YmJsZV9jb3JhbAQJAG5hbWVfaGFzaJz6rWnl+v2qAwoAbmV0d29ya19pZImIWy0KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:tube_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSCAQAACAQAbmFtZRQAbWluZWNyYWZ0OnR1YmVfY29yYWwECQBuYW1lX2hhc2iYa8oO/tgk7wMKAG5ldHdvcmtfaWRTfND5CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:horn_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRHAwAACAQAbmFtZRQAbWluZWNyYWZ0Omhvcm5fY29yYWwECQBuYW1lX2hhc2iZnRHjZbnLPgMKAG5ldHdvcmtfaWR+GGp8CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:dead_fire_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRLAwAACAQAbmFtZRkAbWluZWNyYWZ0OmRlYWRfZmlyZV9jb3JhbAQJAG5hbWVfaGFzaEPU6tFy/latAwoAbmV0d29ya19pZNMa7V4KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:dead_brain_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRJAwAACAQAbmFtZRoAbWluZWNyYWZ0OmRlYWRfYnJhaW5fY29yYWwECQBuYW1lX2hhc2j5L6QJCISvzwMKAG5ldHdvcmtfaWQkKzeiCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:dead_bubble_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRKAwAACAQAbmFtZRsAbWluZWNyYWZ0OmRlYWRfYnViYmxlX2NvcmFsBAkAbmFtZV9oYXNoSTOZ/8wpeNYDCgBuZXR3b3JrX2lka6w9DAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:dead_tube_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRIAwAACAQAbmFtZRkAbWluZWNyYWZ0OmRlYWRfdHViZV9jb3JhbAQJAG5hbWVfaGFzaJGjNWhlaIJeAwoAbmV0d29ya19pZO3Z0ygKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:dead_horn_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRMAwAACAQAbmFtZRkAbWluZWNyYWZ0OmRlYWRfaG9ybl9jb3JhbAQJAG5hbWVfaGFzaJBkz3qt+g2cAwoAbmV0d29ya19pZBAN+eYKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAQAACAQAbmFtZRMAbWluZWNyYWZ0OmNvcmFsX2ZhbgQJAG5hbWVfaGFzaAFROjbTm8JzAwoAbmV0d29ya19pZOg7iS4KBgBzdGF0ZXMICwBjb3JhbF9jb2xvcgMAcmVkAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAQAACAQAbmFtZRMAbWluZWNyYWZ0OmNvcmFsX2ZhbgQJAG5hbWVfaGFzaAFROjbTm8JzAwoAbmV0d29ya19pZIDj8HMKBgBzdGF0ZXMICwBjb3JhbF9jb2xvcgQAcGluawMTAGNvcmFsX2Zhbl9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAQAACAQAbmFtZRMAbWluZWNyYWZ0OmNvcmFsX2ZhbgQJAG5hbWVfaGFzaAFROjbTm8JzAwoAbmV0d29ya19pZLCJP0kKBgBzdGF0ZXMICwBjb3JhbF9jb2xvcgYAcHVycGxlAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAQAACAQAbmFtZRMAbWluZWNyYWZ0OmNvcmFsX2ZhbgQJAG5hbWVfaGFzaAFROjbTm8JzAwoAbmV0d29ya19pZFz2ly4KBgBzdGF0ZXMICwBjb3JhbF9jb2xvcgQAYmx1ZQMTAGNvcmFsX2Zhbl9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAQAACAQAbmFtZRMAbWluZWNyYWZ0OmNvcmFsX2ZhbgQJAG5hbWVfaGFzaAFROjbTm8JzAwoAbmV0d29ya19pZE4TgnYKBgBzdGF0ZXMICwBjb3JhbF9jb2xvcgYAeWVsbG93AxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:coral_fan_dead", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNvcmFsX2Zhbl9kZWFkBAkAbmFtZV9oYXNo3kgokLV4uQIDCgBuZXR3b3JrX2lkdhLQzwoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yAwByZWQDEwBjb3JhbF9mYW5fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:coral_fan_dead", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNvcmFsX2Zhbl9kZWFkBAkAbmFtZV9oYXNo3kgokLV4uQIDCgBuZXR3b3JrX2lkSi6srQoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABwaW5rAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:coral_fan_dead", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNvcmFsX2Zhbl9kZWFkBAkAbmFtZV9oYXNo3kgokLV4uQIDCgBuZXR3b3JrX2lkGiGSzAoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgBwdXJwbGUDEwBjb3JhbF9mYW5fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:coral_fan_dead", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNvcmFsX2Zhbl9kZWFkBAkAbmFtZV9oYXNo3kgokLV4uQIDCgBuZXR3b3JrX2lkmvZKOgoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABibHVlAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:coral_fan_dead", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNvcmFsX2Zhbl9kZWFkBAkAbmFtZV9oYXNo3kgokLV4uQIDCgBuZXR3b3JrX2lknLw+4QoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgB5ZWxsb3cDEwBjb3JhbF9mYW5fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:crimson_roots", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTeAQAACAQAbmFtZRcAbWluZWNyYWZ0OmNyaW1zb25fcm9vdHMECQBuYW1lX2hhc2j1fWgQLViv5QMKAG5ldHdvcmtfaWRLh5DXCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:warped_roots", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTfAQAACAQAbmFtZRYAbWluZWNyYWZ0OndhcnBlZF9yb290cwQJAG5hbWVfaGFzaBc3WvbJOLlkAwoAbmV0d29ya19pZNLgDnAKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:yellow_flower", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQlAAAACAQAbmFtZRcAbWluZWNyYWZ0OnllbGxvd19mbG93ZXIECQBuYW1lX2hhc2jWbU1pF0OUGAMKAG5ldHdvcmtfaWQgO3hpCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:red_flower", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWSqsqQGCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUFAHBvcHB5AAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:red_flower", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWTqDajjCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUGAG9yY2hpZAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:red_flower", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWT5CjveCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUGAGFsbGl1bQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:red_flower", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWTORIBJCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUJAGhvdXN0b25pYQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:red_flower", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWTuNhmYCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUJAHR1bGlwX3JlZAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:red_flower", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWT0O4nfCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUMAHR1bGlwX29yYW5nZQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:red_flower", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWTqkthyCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGULAHR1bGlwX3doaXRlAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:red_flower", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWRMbBA7CgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUKAHR1bGlwX3BpbmsAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:red_flower", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWRexMAuCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUFAG94ZXllAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:red_flower", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWQgs7BECgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUKAGNvcm5mbG93ZXIAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:red_flower", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWRvDuNbCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUSAGxpbHlfb2ZfdGhlX3ZhbGxleQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:double_plant", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZOemRt4KBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQkAc3VuZmxvd2VyAQ8AdXBwZXJfYmxvY2tfYml0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:double_plant", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZOFugoEKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQcAc3lyaW5nYQEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:double_plant", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZN4O+/gKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQQAcm9zZQEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:double_plant", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZI3w4GMKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQcAcGFlb25pYQEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:pitcher_plant", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAwAACAQAbmFtZRcAbWluZWNyYWZ0OnBpdGNoZXJfcGxhbnQECQBuYW1lX2hhc2hRJHzsbDH+SQMKAG5ldHdvcmtfaWRnY76VCgYAc3RhdGVzAQ8AdXBwZXJfYmxvY2tfYml0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:pink_petals", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQkAwAACAQAbmFtZRUAbWluZWNyYWZ0OnBpbmtfcGV0YWxzBAkAbmFtZV9oYXNo6DQwN9SwV3QDCgBuZXR3b3JrX2lkNWneGgoGAHN0YXRlcwMGAGdyb3d0aAAAAAAIHABtaW5lY3JhZnQ6Y2FyZGluYWxfZGlyZWN0aW9uBQBzb3V0aAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:wither_rose", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTXAQAACAQAbmFtZRUAbWluZWNyYWZ0OndpdGhlcl9yb3NlBAkAbmFtZV9oYXNoaSKxl3I516gDCgBuZXR3b3JrX2lkATXLPwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:torchflower", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ3AwAACAQAbmFtZRUAbWluZWNyYWZ0OnRvcmNoZmxvd2VyBAkAbmFtZV9oYXNoL+mHtElwbqQDCgBuZXR3b3JrX2lkI34O+AoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:white_dye" + }, + { + "id": "minecraft:light_gray_dye" + }, + { + "id": "minecraft:gray_dye" + }, + { + "id": "minecraft:black_dye" + }, + { + "id": "minecraft:brown_dye" + }, + { + "id": "minecraft:red_dye" + }, + { + "id": "minecraft:orange_dye" + }, + { + "id": "minecraft:yellow_dye" + }, + { + "id": "minecraft:lime_dye" + }, + { + "id": "minecraft:green_dye" + }, + { + "id": "minecraft:cyan_dye" + }, + { + "id": "minecraft:light_blue_dye" + }, + { + "id": "minecraft:blue_dye" + }, + { + "id": "minecraft:purple_dye" + }, + { + "id": "minecraft:magenta_dye" + }, + { + "id": "minecraft:pink_dye" + }, + { + "id": "minecraft:ink_sac" + }, + { + "id": "minecraft:glow_ink_sac" + }, + { + "id": "minecraft:cocoa_beans" + }, + { + "id": "minecraft:lapis_lazuli" + }, + { + "id": "minecraft:bone_meal" + }, + { + "id": "minecraft:vine", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRqAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnZpbmUECQBuYW1lX2hhc2j0Sj8/XeXOLAMKAG5ldHdvcmtfaWSUkDtbCgYAc3RhdGVzAxMAdmluZV9kaXJlY3Rpb25fYml0cwAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:weeping_vines", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTmAQAACAQAbmFtZRcAbWluZWNyYWZ0OndlZXBpbmdfdmluZXMECQBuYW1lX2hhc2jrLgLHkQygiwMKAG5ldHdvcmtfaWQ8NHSJCgYAc3RhdGVzAxEAd2VlcGluZ192aW5lc19hZ2UAAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:twisting_vines", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQeAgAACAQAbmFtZRgAbWluZWNyYWZ0OnR3aXN0aW5nX3ZpbmVzBAkAbmFtZV9oYXNoDYR5QgVUQJADCgBuZXR3b3JrX2lk5kYVIQoGAHN0YXRlcwMSAHR3aXN0aW5nX3ZpbmVzX2FnZQAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:waterlily", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRvAAAACAQAbmFtZRMAbWluZWNyYWZ0OndhdGVybGlseQQJAG5hbWVfaGFzaEHgC4c1SXg0AwoAbmV0d29ya19pZOOerp8KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:seagrass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSBAQAACAQAbmFtZRIAbWluZWNyYWZ0OnNlYWdyYXNzBAkAbmFtZV9oYXNoHSBFtoHdWxIDCgBuZXR3b3JrX2lkd3lhEAoGAHN0YXRlcwgOAHNlYV9ncmFzc190eXBlBwBkZWZhdWx0AAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:kelp" + }, + { + "id": "minecraft:deadbush", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQgAAAACAQAbmFtZRIAbWluZWNyYWZ0OmRlYWRidXNoBAkAbmFtZV9oYXNoPFODe4IScnYDCgBuZXR3b3JrX2lkVfnl+goGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:bamboo", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSiAQAACAQAbmFtZRAAbWluZWNyYWZ0OmJhbWJvbwQJAG5hbWVfaGFzaBgpGmyzhedCAwoAbmV0d29ya19pZIZv1nYKBgBzdGF0ZXMBBwBhZ2VfYml0AAgQAGJhbWJvb19sZWFmX3NpemUJAG5vX2xlYXZlcwgWAGJhbWJvb19zdGFsa190aGlja25lc3MEAHRoaW4AAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:snow", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRQAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnNub3cECQBuYW1lX2hhc2gVHr5XXdETWAMKAG5ldHdvcmtfaWQ0zCeHCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:ice", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRPAAAACAQAbmFtZQ0AbWluZWNyYWZ0OmljZQQJAG5hbWVfaGFzaNF26f+uUT29AwoAbmV0d29ya19pZOUMaQYKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:packed_ice", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSuAAAACAQAbmFtZRQAbWluZWNyYWZ0OnBhY2tlZF9pY2UECQBuYW1lX2hhc2hk4bu123ZrFgMKAG5ldHdvcmtfaWTr/ooaCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:blue_ice", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQKAQAACAQAbmFtZRIAbWluZWNyYWZ0OmJsdWVfaWNlBAkAbmFtZV9oYXNo+EKxYgFhKcgDCgBuZXR3b3JrX2lkxfsA8goGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:snow_layer", + "block_state_b64": "CgAAAwgAYmxvY2tfaWROAAAACAQAbmFtZRQAbWluZWNyYWZ0OnNub3dfbGF5ZXIECQBuYW1lX2hhc2hXka6atMYUCQMKAG5ldHdvcmtfaWRCrIPcCgYAc3RhdGVzAQsAY292ZXJlZF9iaXQAAwYAaGVpZ2h0AAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:pointed_dripstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQzAgAACAQAbmFtZRsAbWluZWNyYWZ0OnBvaW50ZWRfZHJpcHN0b25lBAkAbmFtZV9oYXNoJMISzmHQgt8DCgBuZXR3b3JrX2lkbWrtYgoGAHN0YXRlcwgTAGRyaXBzdG9uZV90aGlja25lc3MDAHRpcAEHAGhhbmdpbmcBAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:dripstone_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ8AgAACAQAbmFtZRkAbWluZWNyYWZ0OmRyaXBzdG9uZV9ibG9jawQJAG5hbWVfaGFzaIIXnEqY77YsAwoAbmV0d29ya19pZMZi2kwKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:moss_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWROAgAACAQAbmFtZRUAbWluZWNyYWZ0Om1vc3NfY2FycGV0BAkAbmFtZV9oYXNo/NEDxRPTshYDCgBuZXR3b3JrX2lkaGG3QwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:moss_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ/AgAACAQAbmFtZRQAbWluZWNyYWZ0Om1vc3NfYmxvY2sECQBuYW1lX2hhc2iovcsPUYX2tgMKAG5ldHdvcmtfaWT3JSbfCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:dirt_with_roots", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ9AgAACAQAbmFtZRkAbWluZWNyYWZ0OmRpcnRfd2l0aF9yb290cwQJAG5hbWVfaGFzaLCNDYPviDCIAwoAbmV0d29ya19pZNCkwzoKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:hanging_roots", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ+AgAACAQAbmFtZRcAbWluZWNyYWZ0Omhhbmdpbmdfcm9vdHMECQBuYW1lX2hhc2jaXn+Y5UZpDAMKAG5ldHdvcmtfaWRU4c2vCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:mangrove_roots", + "block_state_b64": "CgAAAwgAYmxvY2tfaWThAgAACAQAbmFtZRgAbWluZWNyYWZ0Om1hbmdyb3ZlX3Jvb3RzBAkAbmFtZV9oYXNoa786PzQGZ6kDCgBuZXR3b3JrX2lklA0AHgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:muddy_mangrove_roots", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTiAgAACAQAbmFtZR4AbWluZWNyYWZ0Om11ZGR5X21hbmdyb3ZlX3Jvb3RzBAkAbmFtZV9oYXNo9YApdHpo1RkDCgBuZXR3b3JrX2lkH0Oc4woGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:big_dripleaf", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRCAgAACAQAbmFtZRYAbWluZWNyYWZ0OmJpZ19kcmlwbGVhZgQJAG5hbWVfaGFzaGBEhXjo6qSdAwoAbmV0d29ya19pZMETsb8KBgBzdGF0ZXMBEQBiaWdfZHJpcGxlYWZfaGVhZAEIEQBiaWdfZHJpcGxlYWZfdGlsdAQAbm9uZQgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:small_dripleaf_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRPAgAACAQAbmFtZR4AbWluZWNyYWZ0OnNtYWxsX2RyaXBsZWFmX2Jsb2NrBAkAbmFtZV9oYXNojxRAgXP9uWADCgBuZXR3b3JrX2lkozbVPwoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24EAGVhc3QBDwB1cHBlcl9ibG9ja19iaXQBAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:spore_blossom", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRAAgAACAQAbmFtZRcAbWluZWNyYWZ0OnNwb3JlX2Jsb3Nzb20ECQBuYW1lX2hhc2il3U72Gbco2gMKAG5ldHdvcmtfaWSbbbgcCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:azalea", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRQAgAACAQAbmFtZRAAbWluZWNyYWZ0OmF6YWxlYQQJAG5hbWVfaGFzaNyUl+BW9JrBAwoAbmV0d29ya19pZO/XZtQKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:flowering_azalea", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRRAgAACAQAbmFtZRoAbWluZWNyYWZ0OmZsb3dlcmluZ19hemFsZWEECQBuYW1lX2hhc2ie9r33wz8kiwMKAG5ldHdvcmtfaWQ3ij0VCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:glow_lichen", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSaAgAACAQAbmFtZRUAbWluZWNyYWZ0Omdsb3dfbGljaGVuBAkAbmFtZV9oYXNobyPUrIYlo44DCgBuZXR3b3JrX2lkCh8lSAoGAHN0YXRlcwMZAG11bHRpX2ZhY2VfZGlyZWN0aW9uX2JpdHM/AAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:amethyst_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRGAgAACAQAbmFtZRgAbWluZWNyYWZ0OmFtZXRoeXN0X2Jsb2NrBAkAbmFtZV9oYXNob+JK1iiAthcDCgBuZXR3b3JrX2lk8HtpzgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:budding_amethyst", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRHAgAACAQAbmFtZRoAbWluZWNyYWZ0OmJ1ZGRpbmdfYW1ldGh5c3QECQBuYW1lX2hhc2gJvAwfI14fxgMKAG5ldHdvcmtfaWTQYqfACgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:amethyst_cluster", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRIAgAACAQAbmFtZRoAbWluZWNyYWZ0OmFtZXRoeXN0X2NsdXN0ZXIECQBuYW1lX2hhc2jK82S88Jgm8wMKAG5ldHdvcmtfaWSCPMPGCgYAc3RhdGVzCBQAbWluZWNyYWZ0OmJsb2NrX2ZhY2UCAHVwAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:large_amethyst_bud", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRJAgAACAQAbmFtZRwAbWluZWNyYWZ0OmxhcmdlX2FtZXRoeXN0X2J1ZAQJAG5hbWVfaGFzaAHhdpWD+sd5AwoAbmV0d29ya19pZKkQxOcKBgBzdGF0ZXMIFABtaW5lY3JhZnQ6YmxvY2tfZmFjZQIAdXAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:medium_amethyst_bud", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRKAgAACAQAbmFtZR0AbWluZWNyYWZ0Om1lZGl1bV9hbWV0aHlzdF9idWQECQBuYW1lX2hhc2g5lBGtC0DzZQMKAG5ldHdvcmtfaWSYiP4gCgYAc3RhdGVzCBQAbWluZWNyYWZ0OmJsb2NrX2ZhY2UCAHVwAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:small_amethyst_bud", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRLAgAACAQAbmFtZRwAbWluZWNyYWZ0OnNtYWxsX2FtZXRoeXN0X2J1ZAQJAG5hbWVfaGFzaEnb4+q9PO4YAwoAbmV0d29ya19pZGWzxrQKBgBzdGF0ZXMIFABtaW5lY3JhZnQ6YmxvY2tfZmFjZQIAdXAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:tuff", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRMAgAACAQAbmFtZQ4AbWluZWNyYWZ0OnR1ZmYECQBuYW1lX2hhc2h1Rwc1XYsBGwMKAG5ldHdvcmtfaWRwQGn0CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:calcite", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRFAgAACAQAbmFtZREAbWluZWNyYWZ0OmNhbGNpdGUECQBuYW1lX2hhc2ixKLu8ZIdzDQMKAG5ldHdvcmtfaWQlSbJDCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:chicken" + }, + { + "id": "minecraft:porkchop" + }, + { + "id": "minecraft:beef" + }, + { + "id": "minecraft:mutton" + }, + { + "id": "minecraft:rabbit" + }, + { + "id": "minecraft:cod" + }, + { + "id": "minecraft:salmon" + }, + { + "id": "minecraft:tropical_fish" + }, + { + "id": "minecraft:pufferfish" + }, + { + "id": "minecraft:brown_mushroom", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQnAAAACAQAbmFtZRgAbWluZWNyYWZ0OmJyb3duX211c2hyb29tBAkAbmFtZV9oYXNonYw/FO78WDoDCgBuZXR3b3JrX2lkLh1OXAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:red_mushroom", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQoAAAACAQAbmFtZRYAbWluZWNyYWZ0OnJlZF9tdXNocm9vbQQJAG5hbWVfaGFzaPpzJua7669xAwoAbmV0d29ya19pZCvWPYkKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:crimson_fungus", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTjAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fZnVuZ3VzBAkAbmFtZV9oYXNolIcCUuFM2u0DCgBuZXR3b3JrX2lkD2NN0QoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:warped_fungus", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTkAQAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9mdW5ndXMECQBuYW1lX2hhc2gq8bSnRVTAFgMKAG5ldHdvcmtfaWTkwS+rCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:brown_mushroom_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAAAACAQAbmFtZR4AbWluZWNyYWZ0OmJyb3duX211c2hyb29tX2Jsb2NrBAkAbmFtZV9oYXNoIyjnbI6xy9sDCgBuZXR3b3JrX2lkdOMhDAoGAHN0YXRlcwMSAGh1Z2VfbXVzaHJvb21fYml0cw4AAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:red_mushroom_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRkAAAACAQAbmFtZRwAbWluZWNyYWZ0OnJlZF9tdXNocm9vbV9ibG9jawQJAG5hbWVfaGFzaJTTyJbth9M9AwoAbmV0d29ya19pZM+AyboKBgBzdGF0ZXMDEgBodWdlX211c2hyb29tX2JpdHMOAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:brown_mushroom_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAAAACAQAbmFtZR4AbWluZWNyYWZ0OmJyb3duX211c2hyb29tX2Jsb2NrBAkAbmFtZV9oYXNoIyjnbI6xy9sDCgBuZXR3b3JrX2lkbdt3CAoGAHN0YXRlcwMSAGh1Z2VfbXVzaHJvb21fYml0cw8AAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:brown_mushroom_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAAAACAQAbmFtZR4AbWluZWNyYWZ0OmJyb3duX211c2hyb29tX2Jsb2NrBAkAbmFtZV9oYXNoIyjnbI6xy9sDCgBuZXR3b3JrX2lkSrMl9goGAHN0YXRlcwMSAGh1Z2VfbXVzaHJvb21fYml0cwAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:egg" + }, + { + "id": "minecraft:sugar_cane" + }, + { + "id": "minecraft:sugar" + }, + { + "id": "minecraft:rotten_flesh" + }, + { + "id": "minecraft:bone" + }, + { + "id": "minecraft:web", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQeAAAACAQAbmFtZQ0AbWluZWNyYWZ0OndlYgQJAG5hbWVfaGFzaA4GKQCvG4i9AwoAbmV0d29ya19pZApt+jgKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:spider_eye" + }, + { + "id": "minecraft:mob_spawner", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ0AAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vYl9zcGF3bmVyBAkAbmFtZV9oYXNoNwGrCV/Fkh8DCgBuZXR3b3JrX2lkM1wTmgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:end_portal_frame", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR4AAAACAQAbmFtZRoAbWluZWNyYWZ0OmVuZF9wb3J0YWxfZnJhbWUECQBuYW1lX2hhc2gqofyUIjGOpQMKAG5ldHdvcmtfaWRbGHf8CgYAc3RhdGVzARIAZW5kX3BvcnRhbF9leWVfYml0AAgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:monster_egg", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkqXH7RgoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGUFAHN0b25lAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:monster_egg", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkeIBb6QoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGULAGNvYmJsZXN0b25lAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:monster_egg", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkDZ2cFQoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGULAHN0b25lX2JyaWNrAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:monster_egg", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkOR/cTAoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGURAG1vc3N5X3N0b25lX2JyaWNrAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:monster_egg", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkqdwlHAoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGUTAGNyYWNrZWRfc3RvbmVfYnJpY2sAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:monster_egg", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkFqqPggoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGUUAGNoaXNlbGVkX3N0b25lX2JyaWNrAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:infested_deepslate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTFAgAACAQAbmFtZRwAbWluZWNyYWZ0OmluZmVzdGVkX2RlZXBzbGF0ZQQJAG5hbWVfaGFzaICF2VYccxF1AwoAbmV0d29ya19pZDa/624KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:dragon_egg", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR6AAAACAQAbmFtZRQAbWluZWNyYWZ0OmRyYWdvbl9lZ2cECQBuYW1lX2hhc2inMzXrV+/e1wMKAG5ldHdvcmtfaWTgO1yRCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:turtle_egg", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSeAQAACAQAbmFtZRQAbWluZWNyYWZ0OnR1cnRsZV9lZ2cECQBuYW1lX2hhc2iwSRcxOJIJ9gMKAG5ldHdvcmtfaWSIRNUhCgYAc3RhdGVzCA0AY3JhY2tlZF9zdGF0ZQkAbm9fY3JhY2tzCBAAdHVydGxlX2VnZ19jb3VudAcAb25lX2VnZwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:sniffer_egg", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRTAwAACAQAbmFtZRUAbWluZWNyYWZ0OnNuaWZmZXJfZWdnBAkAbmFtZV9oYXNoY1lozc8lPcYDCgBuZXR3b3JrX2lk7yb/2QoGAHN0YXRlcwgNAGNyYWNrZWRfc3RhdGUJAG5vX2NyYWNrcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:frog_spawn", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAgAACAQAbmFtZRQAbWluZWNyYWZ0OmZyb2dfc3Bhd24ECQBuYW1lX2hhc2iWmd7idp3ZZwMKAG5ldHdvcmtfaWRFzJudCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:pearlescent_froglight", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTUAgAACAQAbmFtZR8AbWluZWNyYWZ0OnBlYXJsZXNjZW50X2Zyb2dsaWdodAQJAG5hbWVfaGFzaKkcFRyycYGyAwoAbmV0d29ya19pZJqYakAKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:verdant_froglight", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTVAgAACAQAbmFtZRsAbWluZWNyYWZ0OnZlcmRhbnRfZnJvZ2xpZ2h0BAkAbmFtZV9oYXNoA+eXuTBohrQDCgBuZXR3b3JrX2lkDIVnsQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:ochre_froglight", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTWAgAACAQAbmFtZRkAbWluZWNyYWZ0Om9jaHJlX2Zyb2dsaWdodAQJAG5hbWVfaGFzaMY59kjPe+c3AwoAbmV0d29ya19pZO2TD50KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:chicken_spawn_egg" + }, + { + "id": "minecraft:bee_spawn_egg" + }, + { + "id": "minecraft:cow_spawn_egg" + }, + { + "id": "minecraft:pig_spawn_egg" + }, + { + "id": "minecraft:sheep_spawn_egg" + }, + { + "id": "minecraft:wolf_spawn_egg" + }, + { + "id": "minecraft:polar_bear_spawn_egg" + }, + { + "id": "minecraft:ocelot_spawn_egg" + }, + { + "id": "minecraft:cat_spawn_egg" + }, + { + "id": "minecraft:mooshroom_spawn_egg" + }, + { + "id": "minecraft:bat_spawn_egg" + }, + { + "id": "minecraft:parrot_spawn_egg" + }, + { + "id": "minecraft:rabbit_spawn_egg" + }, + { + "id": "minecraft:llama_spawn_egg" + }, + { + "id": "minecraft:horse_spawn_egg" + }, + { + "id": "minecraft:donkey_spawn_egg" + }, + { + "id": "minecraft:mule_spawn_egg" + }, + { + "id": "minecraft:skeleton_horse_spawn_egg" + }, + { + "id": "minecraft:zombie_horse_spawn_egg" + }, + { + "id": "minecraft:tropical_fish_spawn_egg" + }, + { + "id": "minecraft:cod_spawn_egg" + }, + { + "id": "minecraft:pufferfish_spawn_egg" + }, + { + "id": "minecraft:salmon_spawn_egg" + }, + { + "id": "minecraft:dolphin_spawn_egg" + }, + { + "id": "minecraft:turtle_spawn_egg" + }, + { + "id": "minecraft:panda_spawn_egg" + }, + { + "id": "minecraft:fox_spawn_egg" + }, + { + "id": "minecraft:creeper_spawn_egg" + }, + { + "id": "minecraft:enderman_spawn_egg" + }, + { + "id": "minecraft:silverfish_spawn_egg" + }, + { + "id": "minecraft:skeleton_spawn_egg" + }, + { + "id": "minecraft:wither_skeleton_spawn_egg" + }, + { + "id": "minecraft:stray_spawn_egg" + }, + { + "id": "minecraft:slime_spawn_egg" + }, + { + "id": "minecraft:spider_spawn_egg" + }, + { + "id": "minecraft:zombie_spawn_egg" + }, + { + "id": "minecraft:zombie_pigman_spawn_egg" + }, + { + "id": "minecraft:husk_spawn_egg" + }, + { + "id": "minecraft:drowned_spawn_egg" + }, + { + "id": "minecraft:squid_spawn_egg" + }, + { + "id": "minecraft:glow_squid_spawn_egg" + }, + { + "id": "minecraft:cave_spider_spawn_egg" + }, + { + "id": "minecraft:witch_spawn_egg" + }, + { + "id": "minecraft:guardian_spawn_egg" + }, + { + "id": "minecraft:elder_guardian_spawn_egg" + }, + { + "id": "minecraft:endermite_spawn_egg" + }, + { + "id": "minecraft:magma_cube_spawn_egg" + }, + { + "id": "minecraft:strider_spawn_egg" + }, + { + "id": "minecraft:hoglin_spawn_egg" + }, + { + "id": "minecraft:piglin_spawn_egg" + }, + { + "id": "minecraft:zoglin_spawn_egg" + }, + { + "id": "minecraft:piglin_brute_spawn_egg" + }, + { + "id": "minecraft:goat_spawn_egg" + }, + { + "id": "minecraft:axolotl_spawn_egg" + }, + { + "id": "minecraft:warden_spawn_egg" + }, + { + "id": "minecraft:allay_spawn_egg" + }, + { + "id": "minecraft:frog_spawn_egg" + }, + { + "id": "minecraft:tadpole_spawn_egg" + }, + { + "id": "minecraft:trader_llama_spawn_egg" + }, + { + "id": "minecraft:camel_spawn_egg" + }, + { + "id": "minecraft:ghast_spawn_egg" + }, + { + "id": "minecraft:blaze_spawn_egg" + }, + { + "id": "minecraft:shulker_spawn_egg" + }, + { + "id": "minecraft:vindicator_spawn_egg" + }, + { + "id": "minecraft:evoker_spawn_egg" + }, + { + "id": "minecraft:vex_spawn_egg" + }, + { + "id": "minecraft:villager_spawn_egg" + }, + { + "id": "minecraft:wandering_trader_spawn_egg" + }, + { + "id": "minecraft:zombie_villager_spawn_egg" + }, + { + "id": "minecraft:phantom_spawn_egg" + }, + { + "id": "minecraft:pillager_spawn_egg" + }, + { + "id": "minecraft:ravager_spawn_egg" + }, + { + "id": "minecraft:iron_golem_spawn_egg" + }, + { + "id": "minecraft:snow_golem_spawn_egg" + }, + { + "id": "minecraft:sniffer_spawn_egg" + }, + { + "id": "minecraft:obsidian", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQxAAAACAQAbmFtZRIAbWluZWNyYWZ0Om9ic2lkaWFuBAkAbmFtZV9oYXNoiz4qrb8QjyEDCgBuZXR3b3JrX2lkuqnPpQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:crying_obsidian", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQgAgAACAQAbmFtZRkAbWluZWNyYWZ0OmNyeWluZ19vYnNpZGlhbgQJAG5hbWVfaGFzaKT0JlA7Z1K+AwoAbmV0d29ya19pZCjbPV4KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:bedrock", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQHAAAACAQAbmFtZREAbWluZWNyYWZ0OmJlZHJvY2sECQBuYW1lX2hhc2hWfFrh4LVtxwMKAG5ldHdvcmtfaWT7fKz1CgYAc3RhdGVzAQ4AaW5maW5pYnVybl9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:soul_sand", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNvdWxfc2FuZAQJAG5hbWVfaGFzaMaf+bccu+KTAwoAbmV0d29ya19pZBQSHrMKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:magma", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTVAAAACAQAbmFtZQ8AbWluZWNyYWZ0Om1hZ21hBAkAbmFtZV9oYXNoqyTjKaIsWfYDCgBuZXR3b3JrX2lkyfWAZgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:nether_wart" + }, + { + "id": "minecraft:end_stone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR5AAAACAQAbmFtZRMAbWluZWNyYWZ0OmVuZF9zdG9uZQQJAG5hbWVfaGFzaH1J9jA39GJNAwoAbmV0d29ya19pZFeFQ7UKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:chorus_flower", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTIAAAACAQAbmFtZRcAbWluZWNyYWZ0OmNob3J1c19mbG93ZXIECQBuYW1lX2hhc2iMpSodli5uawMKAG5ldHdvcmtfaWRnd1ZWCgYAc3RhdGVzAwMAYWdlAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:chorus_plant", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTwAAAACAQAbmFtZRYAbWluZWNyYWZ0OmNob3J1c19wbGFudAQJAG5hbWVfaGFzaJhSrmNGKwaMAwoAbmV0d29ya19pZA3uVqMKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:chorus_fruit" + }, + { + "id": "minecraft:popped_chorus_fruit" + }, + { + "id": "minecraft:sponge", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQTAAAACAQAbmFtZRAAbWluZWNyYWZ0OnNwb25nZQQJAG5hbWVfaGFzaLrd2ScYRDMiAwoAbmV0d29ya19pZF01rO0KBgBzdGF0ZXMICwBzcG9uZ2VfdHlwZQMAZHJ5AAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:sponge", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQTAAAACAQAbmFtZRAAbWluZWNyYWZ0OnNwb25nZQQJAG5hbWVfaGFzaLrd2ScYRDMiAwoAbmV0d29ya19pZPiOc4QKBgBzdGF0ZXMICwBzcG9uZ2VfdHlwZQMAd2V0AAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkGnlaAwoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABibHVlAQgAZGVhZF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkSnHuagoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABwaW5rAQgAZGVhZF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkmkHyegoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgBwdXJwbGUBCABkZWFkX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkdpUDxgoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yAwByZWQBCABkZWFkX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkYNWvYgoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgB5ZWxsb3cBCABkZWFkX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkZSxBQgoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABibHVlAQgAZGVhZF9iaXQBAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lklSTVqQoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABwaW5rAQgAZGVhZF9iaXQBAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lk5fTYuQoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgBwdXJwbGUBCABkZWFkX2JpdAEAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkwUjqBAoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yAwByZWQBCABkZWFkX2JpdAEAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkq4iWoQoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgB5ZWxsb3cBCABkZWFkX2JpdAEAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:sculk", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAgAACAQAbmFtZQ8AbWluZWNyYWZ0OnNjdWxrBAkAbmFtZV9oYXNo2Lq7T5yQF8kDCgBuZXR3b3JrX2lkyqUPPgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:sculk_vein", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTKAgAACAQAbmFtZRQAbWluZWNyYWZ0OnNjdWxrX3ZlaW4ECQBuYW1lX2hhc2gJUdhVooV4zwMKAG5ldHdvcmtfaWSUfn1XCgYAc3RhdGVzAxkAbXVsdGlfZmFjZV9kaXJlY3Rpb25fYml0cwAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:sculk_catalyst", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTLAgAACAQAbmFtZRgAbWluZWNyYWZ0OnNjdWxrX2NhdGFseXN0BAkAbmFtZV9oYXNo+gCpbrCHST4DCgBuZXR3b3JrX2lkMJ2n/woGAHN0YXRlcwEFAGJsb29tAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:sculk_shrieker", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTMAgAACAQAbmFtZRgAbWluZWNyYWZ0OnNjdWxrX3Nocmlla2VyBAkAbmFtZV9oYXNo5OXtyObniQ4DCgBuZXR3b3JrX2lkxapoNAoGAHN0YXRlcwEGAGFjdGl2ZQABCgBjYW5fc3VtbW9uAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:sculk_sensor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQyAgAACAQAbmFtZRYAbWluZWNyYWZ0OnNjdWxrX3NlbnNvcgQJAG5hbWVfaGFzaCkmHreeTgNnAwoAbmV0d29ya19pZLj2WPcKBgBzdGF0ZXMDEgBzY3Vsa19zZW5zb3JfcGhhc2UAAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:calibrated_sculk_sensor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRDAwAACAQAbmFtZSEAbWluZWNyYWZ0OmNhbGlicmF0ZWRfc2N1bGtfc2Vuc29yBAkAbmFtZV9oYXNoffAcXXN/iJUDCgBuZXR3b3JrX2lkwOx3QQoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAxIAc2N1bGtfc2Vuc29yX3BoYXNlAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:reinforced_deepslate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTRAgAACAQAbmFtZR4AbWluZWNyYWZ0OnJlaW5mb3JjZWRfZGVlcHNsYXRlBAkAbmFtZV9oYXNoldDmj91EapQDCgBuZXR3b3JrX2lkHIt+aQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:leather_helmet" + }, + { + "id": "minecraft:chainmail_helmet" + }, + { + "id": "minecraft:iron_helmet" + }, + { + "id": "minecraft:golden_helmet" + }, + { + "id": "minecraft:diamond_helmet" + }, + { + "id": "minecraft:netherite_helmet" + }, + { + "id": "minecraft:leather_chestplate" + }, + { + "id": "minecraft:chainmail_chestplate" + }, + { + "id": "minecraft:iron_chestplate" + }, + { + "id": "minecraft:golden_chestplate" + }, + { + "id": "minecraft:diamond_chestplate" + }, + { + "id": "minecraft:netherite_chestplate" + }, + { + "id": "minecraft:leather_leggings" + }, + { + "id": "minecraft:chainmail_leggings" + }, + { + "id": "minecraft:iron_leggings" + }, + { + "id": "minecraft:golden_leggings" + }, + { + "id": "minecraft:diamond_leggings" + }, + { + "id": "minecraft:netherite_leggings" + }, + { + "id": "minecraft:leather_boots" + }, + { + "id": "minecraft:chainmail_boots" + }, + { + "id": "minecraft:iron_boots" + }, + { + "id": "minecraft:golden_boots" + }, + { + "id": "minecraft:diamond_boots" + }, + { + "id": "minecraft:netherite_boots" + }, + { + "id": "minecraft:wooden_sword" + }, + { + "id": "minecraft:stone_sword" + }, + { + "id": "minecraft:iron_sword" + }, + { + "id": "minecraft:golden_sword" + }, + { + "id": "minecraft:diamond_sword" + }, + { + "id": "minecraft:netherite_sword" + }, + { + "id": "minecraft:wooden_axe" + }, + { + "id": "minecraft:stone_axe" + }, + { + "id": "minecraft:iron_axe" + }, + { + "id": "minecraft:golden_axe" + }, + { + "id": "minecraft:diamond_axe" + }, + { + "id": "minecraft:netherite_axe" + }, + { + "id": "minecraft:wooden_pickaxe" + }, + { + "id": "minecraft:stone_pickaxe" + }, + { + "id": "minecraft:iron_pickaxe" + }, + { + "id": "minecraft:golden_pickaxe" + }, + { + "id": "minecraft:diamond_pickaxe" + }, + { + "id": "minecraft:netherite_pickaxe" + }, + { + "id": "minecraft:wooden_shovel" + }, + { + "id": "minecraft:stone_shovel" + }, + { + "id": "minecraft:iron_shovel" + }, + { + "id": "minecraft:golden_shovel" + }, + { + "id": "minecraft:diamond_shovel" + }, + { + "id": "minecraft:netherite_shovel" + }, + { + "id": "minecraft:wooden_hoe" + }, + { + "id": "minecraft:stone_hoe" + }, + { + "id": "minecraft:iron_hoe" + }, + { + "id": "minecraft:golden_hoe" + }, + { + "id": "minecraft:diamond_hoe" + }, + { + "id": "minecraft:netherite_hoe" + }, + { + "id": "minecraft:bow" + }, + { + "id": "minecraft:crossbow" + }, + { + "id": "minecraft:arrow" + }, + { + "id": "minecraft:arrow", + "damage": 6 + }, + { + "id": "minecraft:arrow", + "damage": 7 + }, + { + "id": "minecraft:arrow", + "damage": 8 + }, + { + "id": "minecraft:arrow", + "damage": 9 + }, + { + "id": "minecraft:arrow", + "damage": 10 + }, + { + "id": "minecraft:arrow", + "damage": 11 + }, + { + "id": "minecraft:arrow", + "damage": 12 + }, + { + "id": "minecraft:arrow", + "damage": 13 + }, + { + "id": "minecraft:arrow", + "damage": 14 + }, + { + "id": "minecraft:arrow", + "damage": 15 + }, + { + "id": "minecraft:arrow", + "damage": 16 + }, + { + "id": "minecraft:arrow", + "damage": 17 + }, + { + "id": "minecraft:arrow", + "damage": 18 + }, + { + "id": "minecraft:arrow", + "damage": 19 + }, + { + "id": "minecraft:arrow", + "damage": 20 + }, + { + "id": "minecraft:arrow", + "damage": 21 + }, + { + "id": "minecraft:arrow", + "damage": 22 + }, + { + "id": "minecraft:arrow", + "damage": 23 + }, + { + "id": "minecraft:arrow", + "damage": 24 + }, + { + "id": "minecraft:arrow", + "damage": 25 + }, + { + "id": "minecraft:arrow", + "damage": 26 + }, + { + "id": "minecraft:arrow", + "damage": 27 + }, + { + "id": "minecraft:arrow", + "damage": 28 + }, + { + "id": "minecraft:arrow", + "damage": 29 + }, + { + "id": "minecraft:arrow", + "damage": 30 + }, + { + "id": "minecraft:arrow", + "damage": 31 + }, + { + "id": "minecraft:arrow", + "damage": 32 + }, + { + "id": "minecraft:arrow", + "damage": 33 + }, + { + "id": "minecraft:arrow", + "damage": 34 + }, + { + "id": "minecraft:arrow", + "damage": 35 + }, + { + "id": "minecraft:arrow", + "damage": 36 + }, + { + "id": "minecraft:arrow", + "damage": 37 + }, + { + "id": "minecraft:arrow", + "damage": 38 + }, + { + "id": "minecraft:arrow", + "damage": 39 + }, + { + "id": "minecraft:arrow", + "damage": 40 + }, + { + "id": "minecraft:arrow", + "damage": 41 + }, + { + "id": "minecraft:arrow", + "damage": 42 + }, + { + "id": "minecraft:arrow", + "damage": 43 + }, + { + "id": "minecraft:shield" + }, + { + "id": "minecraft:cooked_chicken" + }, + { + "id": "minecraft:cooked_porkchop" + }, + { + "id": "minecraft:cooked_beef" + }, + { + "id": "minecraft:cooked_mutton" + }, + { + "id": "minecraft:cooked_rabbit" + }, + { + "id": "minecraft:cooked_cod" + }, + { + "id": "minecraft:cooked_salmon" + }, + { + "id": "minecraft:bread" + }, + { + "id": "minecraft:mushroom_stew" + }, + { + "id": "minecraft:beetroot_soup" + }, + { + "id": "minecraft:rabbit_stew" + }, + { + "id": "minecraft:baked_potato" + }, + { + "id": "minecraft:cookie" + }, + { + "id": "minecraft:pumpkin_pie" + }, + { + "id": "minecraft:cake" + }, + { + "id": "minecraft:dried_kelp" + }, + { + "id": "minecraft:fishing_rod" + }, + { + "id": "minecraft:carrot_on_a_stick" + }, + { + "id": "minecraft:warped_fungus_on_a_stick" + }, + { + "id": "minecraft:snowball" + }, + { + "id": "minecraft:shears" + }, + { + "id": "minecraft:flint_and_steel" + }, + { + "id": "minecraft:lead" + }, + { + "id": "minecraft:clock" + }, + { + "id": "minecraft:compass" + }, + { + "id": "minecraft:recovery_compass" + }, + { + "id": "minecraft:goat_horn" + }, + { + "id": "minecraft:goat_horn", + "damage": 1 + }, + { + "id": "minecraft:goat_horn", + "damage": 2 + }, + { + "id": "minecraft:goat_horn", + "damage": 3 + }, + { + "id": "minecraft:goat_horn", + "damage": 4 + }, + { + "id": "minecraft:goat_horn", + "damage": 5 + }, + { + "id": "minecraft:goat_horn", + "damage": 6 + }, + { + "id": "minecraft:goat_horn", + "damage": 7 + }, + { + "id": "minecraft:empty_map" + }, + { + "id": "minecraft:empty_map", + "damage": 2 + }, + { + "id": "minecraft:saddle" + }, + { + "id": "minecraft:leather_horse_armor" + }, + { + "id": "minecraft:iron_horse_armor" + }, + { + "id": "minecraft:golden_horse_armor" + }, + { + "id": "minecraft:diamond_horse_armor" + }, + { + "id": "minecraft:trident" + }, + { + "id": "minecraft:turtle_helmet" + }, + { + "id": "minecraft:elytra" + }, + { + "id": "minecraft:totem_of_undying" + }, + { + "id": "minecraft:glass_bottle" + }, + { + "id": "minecraft:experience_bottle" + }, + { + "id": "minecraft:potion" + }, + { + "id": "minecraft:potion", + "damage": 1 + }, + { + "id": "minecraft:potion", + "damage": 2 + }, + { + "id": "minecraft:potion", + "damage": 3 + }, + { + "id": "minecraft:potion", + "damage": 4 + }, + { + "id": "minecraft:potion", + "damage": 5 + }, + { + "id": "minecraft:potion", + "damage": 6 + }, + { + "id": "minecraft:potion", + "damage": 7 + }, + { + "id": "minecraft:potion", + "damage": 8 + }, + { + "id": "minecraft:potion", + "damage": 9 + }, + { + "id": "minecraft:potion", + "damage": 10 + }, + { + "id": "minecraft:potion", + "damage": 11 + }, + { + "id": "minecraft:potion", + "damage": 12 + }, + { + "id": "minecraft:potion", + "damage": 13 + }, + { + "id": "minecraft:potion", + "damage": 14 + }, + { + "id": "minecraft:potion", + "damage": 15 + }, + { + "id": "minecraft:potion", + "damage": 16 + }, + { + "id": "minecraft:potion", + "damage": 17 + }, + { + "id": "minecraft:potion", + "damage": 18 + }, + { + "id": "minecraft:potion", + "damage": 19 + }, + { + "id": "minecraft:potion", + "damage": 20 + }, + { + "id": "minecraft:potion", + "damage": 21 + }, + { + "id": "minecraft:potion", + "damage": 22 + }, + { + "id": "minecraft:potion", + "damage": 23 + }, + { + "id": "minecraft:potion", + "damage": 24 + }, + { + "id": "minecraft:potion", + "damage": 25 + }, + { + "id": "minecraft:potion", + "damage": 26 + }, + { + "id": "minecraft:potion", + "damage": 27 + }, + { + "id": "minecraft:potion", + "damage": 28 + }, + { + "id": "minecraft:potion", + "damage": 29 + }, + { + "id": "minecraft:potion", + "damage": 30 + }, + { + "id": "minecraft:potion", + "damage": 31 + }, + { + "id": "minecraft:potion", + "damage": 32 + }, + { + "id": "minecraft:potion", + "damage": 33 + }, + { + "id": "minecraft:potion", + "damage": 34 + }, + { + "id": "minecraft:potion", + "damage": 35 + }, + { + "id": "minecraft:potion", + "damage": 36 + }, + { + "id": "minecraft:potion", + "damage": 37 + }, + { + "id": "minecraft:potion", + "damage": 38 + }, + { + "id": "minecraft:potion", + "damage": 39 + }, + { + "id": "minecraft:potion", + "damage": 40 + }, + { + "id": "minecraft:potion", + "damage": 41 + }, + { + "id": "minecraft:potion", + "damage": 42 + }, + { + "id": "minecraft:splash_potion" + }, + { + "id": "minecraft:splash_potion", + "damage": 1 + }, + { + "id": "minecraft:splash_potion", + "damage": 2 + }, + { + "id": "minecraft:splash_potion", + "damage": 3 + }, + { + "id": "minecraft:splash_potion", + "damage": 4 + }, + { + "id": "minecraft:splash_potion", + "damage": 5 + }, + { + "id": "minecraft:splash_potion", + "damage": 6 + }, + { + "id": "minecraft:splash_potion", + "damage": 7 + }, + { + "id": "minecraft:splash_potion", + "damage": 8 + }, + { + "id": "minecraft:splash_potion", + "damage": 9 + }, + { + "id": "minecraft:splash_potion", + "damage": 10 + }, + { + "id": "minecraft:splash_potion", + "damage": 11 + }, + { + "id": "minecraft:splash_potion", + "damage": 12 + }, + { + "id": "minecraft:splash_potion", + "damage": 13 + }, + { + "id": "minecraft:splash_potion", + "damage": 14 + }, + { + "id": "minecraft:splash_potion", + "damage": 15 + }, + { + "id": "minecraft:splash_potion", + "damage": 16 + }, + { + "id": "minecraft:splash_potion", + "damage": 17 + }, + { + "id": "minecraft:splash_potion", + "damage": 18 + }, + { + "id": "minecraft:splash_potion", + "damage": 19 + }, + { + "id": "minecraft:splash_potion", + "damage": 20 + }, + { + "id": "minecraft:splash_potion", + "damage": 21 + }, + { + "id": "minecraft:splash_potion", + "damage": 22 + }, + { + "id": "minecraft:splash_potion", + "damage": 23 + }, + { + "id": "minecraft:splash_potion", + "damage": 24 + }, + { + "id": "minecraft:splash_potion", + "damage": 25 + }, + { + "id": "minecraft:splash_potion", + "damage": 26 + }, + { + "id": "minecraft:splash_potion", + "damage": 27 + }, + { + "id": "minecraft:splash_potion", + "damage": 28 + }, + { + "id": "minecraft:splash_potion", + "damage": 29 + }, + { + "id": "minecraft:splash_potion", + "damage": 30 + }, + { + "id": "minecraft:splash_potion", + "damage": 31 + }, + { + "id": "minecraft:splash_potion", + "damage": 32 + }, + { + "id": "minecraft:splash_potion", + "damage": 33 + }, + { + "id": "minecraft:splash_potion", + "damage": 34 + }, + { + "id": "minecraft:splash_potion", + "damage": 35 + }, + { + "id": "minecraft:splash_potion", + "damage": 36 + }, + { + "id": "minecraft:splash_potion", + "damage": 37 + }, + { + "id": "minecraft:splash_potion", + "damage": 38 + }, + { + "id": "minecraft:splash_potion", + "damage": 39 + }, + { + "id": "minecraft:splash_potion", + "damage": 40 + }, + { + "id": "minecraft:splash_potion", + "damage": 41 + }, + { + "id": "minecraft:splash_potion", + "damage": 42 + }, + { + "id": "minecraft:lingering_potion" + }, + { + "id": "minecraft:lingering_potion", + "damage": 1 + }, + { + "id": "minecraft:lingering_potion", + "damage": 2 + }, + { + "id": "minecraft:lingering_potion", + "damage": 3 + }, + { + "id": "minecraft:lingering_potion", + "damage": 4 + }, + { + "id": "minecraft:lingering_potion", + "damage": 5 + }, + { + "id": "minecraft:lingering_potion", + "damage": 6 + }, + { + "id": "minecraft:lingering_potion", + "damage": 7 + }, + { + "id": "minecraft:lingering_potion", + "damage": 8 + }, + { + "id": "minecraft:lingering_potion", + "damage": 9 + }, + { + "id": "minecraft:lingering_potion", + "damage": 10 + }, + { + "id": "minecraft:lingering_potion", + "damage": 11 + }, + { + "id": "minecraft:lingering_potion", + "damage": 12 + }, + { + "id": "minecraft:lingering_potion", + "damage": 13 + }, + { + "id": "minecraft:lingering_potion", + "damage": 14 + }, + { + "id": "minecraft:lingering_potion", + "damage": 15 + }, + { + "id": "minecraft:lingering_potion", + "damage": 16 + }, + { + "id": "minecraft:lingering_potion", + "damage": 17 + }, + { + "id": "minecraft:lingering_potion", + "damage": 18 + }, + { + "id": "minecraft:lingering_potion", + "damage": 19 + }, + { + "id": "minecraft:lingering_potion", + "damage": 20 + }, + { + "id": "minecraft:lingering_potion", + "damage": 21 + }, + { + "id": "minecraft:lingering_potion", + "damage": 22 + }, + { + "id": "minecraft:lingering_potion", + "damage": 23 + }, + { + "id": "minecraft:lingering_potion", + "damage": 24 + }, + { + "id": "minecraft:lingering_potion", + "damage": 25 + }, + { + "id": "minecraft:lingering_potion", + "damage": 26 + }, + { + "id": "minecraft:lingering_potion", + "damage": 27 + }, + { + "id": "minecraft:lingering_potion", + "damage": 28 + }, + { + "id": "minecraft:lingering_potion", + "damage": 29 + }, + { + "id": "minecraft:lingering_potion", + "damage": 30 + }, + { + "id": "minecraft:lingering_potion", + "damage": 31 + }, + { + "id": "minecraft:lingering_potion", + "damage": 32 + }, + { + "id": "minecraft:lingering_potion", + "damage": 33 + }, + { + "id": "minecraft:lingering_potion", + "damage": 34 + }, + { + "id": "minecraft:lingering_potion", + "damage": 35 + }, + { + "id": "minecraft:lingering_potion", + "damage": 36 + }, + { + "id": "minecraft:lingering_potion", + "damage": 37 + }, + { + "id": "minecraft:lingering_potion", + "damage": 38 + }, + { + "id": "minecraft:lingering_potion", + "damage": 39 + }, + { + "id": "minecraft:lingering_potion", + "damage": 40 + }, + { + "id": "minecraft:lingering_potion", + "damage": 41 + }, + { + "id": "minecraft:lingering_potion", + "damage": 42 + }, + { + "id": "minecraft:spyglass" + }, + { + "id": "minecraft:brush" + }, + { + "id": "minecraft:stick" + }, + { + "id": "minecraft:bed" + }, + { + "id": "minecraft:bed", + "damage": 8 + }, + { + "id": "minecraft:bed", + "damage": 7 + }, + { + "id": "minecraft:bed", + "damage": 15 + }, + { + "id": "minecraft:bed", + "damage": 12 + }, + { + "id": "minecraft:bed", + "damage": 14 + }, + { + "id": "minecraft:bed", + "damage": 1 + }, + { + "id": "minecraft:bed", + "damage": 4 + }, + { + "id": "minecraft:bed", + "damage": 5 + }, + { + "id": "minecraft:bed", + "damage": 13 + }, + { + "id": "minecraft:bed", + "damage": 9 + }, + { + "id": "minecraft:bed", + "damage": 3 + }, + { + "id": "minecraft:bed", + "damage": 11 + }, + { + "id": "minecraft:bed", + "damage": 10 + }, + { + "id": "minecraft:bed", + "damage": 2 + }, + { + "id": "minecraft:bed", + "damage": 6 + }, + { + "id": "minecraft:torch", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQyAAAACAQAbmFtZQ8AbWluZWNyYWZ0OnRvcmNoBAkAbmFtZV9oYXNoagn7rmDBzisDCgBuZXR3b3JrX2lk+BwwuQoGAHN0YXRlcwgWAHRvcmNoX2ZhY2luZ19kaXJlY3Rpb24HAHVua25vd24AAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:soul_torch", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQLAgAACAQAbmFtZRQAbWluZWNyYWZ0OnNvdWxfdG9yY2gECQBuYW1lX2hhc2huixOT04BRdQMKAG5ldHdvcmtfaWShbFILCgYAc3RhdGVzCBYAdG9yY2hfZmFjaW5nX2RpcmVjdGlvbgcAdW5rbm93bgADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:sea_pickle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAQAACAQAbmFtZRQAbWluZWNyYWZ0OnNlYV9waWNrbGUECQBuYW1lX2hhc2iONEfZJB+glgMKAG5ldHdvcmtfaWSINWQyCgYAc3RhdGVzAw0AY2x1c3Rlcl9jb3VudAAAAAABCABkZWFkX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:lantern", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTPAQAACAQAbmFtZREAbWluZWNyYWZ0OmxhbnRlcm4ECQBuYW1lX2hhc2hMw44VI2HWygMKAG5ldHdvcmtfaWRkjQvzCgYAc3RhdGVzAQcAaGFuZ2luZwAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:soul_lantern", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQMAgAACAQAbmFtZRYAbWluZWNyYWZ0OnNvdWxfbGFudGVybgQJAG5hbWVfaGFzaGjIpjxk9z+RAwoAbmV0d29ya19pZGfoP8cKBgBzdGF0ZXMBBwBoYW5naW5nAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAgAACAQAbmFtZRAAbWluZWNyYWZ0OmNhbmRsZQQJAG5hbWVfaGFzaHPd+MsNdWTfAwoAbmV0d29ya19pZHsBMA0KBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:white_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWScAgAACAQAbmFtZRYAbWluZWNyYWZ0OndoaXRlX2NhbmRsZQQJAG5hbWVfaGFzaN1EG5Q1mHiEAwoAbmV0d29ya19pZKN1mmgKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:orange_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSdAgAACAQAbmFtZRcAbWluZWNyYWZ0Om9yYW5nZV9jYW5kbGUECQBuYW1lX2hhc2jySEVWHgUIHQMKAG5ldHdvcmtfaWSfVz82CgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:magenta_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSeAgAACAQAbmFtZRgAbWluZWNyYWZ0Om1hZ2VudGFfY2FuZGxlBAkAbmFtZV9oYXNoG0u6YIOoBSEDCgBuZXR3b3JrX2lk9xGNkQoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:light_blue_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSfAgAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY2FuZGxlBAkAbmFtZV9oYXNocXGeK0zgrG0DCgBuZXR3b3JrX2lk2m1y8goGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:yellow_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSgAgAACAQAbmFtZRcAbWluZWNyYWZ0OnllbGxvd19jYW5kbGUECQBuYW1lX2hhc2i00dtusU3CqQMKAG5ldHdvcmtfaWR9LTmpCgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:lime_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAgAACAQAbmFtZRUAbWluZWNyYWZ0OmxpbWVfY2FuZGxlBAkAbmFtZV9oYXNokcmrw5xvz7ADCgBuZXR3b3JrX2lkIAUu6QoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:pink_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSiAgAACAQAbmFtZRUAbWluZWNyYWZ0OnBpbmtfY2FuZGxlBAkAbmFtZV9oYXNoQJdEY4sZ0dwDCgBuZXR3b3JrX2lk23Rn5AoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:gray_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSjAgAACAQAbmFtZRUAbWluZWNyYWZ0OmdyYXlfY2FuZGxlBAkAbmFtZV9oYXNoS5poSo9wBDEDCgBuZXR3b3JrX2lk3trRCAoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:light_gray_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSkAgAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY2FuZGxlBAkAbmFtZV9oYXNo9ruTZLBNMasDCgBuZXR3b3JrX2lkb6DOegoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:cyan_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAgAACAQAbmFtZRUAbWluZWNyYWZ0OmN5YW5fY2FuZGxlBAkAbmFtZV9oYXNoc/M8PNVcjOwDCgBuZXR3b3JrX2lkZoIQOQoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:purple_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSmAgAACAQAbmFtZRcAbWluZWNyYWZ0OnB1cnBsZV9jYW5kbGUECQBuYW1lX2hhc2jaI3xUW0/myQMKAG5ldHdvcmtfaWSnLI2BCgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:blue_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSnAgAACAQAbmFtZRUAbWluZWNyYWZ0OmJsdWVfY2FuZGxlBAkAbmFtZV9oYXNoAASSPW6TgQADCgBuZXR3b3JrX2lkrxrjQAoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:brown_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAgAACAQAbmFtZRYAbWluZWNyYWZ0OmJyb3duX2NhbmRsZQQJAG5hbWVfaGFzaDia0l6s1+WYAwoAbmV0d29ya19pZKSkBXYKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:green_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSpAgAACAQAbmFtZRYAbWluZWNyYWZ0OmdyZWVuX2NhbmRsZQQJAG5hbWVfaGFzaLeFPO1l+fIoAwoAbmV0d29ya19pZBkznDsKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:red_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSqAgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9jYW5kbGUECQBuYW1lX2hhc2jjAQpGf59ZdwMKAG5ldHdvcmtfaWRbb88GCgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:black_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSrAgAACAQAbmFtZRYAbWluZWNyYWZ0OmJsYWNrX2NhbmRsZQQJAG5hbWVfaGFzaB+wRDpOqREKAwoAbmV0d29ya19pZNnOnuEKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:crafting_table", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ6AAAACAQAbmFtZRgAbWluZWNyYWZ0OmNyYWZ0aW5nX3RhYmxlBAkAbmFtZV9oYXNoe76VAmjvbpYDCgBuZXR3b3JrX2lkwCxwaAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:cartography_table", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTHAQAACAQAbmFtZRsAbWluZWNyYWZ0OmNhcnRvZ3JhcGh5X3RhYmxlBAkAbmFtZV9oYXNomaWiiD/znP8DCgBuZXR3b3JrX2lkI6FzMwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:fletching_table", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTIAQAACAQAbmFtZRkAbWluZWNyYWZ0OmZsZXRjaGluZ190YWJsZQQJAG5hbWVfaGFzaPFibh8unKyUAwoAbmV0d29ya19pZJ2mW0oKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:smithing_table", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAQAACAQAbmFtZRgAbWluZWNyYWZ0OnNtaXRoaW5nX3RhYmxlBAkAbmFtZV9oYXNo4tFES2xOXEYDCgBuZXR3b3JrX2lkXWMBzQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:beehive", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTaAQAACAQAbmFtZREAbWluZWNyYWZ0OmJlZWhpdmUECQBuYW1lX2hhc2hCcqn12UbNpwMKAG5ldHdvcmtfaWR/idcaCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAMLAGhvbmV5X2xldmVsAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:suspicious_sand", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQQAwAACAQAbmFtZRkAbWluZWNyYWZ0OnN1c3BpY2lvdXNfc2FuZAQJAG5hbWVfaGFzaL67QsuvLP00AwoAbmV0d29ya19pZKnkaIAKBgBzdGF0ZXMDEABicnVzaGVkX3Byb2dyZXNzAAAAAAEHAGhhbmdpbmcBAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:suspicious_gravel", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ8AwAACAQAbmFtZRsAbWluZWNyYWZ0OnN1c3BpY2lvdXNfZ3JhdmVsBAkAbmFtZV9oYXNoJSVbGNk7C3oDCgBuZXR3b3JrX2lkvIEJAAoGAHN0YXRlcwMQAGJydXNoZWRfcHJvZ3Jlc3MAAAAAAQcAaGFuZ2luZwEAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:campfire" + }, + { + "id": "minecraft:soul_campfire" + }, + { + "id": "minecraft:furnace", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ9AAAACAQAbmFtZREAbWluZWNyYWZ0OmZ1cm5hY2UECQBuYW1lX2hhc2ioOQrludYY8wMKAG5ldHdvcmtfaWRZxnDOCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:blast_furnace", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTDAQAACAQAbmFtZRcAbWluZWNyYWZ0OmJsYXN0X2Z1cm5hY2UECQBuYW1lX2hhc2ivDbnjkpGm5QMKAG5ldHdvcmtfaWTcEbV/CgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:smoker", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTFAQAACAQAbmFtZRAAbWluZWNyYWZ0OnNtb2tlcgQJAG5hbWVfaGFzaJd1rDMkRWomAwoAbmV0d29ya19pZGWswMwKBgBzdGF0ZXMIHABtaW5lY3JhZnQ6Y2FyZGluYWxfZGlyZWN0aW9uBQBzb3V0aAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:respawn_anchor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQPAgAACAQAbmFtZRgAbWluZWNyYWZ0OnJlc3Bhd25fYW5jaG9yBAkAbmFtZV9oYXNoZOdcjW05qigDCgBuZXR3b3JrX2lkmhMcaQoGAHN0YXRlcwMVAHJlc3Bhd25fYW5jaG9yX2NoYXJnZQAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:brewing_stand" + }, + { + "id": "minecraft:anvil", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmFudmlsBAkAbmFtZV9oYXNoNqB3fgcUCbwDCgBuZXR3b3JrX2lk8Z3VowoGAHN0YXRlcwgGAGRhbWFnZQkAdW5kYW1hZ2VkCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:anvil", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmFudmlsBAkAbmFtZV9oYXNoNqB3fgcUCbwDCgBuZXR3b3JrX2lkpiv8BAoGAHN0YXRlcwgGAGRhbWFnZRAAc2xpZ2h0bHlfZGFtYWdlZAgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:anvil", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmFudmlsBAkAbmFtZV9oYXNoNqB3fgcUCbwDCgBuZXR3b3JrX2lkFu+pdwoGAHN0YXRlcwgGAGRhbWFnZQwAdmVyeV9kYW1hZ2VkCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:grindstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTCAQAACAQAbmFtZRQAbWluZWNyYWZ0OmdyaW5kc3RvbmUECQBuYW1lX2hhc2id56zc0nk99wMKAG5ldHdvcmtfaWS4Es07CgYAc3RhdGVzCAoAYXR0YWNobWVudAgAc3RhbmRpbmcDCQBkaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:enchanting_table", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR0AAAACAQAbmFtZRoAbWluZWNyYWZ0OmVuY2hhbnRpbmdfdGFibGUECQBuYW1lX2hhc2jgIx24VLvMvwMKAG5ldHdvcmtfaWRliFFJCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:bookshelf", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQvAAAACAQAbmFtZRMAbWluZWNyYWZ0OmJvb2tzaGVsZgQJAG5hbWVfaGFzaDU04DrgJCS9AwoAbmV0d29ya19pZBcWwIwKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:chiseled_bookshelf", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQNAwAACAQAbmFtZRwAbWluZWNyYWZ0OmNoaXNlbGVkX2Jvb2tzaGVsZgQJAG5hbWVfaGFzaNXDBnsIsywYAwoAbmV0d29ya19pZIprt5IKBgBzdGF0ZXMDDABib29rc19zdG9yZWQAAAAAAwkAZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:lectern", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTBAQAACAQAbmFtZREAbWluZWNyYWZ0OmxlY3Rlcm4ECQBuYW1lX2hhc2j5Z4Mmi/1QxAMKAG5ldHdvcmtfaWR4JfDHCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgBCwBwb3dlcmVkX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:cauldron" + }, + { + "id": "minecraft:composter", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTUAQAACAQAbmFtZRMAbWluZWNyYWZ0OmNvbXBvc3RlcgQJAG5hbWVfaGFzaPAADHptzeWJAwoAbmV0d29ya19pZHIL6i4KBgBzdGF0ZXMDFABjb21wb3N0ZXJfZmlsbF9sZXZlbAAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:chest", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ2AAAACAQAbmFtZQ8AbWluZWNyYWZ0OmNoZXN0BAkAbmFtZV9oYXNog9ozMxlcA88DCgBuZXR3b3JrX2lkDkOFvAoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAG5vcnRoAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:trapped_chest", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSSAAAACAQAbmFtZRcAbWluZWNyYWZ0OnRyYXBwZWRfY2hlc3QECQBuYW1lX2hhc2g2qpF9stsEjgMKAG5ldHdvcmtfaWTjJWYxCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAbm9ydGgAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:ender_chest", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSCAAAACAQAbmFtZRUAbWluZWNyYWZ0OmVuZGVyX2NoZXN0BAkAbmFtZV9oYXNohEZzOFdg0WUDCgBuZXR3b3JrX2lkx4jiSQoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAG5vcnRoAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:barrel", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTKAQAACAQAbmFtZRAAbWluZWNyYWZ0OmJhcnJlbAQJAG5hbWVfaGFzaHDkRPGymiRqAwoAbmV0d29ya19pZPnxzgsKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:undyed_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTNAAAACAQAbmFtZRwAbWluZWNyYWZ0OnVuZHllZF9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaOC9mypm/MlBAwoAbmV0d29ya19pZJ8rxp0KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:white_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTaAAAACAQAbmFtZRsAbWluZWNyYWZ0OndoaXRlX3NodWxrZXJfYm94BAkAbmFtZV9oYXNosK79m1rPUBwDCgBuZXR3b3JrX2lkjrET6goGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:light_gray_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRrAwAACAQAbmFtZSAAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2iBe5zq7PxHmgMKAG5ldHdvcmtfaWSCVJv0CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:gray_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRqAwAACAQAbmFtZRoAbWluZWNyYWZ0OmdyYXlfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2ga2s8ctjHUhgMKAG5ldHdvcmtfaWS3WMsWCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:black_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRyAwAACAQAbmFtZRsAbWluZWNyYWZ0OmJsYWNrX3NodWxrZXJfYm94BAkAbmFtZV9oYXNoPm03OZphrp8DCgBuZXR3b3JrX2lkXHztNAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:brown_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRvAwAACAQAbmFtZRsAbWluZWNyYWZ0OmJyb3duX3NodWxrZXJfYm94BAkAbmFtZV9oYXNoT3DD6qAL9cADCgBuZXR3b3JrX2lkaXxpYQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:red_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRxAwAACAQAbmFtZRkAbWluZWNyYWZ0OnJlZF9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaMIlKSCzqSZoAwoAbmV0d29ya19pZNrf+icKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:orange_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRkAwAACAQAbmFtZRwAbWluZWNyYWZ0Om9yYW5nZV9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaG2MAXU67wGrAwoAbmV0d29ya19pZGoO05gKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:yellow_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRnAwAACAQAbmFtZRwAbWluZWNyYWZ0OnllbGxvd19zaHVsa2VyX2JveAQJAG5hbWVfaGFzaIsLwQHYjcIEAwoAbmV0d29ya19pZBCBSiYKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:lime_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRoAwAACAQAbmFtZRoAbWluZWNyYWZ0OmxpbWVfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2hUwBkg+faUGAMKAG5ldHdvcmtfaWRJeKqqCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:green_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRwAwAACAQAbmFtZRsAbWluZWNyYWZ0OmdyZWVuX3NodWxrZXJfYm94BAkAbmFtZV9oYXNoZgUeT3LupLUDCgBuZXR3b3JrX2lkzJiohQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:cyan_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRsAwAACAQAbmFtZRoAbWluZWNyYWZ0OmN5YW5fc2h1bGtlcl9ib3gECQBuYW1lX2hhc2gSfbjteXg5yAMKAG5ldHdvcmtfaWTHeliECgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:light_blue_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRmAwAACAQAbmFtZSAAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2h0VFCX0qsRxQMKAG5ldHdvcmtfaWQXD8U0CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:blue_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRuAwAACAQAbmFtZRoAbWluZWNyYWZ0OmJsdWVfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2hn9gS0XIe6rAMKAG5ldHdvcmtfaWTO4PJaCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:purple_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRtAwAACAQAbmFtZRwAbWluZWNyYWZ0OnB1cnBsZV9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaEV/lkNPxRDdAwoAbmV0d29ya19pZFK25GAKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:magenta_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRlAwAACAQAbmFtZR0AbWluZWNyYWZ0Om1hZ2VudGFfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2iqWM7IJHxcFgMKAG5ldHdvcmtfaWTyyudTCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:pink_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRpAwAACAQAbmFtZRoAbWluZWNyYWZ0OnBpbmtfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2in1tkJ1GNcZgMKAG5ldHdvcmtfaWQOEGXjCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:armor_stand" + }, + { + "id": "minecraft:noteblock", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQZAAAACAQAbmFtZRMAbWluZWNyYWZ0Om5vdGVibG9jawQJAG5hbWVfaGFzaHPA8dBBH0UaAwoAbmV0d29ya19pZH1U5QkKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:jukebox", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRUAAAACAQAbmFtZREAbWluZWNyYWZ0Omp1a2Vib3gECQBuYW1lX2hhc2ieAIPExf/ZfgMKAG5ldHdvcmtfaWSmR7JfCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:music_disc_13" + }, + { + "id": "minecraft:music_disc_cat" + }, + { + "id": "minecraft:music_disc_blocks" + }, + { + "id": "minecraft:music_disc_chirp" + }, + { + "id": "minecraft:music_disc_far" + }, + { + "id": "minecraft:music_disc_mall" + }, + { + "id": "minecraft:music_disc_mellohi" + }, + { + "id": "minecraft:music_disc_stal" + }, + { + "id": "minecraft:music_disc_strad" + }, + { + "id": "minecraft:music_disc_ward" + }, + { + "id": "minecraft:music_disc_11" + }, + { + "id": "minecraft:music_disc_wait" + }, + { + "id": "minecraft:music_disc_otherside" + }, + { + "id": "minecraft:music_disc_5" + }, + { + "id": "minecraft:music_disc_pigstep" + }, + { + "id": "minecraft:music_disc_relic" + }, + { + "id": "minecraft:disc_fragment_5" + }, + { + "id": "minecraft:glowstone_dust" + }, + { + "id": "minecraft:glowstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRZAAAACAQAbmFtZRMAbWluZWNyYWZ0Omdsb3dzdG9uZQQJAG5hbWVfaGFzaFYqXNkefIlPAwoAbmV0d29ya19pZGT7WYYKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:redstone_lamp", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR7AAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZHN0b25lX2xhbXAECQBuYW1lX2hhc2hJ9V80caPvEgMKAG5ldHdvcmtfaWRvNPwnCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:sea_lantern", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSpAAAACAQAbmFtZRUAbWluZWNyYWZ0OnNlYV9sYW50ZXJuBAkAbmFtZV9oYXNoLPsv1TX9M+QDCgBuZXR3b3JrX2lk1PPVyAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:oak_sign" + }, + { + "id": "minecraft:spruce_sign" + }, + { + "id": "minecraft:birch_sign" + }, + { + "id": "minecraft:jungle_sign" + }, + { + "id": "minecraft:acacia_sign" + }, + { + "id": "minecraft:dark_oak_sign" + }, + { + "id": "minecraft:mangrove_sign" + }, + { + "id": "minecraft:cherry_sign" + }, + { + "id": "minecraft:bamboo_sign" + }, + { + "id": "minecraft:crimson_sign" + }, + { + "id": "minecraft:warped_sign" + }, + { + "id": "minecraft:oak_hanging_sign" + }, + { + "id": "minecraft:spruce_hanging_sign" + }, + { + "id": "minecraft:birch_hanging_sign" + }, + { + "id": "minecraft:jungle_hanging_sign" + }, + { + "id": "minecraft:acacia_hanging_sign" + }, + { + "id": "minecraft:dark_oak_hanging_sign" + }, + { + "id": "minecraft:mangrove_hanging_sign" + }, + { + "id": "minecraft:cherry_hanging_sign" + }, + { + "id": "minecraft:bamboo_hanging_sign" + }, + { + "id": "minecraft:crimson_hanging_sign" + }, + { + "id": "minecraft:warped_hanging_sign" + }, + { + "id": "minecraft:painting" + }, + { + "id": "minecraft:frame" + }, + { + "id": "minecraft:glow_frame" + }, + { + "id": "minecraft:honey_bottle" + }, + { + "id": "minecraft:flower_pot" + }, + { + "id": "minecraft:bowl" + }, + { + "id": "minecraft:bucket" + }, + { + "id": "minecraft:milk_bucket" + }, + { + "id": "minecraft:water_bucket" + }, + { + "id": "minecraft:lava_bucket" + }, + { + "id": "minecraft:cod_bucket" + }, + { + "id": "minecraft:salmon_bucket" + }, + { + "id": "minecraft:tropical_fish_bucket" + }, + { + "id": "minecraft:pufferfish_bucket" + }, + { + "id": "minecraft:powder_snow_bucket" + }, + { + "id": "minecraft:axolotl_bucket" + }, + { + "id": "minecraft:tadpole_bucket" + }, + { + "id": "minecraft:skull", + "damage": 3 + }, + { + "id": "minecraft:skull", + "damage": 2 + }, + { + "id": "minecraft:skull", + "damage": 4 + }, + { + "id": "minecraft:skull", + "damage": 5 + }, + { + "id": "minecraft:skull" + }, + { + "id": "minecraft:skull", + "damage": 1 + }, + { + "id": "minecraft:skull", + "damage": 6 + }, + { + "id": "minecraft:beacon", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSKAAAACAQAbmFtZRAAbWluZWNyYWZ0OmJlYWNvbgQJAG5hbWVfaGFzaACwhhfSkdkHAwoAbmV0d29ya19pZF8jfiEKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:bell", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTNAQAACAQAbmFtZQ4AbWluZWNyYWZ0OmJlbGwECQBuYW1lX2hhc2iPqsgDXRcsxAMKAG5ldHdvcmtfaWT7zhOoCgYAc3RhdGVzCAoAYXR0YWNobWVudAgAc3RhbmRpbmcDCQBkaXJlY3Rpb24AAAAAAQoAdG9nZ2xlX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:conduit", + "block_state_b64": "CgAAAwgAYmxvY2tfaWScAQAACAQAbmFtZREAbWluZWNyYWZ0OmNvbmR1aXQECQBuYW1lX2hhc2jqxKAxq2EaWQMKAG5ldHdvcmtfaWTWcBVnCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:stonecutter_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTEAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lY3V0dGVyX2Jsb2NrBAkAbmFtZV9oYXNoQAXTbAM3MeYDCgBuZXR3b3JrX2lkWS4RjAoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAG5vcnRoAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:coal" + }, + { + "id": "minecraft:charcoal" + }, + { + "id": "minecraft:diamond" + }, + { + "id": "minecraft:iron_nugget" + }, + { + "id": "minecraft:raw_iron" + }, + { + "id": "minecraft:raw_gold" + }, + { + "id": "minecraft:raw_copper" + }, + { + "id": "minecraft:copper_ingot" + }, + { + "id": "minecraft:iron_ingot" + }, + { + "id": "minecraft:netherite_scrap" + }, + { + "id": "minecraft:netherite_ingot" + }, + { + "id": "minecraft:gold_nugget" + }, + { + "id": "minecraft:gold_ingot" + }, + { + "id": "minecraft:emerald" + }, + { + "id": "minecraft:quartz" + }, + { + "id": "minecraft:clay_ball" + }, + { + "id": "minecraft:brick" + }, + { + "id": "minecraft:netherbrick" + }, + { + "id": "minecraft:prismarine_shard" + }, + { + "id": "minecraft:amethyst_shard" + }, + { + "id": "minecraft:prismarine_crystals" + }, + { + "id": "minecraft:nautilus_shell" + }, + { + "id": "minecraft:heart_of_the_sea" + }, + { + "id": "minecraft:turtle_scute" + }, + { + "id": "minecraft:phantom_membrane" + }, + { + "id": "minecraft:string" + }, + { + "id": "minecraft:feather" + }, + { + "id": "minecraft:flint" + }, + { + "id": "minecraft:gunpowder" + }, + { + "id": "minecraft:leather" + }, + { + "id": "minecraft:rabbit_hide" + }, + { + "id": "minecraft:rabbit_foot" + }, + { + "id": "minecraft:fire_charge" + }, + { + "id": "minecraft:blaze_rod" + }, + { + "id": "minecraft:blaze_powder" + }, + { + "id": "minecraft:magma_cream" + }, + { + "id": "minecraft:fermented_spider_eye" + }, + { + "id": "minecraft:echo_shard" + }, + { + "id": "minecraft:dragon_breath" + }, + { + "id": "minecraft:shulker_shell" + }, + { + "id": "minecraft:ghast_tear" + }, + { + "id": "minecraft:slime_ball" + }, + { + "id": "minecraft:ender_pearl" + }, + { + "id": "minecraft:ender_eye" + }, + { + "id": "minecraft:nether_star" + }, + { + "id": "minecraft:end_rod", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTQAAAACAQAbmFtZREAbWluZWNyYWZ0OmVuZF9yb2QECQBuYW1lX2hhc2jx/q5cEA0hmQMKAG5ldHdvcmtfaWQ2eM8kCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:lightning_rod", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ3AgAACAQAbmFtZRcAbWluZWNyYWZ0OmxpZ2h0bmluZ19yb2QECQBuYW1lX2hhc2ioXQF1xvfHNQMKAG5ldHdvcmtfaWRLuHyACgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:end_crystal" + }, + { + "id": "minecraft:paper" + }, + { + "id": "minecraft:book" + }, + { + "id": "minecraft:writable_book" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQFAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQFAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQFAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQGAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQGAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQGAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQHAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQHAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQHAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQIAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAUAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAUAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAUAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQMAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQMAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQNAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQNAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQOAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQOAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQOAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAUAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQQAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQRAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQRAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQRAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQSAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQSAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQSAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAUAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQUAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQUAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQVAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQWAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQXAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQXAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQXAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQYAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQYAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQYAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQZAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQZAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQaAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQbAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQcAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAUAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQeAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQeAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQeAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQfAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQfAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQfAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQgAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQhAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQjAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQjAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQjAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQkAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQkAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQkAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQlAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQlAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQlAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:oak_boat" + }, + { + "id": "minecraft:spruce_boat" + }, + { + "id": "minecraft:birch_boat" + }, + { + "id": "minecraft:jungle_boat" + }, + { + "id": "minecraft:acacia_boat" + }, + { + "id": "minecraft:dark_oak_boat" + }, + { + "id": "minecraft:mangrove_boat" + }, + { + "id": "minecraft:cherry_boat" + }, + { + "id": "minecraft:bamboo_raft" + }, + { + "id": "minecraft:oak_chest_boat" + }, + { + "id": "minecraft:spruce_chest_boat" + }, + { + "id": "minecraft:birch_chest_boat" + }, + { + "id": "minecraft:jungle_chest_boat" + }, + { + "id": "minecraft:acacia_chest_boat" + }, + { + "id": "minecraft:dark_oak_chest_boat" + }, + { + "id": "minecraft:mangrove_chest_boat" + }, + { + "id": "minecraft:cherry_chest_boat" + }, + { + "id": "minecraft:bamboo_chest_raft" + }, + { + "id": "minecraft:rail", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRCAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnJhaWwECQBuYW1lX2hhc2hUzmhUXYJDUQMKAG5ldHdvcmtfaWR+Sp6YCgYAc3RhdGVzAw4AcmFpbF9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:golden_rail", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQbAAAACAQAbmFtZRUAbWluZWNyYWZ0OmdvbGRlbl9yYWlsBAkAbmFtZV9oYXNoOoV5MaKipoUDCgBuZXR3b3JrX2lkfAcxLwoGAHN0YXRlcwENAHJhaWxfZGF0YV9iaXQAAw4AcmFpbF9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:detector_rail", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQcAAAACAQAbmFtZRcAbWluZWNyYWZ0OmRldGVjdG9yX3JhaWwECQBuYW1lX2hhc2gVUk31qOysUQMKAG5ldHdvcmtfaWRVW/aICgYAc3RhdGVzAQ0AcmFpbF9kYXRhX2JpdAADDgByYWlsX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:activator_rail", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR+AAAACAQAbmFtZRgAbWluZWNyYWZ0OmFjdGl2YXRvcl9yYWlsBAkAbmFtZV9oYXNosIL91qriCRkDCgBuZXR3b3JrX2lkZfckmwoGAHN0YXRlcwENAHJhaWxfZGF0YV9iaXQAAw4AcmFpbF9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:minecart" + }, + { + "id": "minecraft:chest_minecart" + }, + { + "id": "minecraft:hopper_minecart" + }, + { + "id": "minecraft:tnt_minecart" + }, + { + "id": "minecraft:redstone" + }, + { + "id": "minecraft:redstone_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSYAAAACAQAbmFtZRgAbWluZWNyYWZ0OnJlZHN0b25lX2Jsb2NrBAkAbmFtZV9oYXNoRhULL0r8o0sDCgBuZXR3b3JrX2lklayOHgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:redstone_torch", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRMAAAACAQAbmFtZRgAbWluZWNyYWZ0OnJlZHN0b25lX3RvcmNoBAkAbmFtZV9oYXNoizFRjpYMIDgDCgBuZXR3b3JrX2lkuHz7yAoGAHN0YXRlcwgWAHRvcmNoX2ZhY2luZ19kaXJlY3Rpb24HAHVua25vd24AAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:lever", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRFAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmxldmVyBAkAbmFtZV9oYXNoGMJeLJsUMLYDCgBuZXR3b3JrX2lkEF/GuAoGAHN0YXRlcwgPAGxldmVyX2RpcmVjdGlvbg4AZG93bl9lYXN0X3dlc3QBCABvcGVuX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:wooden_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSPAAAACAQAbmFtZRcAbWluZWNyYWZ0Ondvb2Rlbl9idXR0b24ECQBuYW1lX2hhc2hR7PgSTQt0sQMKAG5ldHdvcmtfaWSU07kYCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:spruce_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSPAQAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9idXR0b24ECQBuYW1lX2hhc2jBW9Z8aYE7YQMKAG5ldHdvcmtfaWTkUIGuCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:birch_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSMAQAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX2J1dHRvbgQJAG5hbWVfaGFzaJXYgGuSHbTwAwoAbmV0d29ya19pZGWp3yoKBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:jungle_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSOAQAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9idXR0b24ECQBuYW1lX2hhc2iCgNANcJs+BQMKAG5ldHdvcmtfaWT9fImWCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:acacia_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAQAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9idXR0b24ECQBuYW1lX2hhc2gVvmcT7LTO0wMKAG5ldHdvcmtfaWRQnxIJCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:dark_oak_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSNAQAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX2J1dHRvbgQJAG5hbWVfaGFzaIV10ZGGrCIEAwoAbmV0d29ya19pZN5vAmIKBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:mangrove_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTmAgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX2J1dHRvbgQJAG5hbWVfaGFzaNzeYYKLgOzJAwoAbmV0d29ya19pZAFEGQ0KBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:cherry_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQRAwAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9idXR0b24ECQBuYW1lX2hhc2j2/IHjeAbUcwMKAG5ldHdvcmtfaWRJ1irQCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:bamboo_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT+AgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19idXR0b24ECQBuYW1lX2hhc2j7AddMi+6nsgMKAG5ldHdvcmtfaWSa9w4/CgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:stone_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRNAAAACAQAbmFtZRYAbWluZWNyYWZ0OnN0b25lX2J1dHRvbgQJAG5hbWVfaGFzaM4ejMctmvohAwoAbmV0d29ya19pZMw+aC0KBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:crimson_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAgAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fYnV0dG9uBAkAbmFtZV9oYXNofnjYHaYIeWgDCgBuZXR3b3JrX2lk+n1vyQoGAHN0YXRlcwESAGJ1dHRvbl9wcmVzc2VkX2JpdAADEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:warped_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQEAgAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9idXR0b24ECQBuYW1lX2hhc2jwkV2EU6Cn1QMKAG5ldHdvcmtfaWTnHnk1CgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:polished_blackstone_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQnAgAACAQAbmFtZSQAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnV0dG9uBAkAbmFtZV9oYXNojmxzQKS0S/EDCgBuZXR3b3JrX2lkDtQ95woGAHN0YXRlcwESAGJ1dHRvbl9wcmVzc2VkX2JpdAADEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:tripwire_hook", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAAAACAQAbmFtZRcAbWluZWNyYWZ0OnRyaXB3aXJlX2hvb2sECQBuYW1lX2hhc2gQdp+oGZLNnAMKAG5ldHdvcmtfaWSy+1KJCgYAc3RhdGVzAQwAYXR0YWNoZWRfYml0AAMJAGRpcmVjdGlvbgAAAAABCwBwb3dlcmVkX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:wooden_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRIAAAACAQAbmFtZR8AbWluZWNyYWZ0Ondvb2Rlbl9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaGkGs5kCuA74AwoAbmV0d29ya19pZDRzPNwKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:spruce_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSZAQAACAQAbmFtZR8AbWluZWNyYWZ0OnNwcnVjZV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaNmwuq549fJKAwoAbmV0d29ya19pZLQMCw0KBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:birch_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSWAQAACAQAbmFtZR4AbWluZWNyYWZ0OmJpcmNoX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNorQkT9kDdlTwDCgBuZXR3b3JrX2lkH0G97AoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:jungle_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSYAQAACAQAbmFtZR8AbWluZWNyYWZ0Omp1bmdsZV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaJ7DcteCkb8/AwoAbmV0d29ya19pZLdPBSAKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:acacia_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSVAQAACAQAbmFtZR8AbWluZWNyYWZ0OmFjYWNpYV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaC2frZtfoYqCAwoAbmV0d29ya19pZIDdI18KBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:dark_oak_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSXAQAACAQAbmFtZSEAbWluZWNyYWZ0OmRhcmtfb2FrX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoHUCJsTy52pwDCgBuZXR3b3JrX2lkKpi8rAoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:mangrove_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTpAgAACAQAbmFtZSEAbWluZWNyYWZ0Om1hbmdyb3ZlX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoiDsTfJaX100DCgBuZXR3b3JrX2lkuwWDyQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:cherry_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQZAwAACAQAbmFtZR8AbWluZWNyYWZ0OmNoZXJyeV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaALMqYEZDUQHAwoAbmV0d29ya19pZPNT+r0KBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:bamboo_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQBAwAACAQAbmFtZR8AbWluZWNyYWZ0OmJhbWJvb19wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaNvxJ7NIAaqlAwoAbmV0d29ya19pZIZ8XnYKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:crimson_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQFAgAACAQAbmFtZSAAbWluZWNyYWZ0OmNyaW1zb25fcHJlc3N1cmVfcGxhdGUECQBuYW1lX2hhc2hqBDVDAd31/gMKAG5ldHdvcmtfaWRmV18LCgYAc3RhdGVzAw8AcmVkc3RvbmVfc2lnbmFsAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:warped_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAgAACAQAbmFtZR8AbWluZWNyYWZ0OndhcnBlZF9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaBxFoQksWtYUAwoAbmV0d29ya19pZJVRoIcKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:stone_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRGAAAACAQAbmFtZR4AbWluZWNyYWZ0OnN0b25lX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNounJuTBUTrU8DCgBuZXR3b3JrX2lkjDydwQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:light_weighted_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSTAAAACAQAbmFtZScAbWluZWNyYWZ0OmxpZ2h0X3dlaWdodGVkX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoOyOJkNxLtkEDCgBuZXR3b3JrX2lkrr2AjgoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:heavy_weighted_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSUAAAACAQAbmFtZScAbWluZWNyYWZ0OmhlYXZ5X3dlaWdodGVkX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoltgDmDvTajUDCgBuZXR3b3JrX2lkFxVKuQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:polished_blackstone_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAgAACAQAbmFtZSwAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfcHJlc3N1cmVfcGxhdGUECQBuYW1lX2hhc2h65Ci6/CeGqwMKAG5ldHdvcmtfaWTaSW5xCgYAc3RhdGVzAw8AcmVkc3RvbmVfc2lnbmFsAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:observer", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT7AAAACAQAbmFtZRIAbWluZWNyYWZ0Om9ic2VydmVyBAkAbmFtZV9oYXNoYhlh1lpmHTgDCgBuZXR3b3JrX2lkQEh55goGAHN0YXRlcwgaAG1pbmVjcmFmdDpmYWNpbmdfZGlyZWN0aW9uBABkb3duAQsAcG93ZXJlZF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:daylight_detector", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSXAAAACAQAbmFtZRsAbWluZWNyYWZ0OmRheWxpZ2h0X2RldGVjdG9yBAkAbmFtZV9oYXNoV0F0s7B7PVgDCgBuZXR3b3JrX2lkri5afQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:repeater" + }, + { + "id": "minecraft:comparator" + }, + { + "id": "minecraft:hopper" + }, + { + "id": "minecraft:dropper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR9AAAACAQAbmFtZREAbWluZWNyYWZ0OmRyb3BwZXIECQBuYW1lX2hhc2joXP7XqU0l3QMKAG5ldHdvcmtfaWQfQN6zCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgMAAAABDQB0cmlnZ2VyZWRfYml0AAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:dispenser", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQXAAAACAQAbmFtZRMAbWluZWNyYWZ0OmRpc3BlbnNlcgQJAG5hbWVfaGFzaP1RR+zAbYP2AwoAbmV0d29ya19pZGAayD0KBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAwAAAAENAHRyaWdnZXJlZF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + }, + { + "id": "minecraft:piston", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQhAAAACAQAbmFtZRAAbWluZWNyYWZ0OnBpc3RvbgQJAG5hbWVfaGFzaDs3AFh1fL0uAwoAbmV0d29ya19pZLD/5XQKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAQAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:sticky_piston", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQdAAAACAQAbmFtZRcAbWluZWNyYWZ0OnN0aWNreV9waXN0b24ECQBuYW1lX2hhc2hPFJFJSiJ0ZQMKAG5ldHdvcmtfaWT/MzCJCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgEAAAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:tnt", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQuAAAACAQAbmFtZQ0AbWluZWNyYWZ0OnRudAQJAG5hbWVfaGFzaEYOHwCvJH29AwoAbmV0d29ya19pZCGfjU4KBgBzdGF0ZXMBFABhbGxvd191bmRlcndhdGVyX2JpdAABCwBleHBsb2RlX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:name_tag" + }, + { + "id": "minecraft:loom", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTLAQAACAQAbmFtZQ4AbWluZWNyYWZ0Omxvb20ECQBuYW1lX2hhc2i7DKjAXNq8TAMKAG5ldHdvcmtfaWR/49HXCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:banner", + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 8, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 7, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 15, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 12, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 14, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 1, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 4, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 5, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 13, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 9, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 3, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 11, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 10, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 2, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 6, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 15, + "nbt_b64": "CgAAAwQAVHlwZQEAAAAA" + }, + { + "id": "minecraft:creeper_banner_pattern" + }, + { + "id": "minecraft:skull_banner_pattern" + }, + { + "id": "minecraft:flower_banner_pattern" + }, + { + "id": "minecraft:mojang_banner_pattern" + }, + { + "id": "minecraft:field_masoned_banner_pattern" + }, + { + "id": "minecraft:bordure_indented_banner_pattern" + }, + { + "id": "minecraft:piglin_banner_pattern" + }, + { + "id": "minecraft:globe_banner_pattern" + }, + { + "id": "minecraft:angler_pottery_sherd" + }, + { + "id": "minecraft:archer_pottery_sherd" + }, + { + "id": "minecraft:arms_up_pottery_sherd" + }, + { + "id": "minecraft:blade_pottery_sherd" + }, + { + "id": "minecraft:brewer_pottery_sherd" + }, + { + "id": "minecraft:burn_pottery_sherd" + }, + { + "id": "minecraft:danger_pottery_sherd" + }, + { + "id": "minecraft:explorer_pottery_sherd" + }, + { + "id": "minecraft:friend_pottery_sherd" + }, + { + "id": "minecraft:heart_pottery_sherd" + }, + { + "id": "minecraft:heartbreak_pottery_sherd" + }, + { + "id": "minecraft:howl_pottery_sherd" + }, + { + "id": "minecraft:miner_pottery_sherd" + }, + { + "id": "minecraft:mourner_pottery_sherd" + }, + { + "id": "minecraft:plenty_pottery_sherd" + }, + { + "id": "minecraft:prize_pottery_sherd" + }, + { + "id": "minecraft:sheaf_pottery_sherd" + }, + { + "id": "minecraft:shelter_pottery_sherd" + }, + { + "id": "minecraft:skull_pottery_sherd" + }, + { + "id": "minecraft:snort_pottery_sherd" + }, + { + "id": "minecraft:netherite_upgrade_smithing_template" + }, + { + "id": "minecraft:sentry_armor_trim_smithing_template" + }, + { + "id": "minecraft:vex_armor_trim_smithing_template" + }, + { + "id": "minecraft:wild_armor_trim_smithing_template" + }, + { + "id": "minecraft:coast_armor_trim_smithing_template" + }, + { + "id": "minecraft:dune_armor_trim_smithing_template" + }, + { + "id": "minecraft:wayfinder_armor_trim_smithing_template" + }, + { + "id": "minecraft:shaper_armor_trim_smithing_template" + }, + { + "id": "minecraft:raiser_armor_trim_smithing_template" + }, + { + "id": "minecraft:host_armor_trim_smithing_template" + }, + { + "id": "minecraft:ward_armor_trim_smithing_template" + }, + { + "id": "minecraft:silence_armor_trim_smithing_template" + }, + { + "id": "minecraft:tide_armor_trim_smithing_template" + }, + { + "id": "minecraft:snout_armor_trim_smithing_template" + }, + { + "id": "minecraft:rib_armor_trim_smithing_template" + }, + { + "id": "minecraft:eye_armor_trim_smithing_template" + }, + { + "id": "minecraft:spire_armor_trim_smithing_template" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwAAAAAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAABwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAIBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAHBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAPBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAMBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAOBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAABBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAEBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAFBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAANBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAJBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAADBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAALBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAKBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAACBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAGBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_star", + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yIR0d/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 8, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yUk9H/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 7, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yl52d/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 15, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9y8PDw/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 12, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9y2rM6/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 14, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yHYD5/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 1, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yJi6w/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 4, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yqkQ8/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 5, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yuDKJ/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 13, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yvU7H/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 9, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yqovz/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 3, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yMlSD/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 11, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yPdj+/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 10, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yH8eA/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 2, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yFnxe/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 6, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9ynJwW/wA=" + }, + { + "id": "minecraft:chain" + }, + { + "id": "minecraft:target", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTuAQAACAQAbmFtZRAAbWluZWNyYWZ0OnRhcmdldAQJAG5hbWVfaGFzaJc66SVbYlaxAwoAbmV0d29ya19pZPBozs0KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + }, + { + "id": "minecraft:decorated_pot", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAwAACAQAbmFtZRcAbWluZWNyYWZ0OmRlY29yYXRlZF9wb3QECQBuYW1lX2hhc2jjQgckn8VTvwMKAG5ldHdvcmtfaWRwvkUUCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + }, + { + "id": "minecraft:lodestone_compass" + }, + { + "id": "minecraft:wither_spawn_egg" + }, + { + "id": "minecraft:ender_dragon_spawn_egg" + } + ] +} \ No newline at end of file diff --git a/core/src/main/resources/bedrock/entity_identifiers.dat b/core/src/main/resources/bedrock/entity_identifiers.dat index 4e8d836c6df13ee61cc445e7edf97d83af9a75b7..9a986cf5c435ac467cac73c25a0ba160cbfbb0be 100644 GIT binary patch delta 37 tcmX?Sd(L)4nbhPBQrwfPWb7vImNK3!&&WNwQA&UFJEp<{dI(OaL9R4YL3M diff --git a/core/src/main/resources/bedrock/runtime_item_states.1_20_70.json b/core/src/main/resources/bedrock/runtime_item_states.1_20_70.json new file mode 100644 index 000000000..887b89ba1 --- /dev/null +++ b/core/src/main/resources/bedrock/runtime_item_states.1_20_70.json @@ -0,0 +1,6126 @@ +[ + { + "name": "minecraft:acacia_boat", + "id": 383 + }, + { + "name": "minecraft:acacia_button", + "id": -140 + }, + { + "name": "minecraft:acacia_chest_boat", + "id": 653 + }, + { + "name": "minecraft:acacia_door", + "id": 567 + }, + { + "name": "minecraft:acacia_double_slab", + "id": -812 + }, + { + "name": "minecraft:acacia_fence", + "id": -575 + }, + { + "name": "minecraft:acacia_fence_gate", + "id": 187 + }, + { + "name": "minecraft:acacia_hanging_sign", + "id": -504 + }, + { + "name": "minecraft:acacia_leaves", + "id": 161 + }, + { + "name": "minecraft:acacia_log", + "id": 162 + }, + { + "name": "minecraft:acacia_planks", + "id": -742 + }, + { + "name": "minecraft:acacia_pressure_plate", + "id": -150 + }, + { + "name": "minecraft:acacia_sign", + "id": 590 + }, + { + "name": "minecraft:acacia_slab", + "id": -807 + }, + { + "name": "minecraft:acacia_stairs", + "id": 163 + }, + { + "name": "minecraft:acacia_standing_sign", + "id": -190 + }, + { + "name": "minecraft:acacia_trapdoor", + "id": -145 + }, + { + "name": "minecraft:acacia_wall_sign", + "id": -191 + }, + { + "name": "minecraft:acacia_wood", + "id": -817 + }, + { + "name": "minecraft:activator_rail", + "id": 126 + }, + { + "name": "minecraft:agent_spawn_egg", + "id": 492 + }, + { + "name": "minecraft:air", + "id": -158 + }, + { + "name": "minecraft:allay_spawn_egg", + "id": 642 + }, + { + "name": "minecraft:allow", + "id": 210 + }, + { + "name": "minecraft:amethyst_block", + "id": -327 + }, + { + "name": "minecraft:amethyst_cluster", + "id": -329 + }, + { + "name": "minecraft:amethyst_shard", + "id": 635 + }, + { + "name": "minecraft:ancient_debris", + "id": -271 + }, + { + "name": "minecraft:andesite", + "id": -594 + }, + { + "name": "minecraft:andesite_stairs", + "id": -171 + }, + { + "name": "minecraft:angler_pottery_sherd", + "id": 667 + }, + { + "name": "minecraft:anvil", + "id": 145 + }, + { + "name": "minecraft:apple", + "id": 257 + }, + { + "name": "minecraft:archer_pottery_sherd", + "id": 668 + }, + { + "name": "minecraft:armadillo_scute", + "id": 709 + }, + { + "name": "minecraft:armadillo_spawn_egg", + "id": 708 + }, + { + "name": "minecraft:armor_stand", + "id": 563 + }, + { + "name": "minecraft:arms_up_pottery_sherd", + "id": 669 + }, + { + "name": "minecraft:arrow", + "id": 304 + }, + { + "name": "minecraft:axolotl_bucket", + "id": 372 + }, + { + "name": "minecraft:axolotl_spawn_egg", + "id": 507 + }, + { + "name": "minecraft:azalea", + "id": -337 + }, + { + "name": "minecraft:azalea_leaves", + "id": -324 + }, + { + "name": "minecraft:azalea_leaves_flowered", + "id": -325 + }, + { + "name": "minecraft:baked_potato", + "id": 282 + }, + { + "name": "minecraft:balloon", + "id": 609 + }, + { + "name": "minecraft:bamboo", + "id": -163 + }, + { + "name": "minecraft:bamboo_block", + "id": -527 + }, + { + "name": "minecraft:bamboo_button", + "id": -511 + }, + { + "name": "minecraft:bamboo_chest_raft", + "id": 665 + }, + { + "name": "minecraft:bamboo_door", + "id": -517 + }, + { + "name": "minecraft:bamboo_double_slab", + "id": -521 + }, + { + "name": "minecraft:bamboo_fence", + "id": -515 + }, + { + "name": "minecraft:bamboo_fence_gate", + "id": -516 + }, + { + "name": "minecraft:bamboo_hanging_sign", + "id": -522 + }, + { + "name": "minecraft:bamboo_mosaic", + "id": -509 + }, + { + "name": "minecraft:bamboo_mosaic_double_slab", + "id": -525 + }, + { + "name": "minecraft:bamboo_mosaic_slab", + "id": -524 + }, + { + "name": "minecraft:bamboo_mosaic_stairs", + "id": -523 + }, + { + "name": "minecraft:bamboo_planks", + "id": -510 + }, + { + "name": "minecraft:bamboo_pressure_plate", + "id": -514 + }, + { + "name": "minecraft:bamboo_raft", + "id": 664 + }, + { + "name": "minecraft:bamboo_sapling", + "id": -164 + }, + { + "name": "minecraft:bamboo_sign", + "id": 663 + }, + { + "name": "minecraft:bamboo_slab", + "id": -513 + }, + { + "name": "minecraft:bamboo_stairs", + "id": -512 + }, + { + "name": "minecraft:bamboo_standing_sign", + "id": -518 + }, + { + "name": "minecraft:bamboo_trapdoor", + "id": -520 + }, + { + "name": "minecraft:bamboo_wall_sign", + "id": -519 + }, + { + "name": "minecraft:banner", + "id": 578 + }, + { + "name": "minecraft:banner_pattern", + "id": 731 + }, + { + "name": "minecraft:barrel", + "id": -203 + }, + { + "name": "minecraft:barrier", + "id": -161 + }, + { + "name": "minecraft:basalt", + "id": -234 + }, + { + "name": "minecraft:bat_spawn_egg", + "id": 457 + }, + { + "name": "minecraft:beacon", + "id": 138 + }, + { + "name": "minecraft:bed", + "id": 422 + }, + { + "name": "minecraft:bedrock", + "id": 7 + }, + { + "name": "minecraft:bee_nest", + "id": -218 + }, + { + "name": "minecraft:bee_spawn_egg", + "id": 499 + }, + { + "name": "minecraft:beef", + "id": 274 + }, + { + "name": "minecraft:beehive", + "id": -219 + }, + { + "name": "minecraft:beetroot", + "id": 286 + }, + { + "name": "minecraft:beetroot_seeds", + "id": 296 + }, + { + "name": "minecraft:beetroot_soup", + "id": 287 + }, + { + "name": "minecraft:bell", + "id": -206 + }, + { + "name": "minecraft:big_dripleaf", + "id": -323 + }, + { + "name": "minecraft:birch_boat", + "id": 380 + }, + { + "name": "minecraft:birch_button", + "id": -141 + }, + { + "name": "minecraft:birch_chest_boat", + "id": 650 + }, + { + "name": "minecraft:birch_door", + "id": 565 + }, + { + "name": "minecraft:birch_double_slab", + "id": -810 + }, + { + "name": "minecraft:birch_fence", + "id": -576 + }, + { + "name": "minecraft:birch_fence_gate", + "id": 184 + }, + { + "name": "minecraft:birch_hanging_sign", + "id": -502 + }, + { + "name": "minecraft:birch_leaves", + "id": -801 + }, + { + "name": "minecraft:birch_log", + "id": -570 + }, + { + "name": "minecraft:birch_planks", + "id": -740 + }, + { + "name": "minecraft:birch_pressure_plate", + "id": -151 + }, + { + "name": "minecraft:birch_sign", + "id": 588 + }, + { + "name": "minecraft:birch_slab", + "id": -805 + }, + { + "name": "minecraft:birch_stairs", + "id": 135 + }, + { + "name": "minecraft:birch_standing_sign", + "id": -186 + }, + { + "name": "minecraft:birch_trapdoor", + "id": -146 + }, + { + "name": "minecraft:birch_wall_sign", + "id": -187 + }, + { + "name": "minecraft:birch_wood", + "id": -815 + }, + { + "name": "minecraft:black_candle", + "id": -428 + }, + { + "name": "minecraft:black_candle_cake", + "id": -445 + }, + { + "name": "minecraft:black_carpet", + "id": -611 + }, + { + "name": "minecraft:black_concrete", + "id": -642 + }, + { + "name": "minecraft:black_concrete_powder", + "id": -723 + }, + { + "name": "minecraft:black_dye", + "id": 399 + }, + { + "name": "minecraft:black_glazed_terracotta", + "id": 235 + }, + { + "name": "minecraft:black_shulker_box", + "id": -627 + }, + { + "name": "minecraft:black_stained_glass", + "id": -687 + }, + { + "name": "minecraft:black_stained_glass_pane", + "id": -657 + }, + { + "name": "minecraft:black_terracotta", + "id": -738 + }, + { + "name": "minecraft:black_wool", + "id": -554 + }, + { + "name": "minecraft:blackstone", + "id": -273 + }, + { + "name": "minecraft:blackstone_double_slab", + "id": -283 + }, + { + "name": "minecraft:blackstone_slab", + "id": -282 + }, + { + "name": "minecraft:blackstone_stairs", + "id": -276 + }, + { + "name": "minecraft:blackstone_wall", + "id": -277 + }, + { + "name": "minecraft:blade_pottery_sherd", + "id": 670 + }, + { + "name": "minecraft:blast_furnace", + "id": -196 + }, + { + "name": "minecraft:blaze_powder", + "id": 433 + }, + { + "name": "minecraft:blaze_rod", + "id": 427 + }, + { + "name": "minecraft:blaze_spawn_egg", + "id": 460 + }, + { + "name": "minecraft:bleach", + "id": 607 + }, + { + "name": "minecraft:blue_candle", + "id": -424 + }, + { + "name": "minecraft:blue_candle_cake", + "id": -441 + }, + { + "name": "minecraft:blue_carpet", + "id": -607 + }, + { + "name": "minecraft:blue_concrete", + "id": -638 + }, + { + "name": "minecraft:blue_concrete_powder", + "id": -719 + }, + { + "name": "minecraft:blue_dye", + "id": 403 + }, + { + "name": "minecraft:blue_glazed_terracotta", + "id": 231 + }, + { + "name": "minecraft:blue_ice", + "id": -11 + }, + { + "name": "minecraft:blue_shulker_box", + "id": -623 + }, + { + "name": "minecraft:blue_stained_glass", + "id": -683 + }, + { + "name": "minecraft:blue_stained_glass_pane", + "id": -653 + }, + { + "name": "minecraft:blue_terracotta", + "id": -734 + }, + { + "name": "minecraft:blue_wool", + "id": -563 + }, + { + "name": "minecraft:boat", + "id": 729 + }, + { + "name": "minecraft:bogged_spawn_egg", + "id": 467 + }, + { + "name": "minecraft:bone", + "id": 419 + }, + { + "name": "minecraft:bone_block", + "id": 216 + }, + { + "name": "minecraft:bone_meal", + "id": 415 + }, + { + "name": "minecraft:book", + "id": 391 + }, + { + "name": "minecraft:bookshelf", + "id": 47 + }, + { + "name": "minecraft:border_block", + "id": 212 + }, + { + "name": "minecraft:bordure_indented_banner_pattern", + "id": 597 + }, + { + "name": "minecraft:bow", + "id": 303 + }, + { + "name": "minecraft:bowl", + "id": 324 + }, + { + "name": "minecraft:brain_coral", + "id": -581 + }, + { + "name": "minecraft:bread", + "id": 262 + }, + { + "name": "minecraft:breeze_spawn_egg", + "id": 506 + }, + { + "name": "minecraft:brewer_pottery_sherd", + "id": 671 + }, + { + "name": "minecraft:brewing_stand", + "id": 435 + }, + { + "name": "minecraft:brick", + "id": 387 + }, + { + "name": "minecraft:brick_block", + "id": 45 + }, + { + "name": "minecraft:brick_stairs", + "id": 108 + }, + { + "name": "minecraft:brown_candle", + "id": -425 + }, + { + "name": "minecraft:brown_candle_cake", + "id": -442 + }, + { + "name": "minecraft:brown_carpet", + "id": -608 + }, + { + "name": "minecraft:brown_concrete", + "id": -639 + }, + { + "name": "minecraft:brown_concrete_powder", + "id": -720 + }, + { + "name": "minecraft:brown_dye", + "id": 402 + }, + { + "name": "minecraft:brown_glazed_terracotta", + "id": 232 + }, + { + "name": "minecraft:brown_mushroom", + "id": 39 + }, + { + "name": "minecraft:brown_mushroom_block", + "id": 99 + }, + { + "name": "minecraft:brown_shulker_box", + "id": -624 + }, + { + "name": "minecraft:brown_stained_glass", + "id": -684 + }, + { + "name": "minecraft:brown_stained_glass_pane", + "id": -654 + }, + { + "name": "minecraft:brown_terracotta", + "id": -735 + }, + { + "name": "minecraft:brown_wool", + "id": -555 + }, + { + "name": "minecraft:brush", + "id": 687 + }, + { + "name": "minecraft:bubble_column", + "id": -160 + }, + { + "name": "minecraft:bubble_coral", + "id": -582 + }, + { + "name": "minecraft:bucket", + "id": 363 + }, + { + "name": "minecraft:budding_amethyst", + "id": -328 + }, + { + "name": "minecraft:burn_pottery_sherd", + "id": 672 + }, + { + "name": "minecraft:cactus", + "id": 81 + }, + { + "name": "minecraft:cake", + "id": 421 + }, + { + "name": "minecraft:calcite", + "id": -326 + }, + { + "name": "minecraft:calibrated_sculk_sensor", + "id": -580 + }, + { + "name": "minecraft:camel_spawn_egg", + "id": 666 + }, + { + "name": "minecraft:camera", + "id": 604 + }, + { + "name": "minecraft:campfire", + "id": 600 + }, + { + "name": "minecraft:candle", + "id": -412 + }, + { + "name": "minecraft:candle_cake", + "id": -429 + }, + { + "name": "minecraft:carpet", + "id": 712 + }, + { + "name": "minecraft:carrot", + "id": 280 + }, + { + "name": "minecraft:carrot_on_a_stick", + "id": 528 + }, + { + "name": "minecraft:carrots", + "id": 141 + }, + { + "name": "minecraft:cartography_table", + "id": -200 + }, + { + "name": "minecraft:carved_pumpkin", + "id": -155 + }, + { + "name": "minecraft:cat_spawn_egg", + "id": 493 + }, + { + "name": "minecraft:cauldron", + "id": 436 + }, + { + "name": "minecraft:cave_spider_spawn_egg", + "id": 461 + }, + { + "name": "minecraft:cave_vines", + "id": -322 + }, + { + "name": "minecraft:cave_vines_body_with_berries", + "id": -375 + }, + { + "name": "minecraft:cave_vines_head_with_berries", + "id": -376 + }, + { + "name": "minecraft:chain", + "id": 630 + }, + { + "name": "minecraft:chain_command_block", + "id": 189 + }, + { + "name": "minecraft:chainmail_boots", + "id": 345 + }, + { + "name": "minecraft:chainmail_chestplate", + "id": 343 + }, + { + "name": "minecraft:chainmail_helmet", + "id": 342 + }, + { + "name": "minecraft:chainmail_leggings", + "id": 344 + }, + { + "name": "minecraft:charcoal", + "id": 306 + }, + { + "name": "minecraft:chemical_heat", + "id": 192 + }, + { + "name": "minecraft:chemistry_table", + "id": 238 + }, + { + "name": "minecraft:cherry_boat", + "id": 660 + }, + { + "name": "minecraft:cherry_button", + "id": -530 + }, + { + "name": "minecraft:cherry_chest_boat", + "id": 661 + }, + { + "name": "minecraft:cherry_door", + "id": -531 + }, + { + "name": "minecraft:cherry_double_slab", + "id": -540 + }, + { + "name": "minecraft:cherry_fence", + "id": -532 + }, + { + "name": "minecraft:cherry_fence_gate", + "id": -533 + }, + { + "name": "minecraft:cherry_hanging_sign", + "id": -534 + }, + { + "name": "minecraft:cherry_leaves", + "id": -548 + }, + { + "name": "minecraft:cherry_log", + "id": -536 + }, + { + "name": "minecraft:cherry_planks", + "id": -537 + }, + { + "name": "minecraft:cherry_pressure_plate", + "id": -538 + }, + { + "name": "minecraft:cherry_sapling", + "id": -547 + }, + { + "name": "minecraft:cherry_sign", + "id": 662 + }, + { + "name": "minecraft:cherry_slab", + "id": -539 + }, + { + "name": "minecraft:cherry_stairs", + "id": -541 + }, + { + "name": "minecraft:cherry_standing_sign", + "id": -542 + }, + { + "name": "minecraft:cherry_trapdoor", + "id": -543 + }, + { + "name": "minecraft:cherry_wall_sign", + "id": -544 + }, + { + "name": "minecraft:cherry_wood", + "id": -546 + }, + { + "name": "minecraft:chest", + "id": 54 + }, + { + "name": "minecraft:chest_boat", + "id": 656 + }, + { + "name": "minecraft:chest_minecart", + "id": 393 + }, + { + "name": "minecraft:chicken", + "id": 276 + }, + { + "name": "minecraft:chicken_spawn_egg", + "id": 439 + }, + { + "name": "minecraft:chiseled_bookshelf", + "id": -526 + }, + { + "name": "minecraft:chiseled_copper", + "id": -760 + }, + { + "name": "minecraft:chiseled_deepslate", + "id": -395 + }, + { + "name": "minecraft:chiseled_nether_bricks", + "id": -302 + }, + { + "name": "minecraft:chiseled_polished_blackstone", + "id": -279 + }, + { + "name": "minecraft:chiseled_tuff", + "id": -753 + }, + { + "name": "minecraft:chiseled_tuff_bricks", + "id": -759 + }, + { + "name": "minecraft:chorus_flower", + "id": 200 + }, + { + "name": "minecraft:chorus_fruit", + "id": 569 + }, + { + "name": "minecraft:chorus_plant", + "id": 240 + }, + { + "name": "minecraft:clay", + "id": 82 + }, + { + "name": "minecraft:clay_ball", + "id": 388 + }, + { + "name": "minecraft:client_request_placeholder_block", + "id": -465 + }, + { + "name": "minecraft:clock", + "id": 397 + }, + { + "name": "minecraft:coal", + "id": 305 + }, + { + "name": "minecraft:coal_block", + "id": 173 + }, + { + "name": "minecraft:coal_ore", + "id": 16 + }, + { + "name": "minecraft:coast_armor_trim_smithing_template", + "id": 691 + }, + { + "name": "minecraft:cobbled_deepslate", + "id": -379 + }, + { + "name": "minecraft:cobbled_deepslate_double_slab", + "id": -396 + }, + { + "name": "minecraft:cobbled_deepslate_slab", + "id": -380 + }, + { + "name": "minecraft:cobbled_deepslate_stairs", + "id": -381 + }, + { + "name": "minecraft:cobbled_deepslate_wall", + "id": -382 + }, + { + "name": "minecraft:cobblestone", + "id": 4 + }, + { + "name": "minecraft:cobblestone_wall", + "id": 139 + }, + { + "name": "minecraft:cocoa", + "id": 127 + }, + { + "name": "minecraft:cocoa_beans", + "id": 416 + }, + { + "name": "minecraft:cod", + "id": 265 + }, + { + "name": "minecraft:cod_bucket", + "id": 367 + }, + { + "name": "minecraft:cod_spawn_egg", + "id": 485 + }, + { + "name": "minecraft:colored_torch_bp", + "id": 204 + }, + { + "name": "minecraft:colored_torch_rg", + "id": 202 + }, + { + "name": "minecraft:command_block", + "id": 137 + }, + { + "name": "minecraft:command_block_minecart", + "id": 574 + }, + { + "name": "minecraft:comparator", + "id": 533 + }, + { + "name": "minecraft:compass", + "id": 395 + }, + { + "name": "minecraft:composter", + "id": -213 + }, + { + "name": "minecraft:compound", + "id": 605 + }, + { + "name": "minecraft:concrete", + "id": 721 + }, + { + "name": "minecraft:concrete_powder", + "id": 722 + }, + { + "name": "minecraft:conduit", + "id": -157 + }, + { + "name": "minecraft:cooked_beef", + "id": 275 + }, + { + "name": "minecraft:cooked_chicken", + "id": 277 + }, + { + "name": "minecraft:cooked_cod", + "id": 269 + }, + { + "name": "minecraft:cooked_mutton", + "id": 562 + }, + { + "name": "minecraft:cooked_porkchop", + "id": 264 + }, + { + "name": "minecraft:cooked_rabbit", + "id": 290 + }, + { + "name": "minecraft:cooked_salmon", + "id": 270 + }, + { + "name": "minecraft:cookie", + "id": 272 + }, + { + "name": "minecraft:copper_block", + "id": -340 + }, + { + "name": "minecraft:copper_bulb", + "id": -776 + }, + { + "name": "minecraft:copper_door", + "id": -784 + }, + { + "name": "minecraft:copper_grate", + "id": -768 + }, + { + "name": "minecraft:copper_ingot", + "id": 515 + }, + { + "name": "minecraft:copper_ore", + "id": -311 + }, + { + "name": "minecraft:copper_trapdoor", + "id": -792 + }, + { + "name": "minecraft:coral", + "id": 719 + }, + { + "name": "minecraft:coral_block", + "id": -132 + }, + { + "name": "minecraft:coral_fan", + "id": -133 + }, + { + "name": "minecraft:coral_fan_dead", + "id": -134 + }, + { + "name": "minecraft:coral_fan_hang", + "id": -135 + }, + { + "name": "minecraft:coral_fan_hang2", + "id": -136 + }, + { + "name": "minecraft:coral_fan_hang3", + "id": -137 + }, + { + "name": "minecraft:cow_spawn_egg", + "id": 440 + }, + { + "name": "minecraft:cracked_deepslate_bricks", + "id": -410 + }, + { + "name": "minecraft:cracked_deepslate_tiles", + "id": -409 + }, + { + "name": "minecraft:cracked_nether_bricks", + "id": -303 + }, + { + "name": "minecraft:cracked_polished_blackstone_bricks", + "id": -280 + }, + { + "name": "minecraft:crafter", + "id": -313 + }, + { + "name": "minecraft:crafting_table", + "id": 58 + }, + { + "name": "minecraft:creeper_banner_pattern", + "id": 593 + }, + { + "name": "minecraft:creeper_spawn_egg", + "id": 445 + }, + { + "name": "minecraft:crimson_button", + "id": -260 + }, + { + "name": "minecraft:crimson_door", + "id": 627 + }, + { + "name": "minecraft:crimson_double_slab", + "id": -266 + }, + { + "name": "minecraft:crimson_fence", + "id": -256 + }, + { + "name": "minecraft:crimson_fence_gate", + "id": -258 + }, + { + "name": "minecraft:crimson_fungus", + "id": -228 + }, + { + "name": "minecraft:crimson_hanging_sign", + "id": -506 + }, + { + "name": "minecraft:crimson_hyphae", + "id": -299 + }, + { + "name": "minecraft:crimson_nylium", + "id": -232 + }, + { + "name": "minecraft:crimson_planks", + "id": -242 + }, + { + "name": "minecraft:crimson_pressure_plate", + "id": -262 + }, + { + "name": "minecraft:crimson_roots", + "id": -223 + }, + { + "name": "minecraft:crimson_sign", + "id": 625 + }, + { + "name": "minecraft:crimson_slab", + "id": -264 + }, + { + "name": "minecraft:crimson_stairs", + "id": -254 + }, + { + "name": "minecraft:crimson_standing_sign", + "id": -250 + }, + { + "name": "minecraft:crimson_stem", + "id": -225 + }, + { + "name": "minecraft:crimson_trapdoor", + "id": -246 + }, + { + "name": "minecraft:crimson_wall_sign", + "id": -252 + }, + { + "name": "minecraft:crossbow", + "id": 586 + }, + { + "name": "minecraft:crying_obsidian", + "id": -289 + }, + { + "name": "minecraft:cut_copper", + "id": -347 + }, + { + "name": "minecraft:cut_copper_slab", + "id": -361 + }, + { + "name": "minecraft:cut_copper_stairs", + "id": -354 + }, + { + "name": "minecraft:cyan_candle", + "id": -422 + }, + { + "name": "minecraft:cyan_candle_cake", + "id": -439 + }, + { + "name": "minecraft:cyan_carpet", + "id": -605 + }, + { + "name": "minecraft:cyan_concrete", + "id": -636 + }, + { + "name": "minecraft:cyan_concrete_powder", + "id": -717 + }, + { + "name": "minecraft:cyan_dye", + "id": 405 + }, + { + "name": "minecraft:cyan_glazed_terracotta", + "id": 229 + }, + { + "name": "minecraft:cyan_shulker_box", + "id": -621 + }, + { + "name": "minecraft:cyan_stained_glass", + "id": -681 + }, + { + "name": "minecraft:cyan_stained_glass_pane", + "id": -651 + }, + { + "name": "minecraft:cyan_terracotta", + "id": -732 + }, + { + "name": "minecraft:cyan_wool", + "id": -561 + }, + { + "name": "minecraft:danger_pottery_sherd", + "id": 673 + }, + { + "name": "minecraft:dark_oak_boat", + "id": 384 + }, + { + "name": "minecraft:dark_oak_button", + "id": -142 + }, + { + "name": "minecraft:dark_oak_chest_boat", + "id": 654 + }, + { + "name": "minecraft:dark_oak_door", + "id": 568 + }, + { + "name": "minecraft:dark_oak_double_slab", + "id": -813 + }, + { + "name": "minecraft:dark_oak_fence", + "id": -577 + }, + { + "name": "minecraft:dark_oak_fence_gate", + "id": 186 + }, + { + "name": "minecraft:dark_oak_hanging_sign", + "id": -505 + }, + { + "name": "minecraft:dark_oak_leaves", + "id": -803 + }, + { + "name": "minecraft:dark_oak_log", + "id": -572 + }, + { + "name": "minecraft:dark_oak_planks", + "id": -743 + }, + { + "name": "minecraft:dark_oak_pressure_plate", + "id": -152 + }, + { + "name": "minecraft:dark_oak_sign", + "id": 591 + }, + { + "name": "minecraft:dark_oak_slab", + "id": -808 + }, + { + "name": "minecraft:dark_oak_stairs", + "id": 164 + }, + { + "name": "minecraft:dark_oak_trapdoor", + "id": -147 + }, + { + "name": "minecraft:dark_oak_wood", + "id": -818 + }, + { + "name": "minecraft:dark_prismarine_stairs", + "id": -3 + }, + { + "name": "minecraft:darkoak_standing_sign", + "id": -192 + }, + { + "name": "minecraft:darkoak_wall_sign", + "id": -193 + }, + { + "name": "minecraft:daylight_detector", + "id": 151 + }, + { + "name": "minecraft:daylight_detector_inverted", + "id": 178 + }, + { + "name": "minecraft:dead_brain_coral", + "id": -586 + }, + { + "name": "minecraft:dead_bubble_coral", + "id": -587 + }, + { + "name": "minecraft:dead_fire_coral", + "id": -588 + }, + { + "name": "minecraft:dead_horn_coral", + "id": -589 + }, + { + "name": "minecraft:dead_tube_coral", + "id": -585 + }, + { + "name": "minecraft:deadbush", + "id": 32 + }, + { + "name": "minecraft:decorated_pot", + "id": -551 + }, + { + "name": "minecraft:deepslate", + "id": -378 + }, + { + "name": "minecraft:deepslate_brick_double_slab", + "id": -399 + }, + { + "name": "minecraft:deepslate_brick_slab", + "id": -392 + }, + { + "name": "minecraft:deepslate_brick_stairs", + "id": -393 + }, + { + "name": "minecraft:deepslate_brick_wall", + "id": -394 + }, + { + "name": "minecraft:deepslate_bricks", + "id": -391 + }, + { + "name": "minecraft:deepslate_coal_ore", + "id": -406 + }, + { + "name": "minecraft:deepslate_copper_ore", + "id": -408 + }, + { + "name": "minecraft:deepslate_diamond_ore", + "id": -405 + }, + { + "name": "minecraft:deepslate_emerald_ore", + "id": -407 + }, + { + "name": "minecraft:deepslate_gold_ore", + "id": -402 + }, + { + "name": "minecraft:deepslate_iron_ore", + "id": -401 + }, + { + "name": "minecraft:deepslate_lapis_ore", + "id": -400 + }, + { + "name": "minecraft:deepslate_redstone_ore", + "id": -403 + }, + { + "name": "minecraft:deepslate_tile_double_slab", + "id": -398 + }, + { + "name": "minecraft:deepslate_tile_slab", + "id": -388 + }, + { + "name": "minecraft:deepslate_tile_stairs", + "id": -389 + }, + { + "name": "minecraft:deepslate_tile_wall", + "id": -390 + }, + { + "name": "minecraft:deepslate_tiles", + "id": -387 + }, + { + "name": "minecraft:deny", + "id": 211 + }, + { + "name": "minecraft:detector_rail", + "id": 28 + }, + { + "name": "minecraft:diamond", + "id": 307 + }, + { + "name": "minecraft:diamond_axe", + "id": 322 + }, + { + "name": "minecraft:diamond_block", + "id": 57 + }, + { + "name": "minecraft:diamond_boots", + "id": 353 + }, + { + "name": "minecraft:diamond_chestplate", + "id": 351 + }, + { + "name": "minecraft:diamond_helmet", + "id": 350 + }, + { + "name": "minecraft:diamond_hoe", + "id": 335 + }, + { + "name": "minecraft:diamond_horse_armor", + "id": 544 + }, + { + "name": "minecraft:diamond_leggings", + "id": 352 + }, + { + "name": "minecraft:diamond_ore", + "id": 56 + }, + { + "name": "minecraft:diamond_pickaxe", + "id": 321 + }, + { + "name": "minecraft:diamond_shovel", + "id": 320 + }, + { + "name": "minecraft:diamond_sword", + "id": 319 + }, + { + "name": "minecraft:diorite", + "id": -592 + }, + { + "name": "minecraft:diorite_stairs", + "id": -170 + }, + { + "name": "minecraft:dirt", + "id": 3 + }, + { + "name": "minecraft:dirt_with_roots", + "id": -318 + }, + { + "name": "minecraft:disc_fragment_5", + "id": 648 + }, + { + "name": "minecraft:dispenser", + "id": 23 + }, + { + "name": "minecraft:dolphin_spawn_egg", + "id": 489 + }, + { + "name": "minecraft:donkey_spawn_egg", + "id": 470 + }, + { + "name": "minecraft:double_cut_copper_slab", + "id": -368 + }, + { + "name": "minecraft:double_plant", + "id": 175 + }, + { + "name": "minecraft:double_stone_block_slab", + "id": 43 + }, + { + "name": "minecraft:double_stone_block_slab2", + "id": 181 + }, + { + "name": "minecraft:double_stone_block_slab3", + "id": -167 + }, + { + "name": "minecraft:double_stone_block_slab4", + "id": -168 + }, + { + "name": "minecraft:dragon_breath", + "id": 571 + }, + { + "name": "minecraft:dragon_egg", + "id": 122 + }, + { + "name": "minecraft:dried_kelp", + "id": 271 + }, + { + "name": "minecraft:dried_kelp_block", + "id": -139 + }, + { + "name": "minecraft:dripstone_block", + "id": -317 + }, + { + "name": "minecraft:dropper", + "id": 125 + }, + { + "name": "minecraft:drowned_spawn_egg", + "id": 488 + }, + { + "name": "minecraft:dune_armor_trim_smithing_template", + "id": 690 + }, + { + "name": "minecraft:dye", + "id": 730 + }, + { + "name": "minecraft:echo_shard", + "id": 658 + }, + { + "name": "minecraft:egg", + "id": 394 + }, + { + "name": "minecraft:elder_guardian_spawn_egg", + "id": 476 + }, + { + "name": "minecraft:element_0", + "id": 36 + }, + { + "name": "minecraft:element_1", + "id": -12 + }, + { + "name": "minecraft:element_10", + "id": -21 + }, + { + "name": "minecraft:element_100", + "id": -111 + }, + { + "name": "minecraft:element_101", + "id": -112 + }, + { + "name": "minecraft:element_102", + "id": -113 + }, + { + "name": "minecraft:element_103", + "id": -114 + }, + { + "name": "minecraft:element_104", + "id": -115 + }, + { + "name": "minecraft:element_105", + "id": -116 + }, + { + "name": "minecraft:element_106", + "id": -117 + }, + { + "name": "minecraft:element_107", + "id": -118 + }, + { + "name": "minecraft:element_108", + "id": -119 + }, + { + "name": "minecraft:element_109", + "id": -120 + }, + { + "name": "minecraft:element_11", + "id": -22 + }, + { + "name": "minecraft:element_110", + "id": -121 + }, + { + "name": "minecraft:element_111", + "id": -122 + }, + { + "name": "minecraft:element_112", + "id": -123 + }, + { + "name": "minecraft:element_113", + "id": -124 + }, + { + "name": "minecraft:element_114", + "id": -125 + }, + { + "name": "minecraft:element_115", + "id": -126 + }, + { + "name": "minecraft:element_116", + "id": -127 + }, + { + "name": "minecraft:element_117", + "id": -128 + }, + { + "name": "minecraft:element_118", + "id": -129 + }, + { + "name": "minecraft:element_12", + "id": -23 + }, + { + "name": "minecraft:element_13", + "id": -24 + }, + { + "name": "minecraft:element_14", + "id": -25 + }, + { + "name": "minecraft:element_15", + "id": -26 + }, + { + "name": "minecraft:element_16", + "id": -27 + }, + { + "name": "minecraft:element_17", + "id": -28 + }, + { + "name": "minecraft:element_18", + "id": -29 + }, + { + "name": "minecraft:element_19", + "id": -30 + }, + { + "name": "minecraft:element_2", + "id": -13 + }, + { + "name": "minecraft:element_20", + "id": -31 + }, + { + "name": "minecraft:element_21", + "id": -32 + }, + { + "name": "minecraft:element_22", + "id": -33 + }, + { + "name": "minecraft:element_23", + "id": -34 + }, + { + "name": "minecraft:element_24", + "id": -35 + }, + { + "name": "minecraft:element_25", + "id": -36 + }, + { + "name": "minecraft:element_26", + "id": -37 + }, + { + "name": "minecraft:element_27", + "id": -38 + }, + { + "name": "minecraft:element_28", + "id": -39 + }, + { + "name": "minecraft:element_29", + "id": -40 + }, + { + "name": "minecraft:element_3", + "id": -14 + }, + { + "name": "minecraft:element_30", + "id": -41 + }, + { + "name": "minecraft:element_31", + "id": -42 + }, + { + "name": "minecraft:element_32", + "id": -43 + }, + { + "name": "minecraft:element_33", + "id": -44 + }, + { + "name": "minecraft:element_34", + "id": -45 + }, + { + "name": "minecraft:element_35", + "id": -46 + }, + { + "name": "minecraft:element_36", + "id": -47 + }, + { + "name": "minecraft:element_37", + "id": -48 + }, + { + "name": "minecraft:element_38", + "id": -49 + }, + { + "name": "minecraft:element_39", + "id": -50 + }, + { + "name": "minecraft:element_4", + "id": -15 + }, + { + "name": "minecraft:element_40", + "id": -51 + }, + { + "name": "minecraft:element_41", + "id": -52 + }, + { + "name": "minecraft:element_42", + "id": -53 + }, + { + "name": "minecraft:element_43", + "id": -54 + }, + { + "name": "minecraft:element_44", + "id": -55 + }, + { + "name": "minecraft:element_45", + "id": -56 + }, + { + "name": "minecraft:element_46", + "id": -57 + }, + { + "name": "minecraft:element_47", + "id": -58 + }, + { + "name": "minecraft:element_48", + "id": -59 + }, + { + "name": "minecraft:element_49", + "id": -60 + }, + { + "name": "minecraft:element_5", + "id": -16 + }, + { + "name": "minecraft:element_50", + "id": -61 + }, + { + "name": "minecraft:element_51", + "id": -62 + }, + { + "name": "minecraft:element_52", + "id": -63 + }, + { + "name": "minecraft:element_53", + "id": -64 + }, + { + "name": "minecraft:element_54", + "id": -65 + }, + { + "name": "minecraft:element_55", + "id": -66 + }, + { + "name": "minecraft:element_56", + "id": -67 + }, + { + "name": "minecraft:element_57", + "id": -68 + }, + { + "name": "minecraft:element_58", + "id": -69 + }, + { + "name": "minecraft:element_59", + "id": -70 + }, + { + "name": "minecraft:element_6", + "id": -17 + }, + { + "name": "minecraft:element_60", + "id": -71 + }, + { + "name": "minecraft:element_61", + "id": -72 + }, + { + "name": "minecraft:element_62", + "id": -73 + }, + { + "name": "minecraft:element_63", + "id": -74 + }, + { + "name": "minecraft:element_64", + "id": -75 + }, + { + "name": "minecraft:element_65", + "id": -76 + }, + { + "name": "minecraft:element_66", + "id": -77 + }, + { + "name": "minecraft:element_67", + "id": -78 + }, + { + "name": "minecraft:element_68", + "id": -79 + }, + { + "name": "minecraft:element_69", + "id": -80 + }, + { + "name": "minecraft:element_7", + "id": -18 + }, + { + "name": "minecraft:element_70", + "id": -81 + }, + { + "name": "minecraft:element_71", + "id": -82 + }, + { + "name": "minecraft:element_72", + "id": -83 + }, + { + "name": "minecraft:element_73", + "id": -84 + }, + { + "name": "minecraft:element_74", + "id": -85 + }, + { + "name": "minecraft:element_75", + "id": -86 + }, + { + "name": "minecraft:element_76", + "id": -87 + }, + { + "name": "minecraft:element_77", + "id": -88 + }, + { + "name": "minecraft:element_78", + "id": -89 + }, + { + "name": "minecraft:element_79", + "id": -90 + }, + { + "name": "minecraft:element_8", + "id": -19 + }, + { + "name": "minecraft:element_80", + "id": -91 + }, + { + "name": "minecraft:element_81", + "id": -92 + }, + { + "name": "minecraft:element_82", + "id": -93 + }, + { + "name": "minecraft:element_83", + "id": -94 + }, + { + "name": "minecraft:element_84", + "id": -95 + }, + { + "name": "minecraft:element_85", + "id": -96 + }, + { + "name": "minecraft:element_86", + "id": -97 + }, + { + "name": "minecraft:element_87", + "id": -98 + }, + { + "name": "minecraft:element_88", + "id": -99 + }, + { + "name": "minecraft:element_89", + "id": -100 + }, + { + "name": "minecraft:element_9", + "id": -20 + }, + { + "name": "minecraft:element_90", + "id": -101 + }, + { + "name": "minecraft:element_91", + "id": -102 + }, + { + "name": "minecraft:element_92", + "id": -103 + }, + { + "name": "minecraft:element_93", + "id": -104 + }, + { + "name": "minecraft:element_94", + "id": -105 + }, + { + "name": "minecraft:element_95", + "id": -106 + }, + { + "name": "minecraft:element_96", + "id": -107 + }, + { + "name": "minecraft:element_97", + "id": -108 + }, + { + "name": "minecraft:element_98", + "id": -109 + }, + { + "name": "minecraft:element_99", + "id": -110 + }, + { + "name": "minecraft:elytra", + "id": 575 + }, + { + "name": "minecraft:emerald", + "id": 523 + }, + { + "name": "minecraft:emerald_block", + "id": 133 + }, + { + "name": "minecraft:emerald_ore", + "id": 129 + }, + { + "name": "minecraft:empty_map", + "id": 526 + }, + { + "name": "minecraft:enchanted_book", + "id": 532 + }, + { + "name": "minecraft:enchanted_golden_apple", + "id": 260 + }, + { + "name": "minecraft:enchanting_table", + "id": 116 + }, + { + "name": "minecraft:end_brick_stairs", + "id": -178 + }, + { + "name": "minecraft:end_bricks", + "id": 206 + }, + { + "name": "minecraft:end_crystal", + "id": 733 + }, + { + "name": "minecraft:end_gateway", + "id": 209 + }, + { + "name": "minecraft:end_portal", + "id": 119 + }, + { + "name": "minecraft:end_portal_frame", + "id": 120 + }, + { + "name": "minecraft:end_rod", + "id": 208 + }, + { + "name": "minecraft:end_stone", + "id": 121 + }, + { + "name": "minecraft:ender_chest", + "id": 130 + }, + { + "name": "minecraft:ender_dragon_spawn_egg", + "id": 512 + }, + { + "name": "minecraft:ender_eye", + "id": 437 + }, + { + "name": "minecraft:ender_pearl", + "id": 426 + }, + { + "name": "minecraft:enderman_spawn_egg", + "id": 446 + }, + { + "name": "minecraft:endermite_spawn_egg", + "id": 464 + }, + { + "name": "minecraft:evoker_spawn_egg", + "id": 480 + }, + { + "name": "minecraft:experience_bottle", + "id": 519 + }, + { + "name": "minecraft:explorer_pottery_sherd", + "id": 674 + }, + { + "name": "minecraft:exposed_chiseled_copper", + "id": -761 + }, + { + "name": "minecraft:exposed_copper", + "id": -341 + }, + { + "name": "minecraft:exposed_copper_bulb", + "id": -777 + }, + { + "name": "minecraft:exposed_copper_door", + "id": -785 + }, + { + "name": "minecraft:exposed_copper_grate", + "id": -769 + }, + { + "name": "minecraft:exposed_copper_trapdoor", + "id": -793 + }, + { + "name": "minecraft:exposed_cut_copper", + "id": -348 + }, + { + "name": "minecraft:exposed_cut_copper_slab", + "id": -362 + }, + { + "name": "minecraft:exposed_cut_copper_stairs", + "id": -355 + }, + { + "name": "minecraft:exposed_double_cut_copper_slab", + "id": -369 + }, + { + "name": "minecraft:eye_armor_trim_smithing_template", + "id": 694 + }, + { + "name": "minecraft:farmland", + "id": 60 + }, + { + "name": "minecraft:feather", + "id": 330 + }, + { + "name": "minecraft:fence", + "id": 714 + }, + { + "name": "minecraft:fence_gate", + "id": 107 + }, + { + "name": "minecraft:fermented_spider_eye", + "id": 432 + }, + { + "name": "minecraft:field_masoned_banner_pattern", + "id": 596 + }, + { + "name": "minecraft:filled_map", + "id": 424 + }, + { + "name": "minecraft:fire", + "id": 51 + }, + { + "name": "minecraft:fire_charge", + "id": 520 + }, + { + "name": "minecraft:fire_coral", + "id": -583 + }, + { + "name": "minecraft:firework_rocket", + "id": 530 + }, + { + "name": "minecraft:firework_star", + "id": 531 + }, + { + "name": "minecraft:fishing_rod", + "id": 396 + }, + { + "name": "minecraft:fletching_table", + "id": -201 + }, + { + "name": "minecraft:flint", + "id": 359 + }, + { + "name": "minecraft:flint_and_steel", + "id": 302 + }, + { + "name": "minecraft:flower_banner_pattern", + "id": 592 + }, + { + "name": "minecraft:flower_pot", + "id": 525 + }, + { + "name": "minecraft:flowering_azalea", + "id": -338 + }, + { + "name": "minecraft:flowing_lava", + "id": 10 + }, + { + "name": "minecraft:flowing_water", + "id": 8 + }, + { + "name": "minecraft:fox_spawn_egg", + "id": 495 + }, + { + "name": "minecraft:frame", + "id": 524 + }, + { + "name": "minecraft:friend_pottery_sherd", + "id": 675 + }, + { + "name": "minecraft:frog_spawn", + "id": -468 + }, + { + "name": "minecraft:frog_spawn_egg", + "id": 639 + }, + { + "name": "minecraft:frosted_ice", + "id": 207 + }, + { + "name": "minecraft:furnace", + "id": 61 + }, + { + "name": "minecraft:ghast_spawn_egg", + "id": 458 + }, + { + "name": "minecraft:ghast_tear", + "id": 428 + }, + { + "name": "minecraft:gilded_blackstone", + "id": -281 + }, + { + "name": "minecraft:glass", + "id": 20 + }, + { + "name": "minecraft:glass_bottle", + "id": 431 + }, + { + "name": "minecraft:glass_pane", + "id": 102 + }, + { + "name": "minecraft:glistering_melon_slice", + "id": 438 + }, + { + "name": "minecraft:globe_banner_pattern", + "id": 599 + }, + { + "name": "minecraft:glow_berries", + "id": 734 + }, + { + "name": "minecraft:glow_frame", + "id": 634 + }, + { + "name": "minecraft:glow_ink_sac", + "id": 514 + }, + { + "name": "minecraft:glow_lichen", + "id": -411 + }, + { + "name": "minecraft:glow_squid_spawn_egg", + "id": 509 + }, + { + "name": "minecraft:glow_stick", + "id": 612 + }, + { + "name": "minecraft:glowingobsidian", + "id": 246 + }, + { + "name": "minecraft:glowstone", + "id": 89 + }, + { + "name": "minecraft:glowstone_dust", + "id": 398 + }, + { + "name": "minecraft:goat_horn", + "id": 638 + }, + { + "name": "minecraft:goat_spawn_egg", + "id": 508 + }, + { + "name": "minecraft:gold_block", + "id": 41 + }, + { + "name": "minecraft:gold_ingot", + "id": 309 + }, + { + "name": "minecraft:gold_nugget", + "id": 429 + }, + { + "name": "minecraft:gold_ore", + "id": 14 + }, + { + "name": "minecraft:golden_apple", + "id": 259 + }, + { + "name": "minecraft:golden_axe", + "id": 328 + }, + { + "name": "minecraft:golden_boots", + "id": 357 + }, + { + "name": "minecraft:golden_carrot", + "id": 284 + }, + { + "name": "minecraft:golden_chestplate", + "id": 355 + }, + { + "name": "minecraft:golden_helmet", + "id": 354 + }, + { + "name": "minecraft:golden_hoe", + "id": 336 + }, + { + "name": "minecraft:golden_horse_armor", + "id": 543 + }, + { + "name": "minecraft:golden_leggings", + "id": 356 + }, + { + "name": "minecraft:golden_pickaxe", + "id": 327 + }, + { + "name": "minecraft:golden_rail", + "id": 27 + }, + { + "name": "minecraft:golden_shovel", + "id": 326 + }, + { + "name": "minecraft:golden_sword", + "id": 325 + }, + { + "name": "minecraft:granite", + "id": -590 + }, + { + "name": "minecraft:granite_stairs", + "id": -169 + }, + { + "name": "minecraft:grass_block", + "id": 2 + }, + { + "name": "minecraft:grass_path", + "id": 198 + }, + { + "name": "minecraft:gravel", + "id": 13 + }, + { + "name": "minecraft:gray_candle", + "id": -420 + }, + { + "name": "minecraft:gray_candle_cake", + "id": -437 + }, + { + "name": "minecraft:gray_carpet", + "id": -603 + }, + { + "name": "minecraft:gray_concrete", + "id": -634 + }, + { + "name": "minecraft:gray_concrete_powder", + "id": -715 + }, + { + "name": "minecraft:gray_dye", + "id": 407 + }, + { + "name": "minecraft:gray_glazed_terracotta", + "id": 227 + }, + { + "name": "minecraft:gray_shulker_box", + "id": -619 + }, + { + "name": "minecraft:gray_stained_glass", + "id": -679 + }, + { + "name": "minecraft:gray_stained_glass_pane", + "id": -649 + }, + { + "name": "minecraft:gray_terracotta", + "id": -730 + }, + { + "name": "minecraft:gray_wool", + "id": -553 + }, + { + "name": "minecraft:green_candle", + "id": -426 + }, + { + "name": "minecraft:green_candle_cake", + "id": -443 + }, + { + "name": "minecraft:green_carpet", + "id": -609 + }, + { + "name": "minecraft:green_concrete", + "id": -640 + }, + { + "name": "minecraft:green_concrete_powder", + "id": -721 + }, + { + "name": "minecraft:green_dye", + "id": 401 + }, + { + "name": "minecraft:green_glazed_terracotta", + "id": 233 + }, + { + "name": "minecraft:green_shulker_box", + "id": -625 + }, + { + "name": "minecraft:green_stained_glass", + "id": -685 + }, + { + "name": "minecraft:green_stained_glass_pane", + "id": -655 + }, + { + "name": "minecraft:green_terracotta", + "id": -736 + }, + { + "name": "minecraft:green_wool", + "id": -560 + }, + { + "name": "minecraft:grindstone", + "id": -195 + }, + { + "name": "minecraft:guardian_spawn_egg", + "id": 465 + }, + { + "name": "minecraft:gunpowder", + "id": 331 + }, + { + "name": "minecraft:hanging_roots", + "id": -319 + }, + { + "name": "minecraft:hard_black_stained_glass", + "id": -702 + }, + { + "name": "minecraft:hard_black_stained_glass_pane", + "id": -672 + }, + { + "name": "minecraft:hard_blue_stained_glass", + "id": -698 + }, + { + "name": "minecraft:hard_blue_stained_glass_pane", + "id": -668 + }, + { + "name": "minecraft:hard_brown_stained_glass", + "id": -699 + }, + { + "name": "minecraft:hard_brown_stained_glass_pane", + "id": -669 + }, + { + "name": "minecraft:hard_cyan_stained_glass", + "id": -696 + }, + { + "name": "minecraft:hard_cyan_stained_glass_pane", + "id": -666 + }, + { + "name": "minecraft:hard_glass", + "id": 253 + }, + { + "name": "minecraft:hard_glass_pane", + "id": 190 + }, + { + "name": "minecraft:hard_gray_stained_glass", + "id": -694 + }, + { + "name": "minecraft:hard_gray_stained_glass_pane", + "id": -664 + }, + { + "name": "minecraft:hard_green_stained_glass", + "id": -700 + }, + { + "name": "minecraft:hard_green_stained_glass_pane", + "id": -670 + }, + { + "name": "minecraft:hard_light_blue_stained_glass", + "id": -690 + }, + { + "name": "minecraft:hard_light_blue_stained_glass_pane", + "id": -660 + }, + { + "name": "minecraft:hard_light_gray_stained_glass", + "id": -695 + }, + { + "name": "minecraft:hard_light_gray_stained_glass_pane", + "id": -665 + }, + { + "name": "minecraft:hard_lime_stained_glass", + "id": -692 + }, + { + "name": "minecraft:hard_lime_stained_glass_pane", + "id": -662 + }, + { + "name": "minecraft:hard_magenta_stained_glass", + "id": -689 + }, + { + "name": "minecraft:hard_magenta_stained_glass_pane", + "id": -659 + }, + { + "name": "minecraft:hard_orange_stained_glass", + "id": -688 + }, + { + "name": "minecraft:hard_orange_stained_glass_pane", + "id": -658 + }, + { + "name": "minecraft:hard_pink_stained_glass", + "id": -693 + }, + { + "name": "minecraft:hard_pink_stained_glass_pane", + "id": -663 + }, + { + "name": "minecraft:hard_purple_stained_glass", + "id": -697 + }, + { + "name": "minecraft:hard_purple_stained_glass_pane", + "id": -667 + }, + { + "name": "minecraft:hard_red_stained_glass", + "id": -701 + }, + { + "name": "minecraft:hard_red_stained_glass_pane", + "id": -671 + }, + { + "name": "minecraft:hard_stained_glass", + "id": 727 + }, + { + "name": "minecraft:hard_stained_glass_pane", + "id": 728 + }, + { + "name": "minecraft:hard_white_stained_glass", + "id": 254 + }, + { + "name": "minecraft:hard_white_stained_glass_pane", + "id": 191 + }, + { + "name": "minecraft:hard_yellow_stained_glass", + "id": -691 + }, + { + "name": "minecraft:hard_yellow_stained_glass_pane", + "id": -661 + }, + { + "name": "minecraft:hardened_clay", + "id": 172 + }, + { + "name": "minecraft:hay_block", + "id": 170 + }, + { + "name": "minecraft:heart_of_the_sea", + "id": 582 + }, + { + "name": "minecraft:heart_pottery_sherd", + "id": 676 + }, + { + "name": "minecraft:heartbreak_pottery_sherd", + "id": 677 + }, + { + "name": "minecraft:heavy_weighted_pressure_plate", + "id": 148 + }, + { + "name": "minecraft:hoglin_spawn_egg", + "id": 501 + }, + { + "name": "minecraft:honey_block", + "id": -220 + }, + { + "name": "minecraft:honey_bottle", + "id": 603 + }, + { + "name": "minecraft:honeycomb", + "id": 602 + }, + { + "name": "minecraft:honeycomb_block", + "id": -221 + }, + { + "name": "minecraft:hopper", + "id": 538 + }, + { + "name": "minecraft:hopper_minecart", + "id": 537 + }, + { + "name": "minecraft:horn_coral", + "id": -584 + }, + { + "name": "minecraft:horse_spawn_egg", + "id": 462 + }, + { + "name": "minecraft:host_armor_trim_smithing_template", + "id": 704 + }, + { + "name": "minecraft:howl_pottery_sherd", + "id": 678 + }, + { + "name": "minecraft:husk_spawn_egg", + "id": 468 + }, + { + "name": "minecraft:ice", + "id": 79 + }, + { + "name": "minecraft:ice_bomb", + "id": 606 + }, + { + "name": "minecraft:infested_deepslate", + "id": -454 + }, + { + "name": "minecraft:info_update", + "id": 248 + }, + { + "name": "minecraft:info_update2", + "id": 249 + }, + { + "name": "minecraft:ink_sac", + "id": 417 + }, + { + "name": "minecraft:invisible_bedrock", + "id": 95 + }, + { + "name": "minecraft:iron_axe", + "id": 301 + }, + { + "name": "minecraft:iron_bars", + "id": 101 + }, + { + "name": "minecraft:iron_block", + "id": 42 + }, + { + "name": "minecraft:iron_boots", + "id": 349 + }, + { + "name": "minecraft:iron_chestplate", + "id": 347 + }, + { + "name": "minecraft:iron_door", + "id": 375 + }, + { + "name": "minecraft:iron_golem_spawn_egg", + "id": 510 + }, + { + "name": "minecraft:iron_helmet", + "id": 346 + }, + { + "name": "minecraft:iron_hoe", + "id": 334 + }, + { + "name": "minecraft:iron_horse_armor", + "id": 542 + }, + { + "name": "minecraft:iron_ingot", + "id": 308 + }, + { + "name": "minecraft:iron_leggings", + "id": 348 + }, + { + "name": "minecraft:iron_nugget", + "id": 580 + }, + { + "name": "minecraft:iron_ore", + "id": 15 + }, + { + "name": "minecraft:iron_pickaxe", + "id": 300 + }, + { + "name": "minecraft:iron_shovel", + "id": 299 + }, + { + "name": "minecraft:iron_sword", + "id": 310 + }, + { + "name": "minecraft:iron_trapdoor", + "id": 167 + }, + { + "name": "minecraft:item.acacia_door", + "id": 196 + }, + { + "name": "minecraft:item.bed", + "id": 26 + }, + { + "name": "minecraft:item.beetroot", + "id": 244 + }, + { + "name": "minecraft:item.birch_door", + "id": 194 + }, + { + "name": "minecraft:item.brewing_stand", + "id": 117 + }, + { + "name": "minecraft:item.cake", + "id": 92 + }, + { + "name": "minecraft:item.camera", + "id": 242 + }, + { + "name": "minecraft:item.campfire", + "id": -209 + }, + { + "name": "minecraft:item.cauldron", + "id": 118 + }, + { + "name": "minecraft:item.chain", + "id": -286 + }, + { + "name": "minecraft:item.crimson_door", + "id": -244 + }, + { + "name": "minecraft:item.dark_oak_door", + "id": 197 + }, + { + "name": "minecraft:item.flower_pot", + "id": 140 + }, + { + "name": "minecraft:item.frame", + "id": 199 + }, + { + "name": "minecraft:item.glow_frame", + "id": -339 + }, + { + "name": "minecraft:item.hopper", + "id": 154 + }, + { + "name": "minecraft:item.iron_door", + "id": 71 + }, + { + "name": "minecraft:item.jungle_door", + "id": 195 + }, + { + "name": "minecraft:item.kelp", + "id": -138 + }, + { + "name": "minecraft:item.mangrove_door", + "id": -493 + }, + { + "name": "minecraft:item.nether_sprouts", + "id": -238 + }, + { + "name": "minecraft:item.nether_wart", + "id": 115 + }, + { + "name": "minecraft:item.reeds", + "id": 83 + }, + { + "name": "minecraft:item.skull", + "id": 144 + }, + { + "name": "minecraft:item.soul_campfire", + "id": -290 + }, + { + "name": "minecraft:item.spruce_door", + "id": 193 + }, + { + "name": "minecraft:item.warped_door", + "id": -245 + }, + { + "name": "minecraft:item.wheat", + "id": 59 + }, + { + "name": "minecraft:item.wooden_door", + "id": 64 + }, + { + "name": "minecraft:jigsaw", + "id": -211 + }, + { + "name": "minecraft:jukebox", + "id": 84 + }, + { + "name": "minecraft:jungle_boat", + "id": 381 + }, + { + "name": "minecraft:jungle_button", + "id": -143 + }, + { + "name": "minecraft:jungle_chest_boat", + "id": 651 + }, + { + "name": "minecraft:jungle_door", + "id": 566 + }, + { + "name": "minecraft:jungle_double_slab", + "id": -811 + }, + { + "name": "minecraft:jungle_fence", + "id": -578 + }, + { + "name": "minecraft:jungle_fence_gate", + "id": 185 + }, + { + "name": "minecraft:jungle_hanging_sign", + "id": -503 + }, + { + "name": "minecraft:jungle_leaves", + "id": -802 + }, + { + "name": "minecraft:jungle_log", + "id": -571 + }, + { + "name": "minecraft:jungle_planks", + "id": -741 + }, + { + "name": "minecraft:jungle_pressure_plate", + "id": -153 + }, + { + "name": "minecraft:jungle_sign", + "id": 589 + }, + { + "name": "minecraft:jungle_slab", + "id": -806 + }, + { + "name": "minecraft:jungle_stairs", + "id": 136 + }, + { + "name": "minecraft:jungle_standing_sign", + "id": -188 + }, + { + "name": "minecraft:jungle_trapdoor", + "id": -148 + }, + { + "name": "minecraft:jungle_wall_sign", + "id": -189 + }, + { + "name": "minecraft:jungle_wood", + "id": -816 + }, + { + "name": "minecraft:kelp", + "id": 386 + }, + { + "name": "minecraft:ladder", + "id": 65 + }, + { + "name": "minecraft:lantern", + "id": -208 + }, + { + "name": "minecraft:lapis_block", + "id": 22 + }, + { + "name": "minecraft:lapis_lazuli", + "id": 418 + }, + { + "name": "minecraft:lapis_ore", + "id": 21 + }, + { + "name": "minecraft:large_amethyst_bud", + "id": -330 + }, + { + "name": "minecraft:lava", + "id": 11 + }, + { + "name": "minecraft:lava_bucket", + "id": 366 + }, + { + "name": "minecraft:lead", + "id": 558 + }, + { + "name": "minecraft:leather", + "id": 385 + }, + { + "name": "minecraft:leather_boots", + "id": 341 + }, + { + "name": "minecraft:leather_chestplate", + "id": 339 + }, + { + "name": "minecraft:leather_helmet", + "id": 338 + }, + { + "name": "minecraft:leather_horse_armor", + "id": 541 + }, + { + "name": "minecraft:leather_leggings", + "id": 340 + }, + { + "name": "minecraft:leaves", + "id": 715 + }, + { + "name": "minecraft:leaves2", + "id": 716 + }, + { + "name": "minecraft:lectern", + "id": -194 + }, + { + "name": "minecraft:lever", + "id": 69 + }, + { + "name": "minecraft:light_block", + "id": -215 + }, + { + "name": "minecraft:light_blue_candle", + "id": -416 + }, + { + "name": "minecraft:light_blue_candle_cake", + "id": -433 + }, + { + "name": "minecraft:light_blue_carpet", + "id": -599 + }, + { + "name": "minecraft:light_blue_concrete", + "id": -630 + }, + { + "name": "minecraft:light_blue_concrete_powder", + "id": -711 + }, + { + "name": "minecraft:light_blue_dye", + "id": 411 + }, + { + "name": "minecraft:light_blue_glazed_terracotta", + "id": 223 + }, + { + "name": "minecraft:light_blue_shulker_box", + "id": -615 + }, + { + "name": "minecraft:light_blue_stained_glass", + "id": -675 + }, + { + "name": "minecraft:light_blue_stained_glass_pane", + "id": -645 + }, + { + "name": "minecraft:light_blue_terracotta", + "id": -726 + }, + { + "name": "minecraft:light_blue_wool", + "id": -562 + }, + { + "name": "minecraft:light_gray_candle", + "id": -421 + }, + { + "name": "minecraft:light_gray_candle_cake", + "id": -438 + }, + { + "name": "minecraft:light_gray_carpet", + "id": -604 + }, + { + "name": "minecraft:light_gray_concrete", + "id": -635 + }, + { + "name": "minecraft:light_gray_concrete_powder", + "id": -716 + }, + { + "name": "minecraft:light_gray_dye", + "id": 406 + }, + { + "name": "minecraft:light_gray_shulker_box", + "id": -620 + }, + { + "name": "minecraft:light_gray_stained_glass", + "id": -680 + }, + { + "name": "minecraft:light_gray_stained_glass_pane", + "id": -650 + }, + { + "name": "minecraft:light_gray_terracotta", + "id": -731 + }, + { + "name": "minecraft:light_gray_wool", + "id": -552 + }, + { + "name": "minecraft:light_weighted_pressure_plate", + "id": 147 + }, + { + "name": "minecraft:lightning_rod", + "id": -312 + }, + { + "name": "minecraft:lime_candle", + "id": -418 + }, + { + "name": "minecraft:lime_candle_cake", + "id": -435 + }, + { + "name": "minecraft:lime_carpet", + "id": -601 + }, + { + "name": "minecraft:lime_concrete", + "id": -632 + }, + { + "name": "minecraft:lime_concrete_powder", + "id": -713 + }, + { + "name": "minecraft:lime_dye", + "id": 409 + }, + { + "name": "minecraft:lime_glazed_terracotta", + "id": 225 + }, + { + "name": "minecraft:lime_shulker_box", + "id": -617 + }, + { + "name": "minecraft:lime_stained_glass", + "id": -677 + }, + { + "name": "minecraft:lime_stained_glass_pane", + "id": -647 + }, + { + "name": "minecraft:lime_terracotta", + "id": -728 + }, + { + "name": "minecraft:lime_wool", + "id": -559 + }, + { + "name": "minecraft:lingering_potion", + "id": 573 + }, + { + "name": "minecraft:lit_blast_furnace", + "id": -214 + }, + { + "name": "minecraft:lit_deepslate_redstone_ore", + "id": -404 + }, + { + "name": "minecraft:lit_furnace", + "id": 62 + }, + { + "name": "minecraft:lit_pumpkin", + "id": 91 + }, + { + "name": "minecraft:lit_redstone_lamp", + "id": 124 + }, + { + "name": "minecraft:lit_redstone_ore", + "id": 74 + }, + { + "name": "minecraft:lit_smoker", + "id": -199 + }, + { + "name": "minecraft:llama_spawn_egg", + "id": 478 + }, + { + "name": "minecraft:lodestone", + "id": -222 + }, + { + "name": "minecraft:lodestone_compass", + "id": 613 + }, + { + "name": "minecraft:log", + "id": 713 + }, + { + "name": "minecraft:log2", + "id": 720 + }, + { + "name": "minecraft:loom", + "id": -204 + }, + { + "name": "minecraft:magenta_candle", + "id": -415 + }, + { + "name": "minecraft:magenta_candle_cake", + "id": -432 + }, + { + "name": "minecraft:magenta_carpet", + "id": -598 + }, + { + "name": "minecraft:magenta_concrete", + "id": -629 + }, + { + "name": "minecraft:magenta_concrete_powder", + "id": -710 + }, + { + "name": "minecraft:magenta_dye", + "id": 412 + }, + { + "name": "minecraft:magenta_glazed_terracotta", + "id": 222 + }, + { + "name": "minecraft:magenta_shulker_box", + "id": -614 + }, + { + "name": "minecraft:magenta_stained_glass", + "id": -674 + }, + { + "name": "minecraft:magenta_stained_glass_pane", + "id": -644 + }, + { + "name": "minecraft:magenta_terracotta", + "id": -725 + }, + { + "name": "minecraft:magenta_wool", + "id": -565 + }, + { + "name": "minecraft:magma", + "id": 213 + }, + { + "name": "minecraft:magma_cream", + "id": 434 + }, + { + "name": "minecraft:magma_cube_spawn_egg", + "id": 459 + }, + { + "name": "minecraft:mangrove_boat", + "id": 646 + }, + { + "name": "minecraft:mangrove_button", + "id": -487 + }, + { + "name": "minecraft:mangrove_chest_boat", + "id": 655 + }, + { + "name": "minecraft:mangrove_door", + "id": 644 + }, + { + "name": "minecraft:mangrove_double_slab", + "id": -499 + }, + { + "name": "minecraft:mangrove_fence", + "id": -491 + }, + { + "name": "minecraft:mangrove_fence_gate", + "id": -492 + }, + { + "name": "minecraft:mangrove_hanging_sign", + "id": -508 + }, + { + "name": "minecraft:mangrove_leaves", + "id": -472 + }, + { + "name": "minecraft:mangrove_log", + "id": -484 + }, + { + "name": "minecraft:mangrove_planks", + "id": -486 + }, + { + "name": "minecraft:mangrove_pressure_plate", + "id": -490 + }, + { + "name": "minecraft:mangrove_propagule", + "id": -474 + }, + { + "name": "minecraft:mangrove_roots", + "id": -482 + }, + { + "name": "minecraft:mangrove_sign", + "id": 645 + }, + { + "name": "minecraft:mangrove_slab", + "id": -489 + }, + { + "name": "minecraft:mangrove_stairs", + "id": -488 + }, + { + "name": "minecraft:mangrove_standing_sign", + "id": -494 + }, + { + "name": "minecraft:mangrove_trapdoor", + "id": -496 + }, + { + "name": "minecraft:mangrove_wall_sign", + "id": -495 + }, + { + "name": "minecraft:mangrove_wood", + "id": -497 + }, + { + "name": "minecraft:medicine", + "id": 610 + }, + { + "name": "minecraft:medium_amethyst_bud", + "id": -331 + }, + { + "name": "minecraft:melon_block", + "id": 103 + }, + { + "name": "minecraft:melon_seeds", + "id": 294 + }, + { + "name": "minecraft:melon_slice", + "id": 273 + }, + { + "name": "minecraft:melon_stem", + "id": 105 + }, + { + "name": "minecraft:milk_bucket", + "id": 364 + }, + { + "name": "minecraft:minecart", + "id": 373 + }, + { + "name": "minecraft:miner_pottery_sherd", + "id": 679 + }, + { + "name": "minecraft:mob_spawner", + "id": 52 + }, + { + "name": "minecraft:mojang_banner_pattern", + "id": 595 + }, + { + "name": "minecraft:monster_egg", + "id": 97 + }, + { + "name": "minecraft:mooshroom_spawn_egg", + "id": 444 + }, + { + "name": "minecraft:moss_block", + "id": -320 + }, + { + "name": "minecraft:moss_carpet", + "id": -335 + }, + { + "name": "minecraft:mossy_cobblestone", + "id": 48 + }, + { + "name": "minecraft:mossy_cobblestone_stairs", + "id": -179 + }, + { + "name": "minecraft:mossy_stone_brick_stairs", + "id": -175 + }, + { + "name": "minecraft:mourner_pottery_sherd", + "id": 680 + }, + { + "name": "minecraft:moving_block", + "id": 250 + }, + { + "name": "minecraft:mud", + "id": -473 + }, + { + "name": "minecraft:mud_brick_double_slab", + "id": -479 + }, + { + "name": "minecraft:mud_brick_slab", + "id": -478 + }, + { + "name": "minecraft:mud_brick_stairs", + "id": -480 + }, + { + "name": "minecraft:mud_brick_wall", + "id": -481 + }, + { + "name": "minecraft:mud_bricks", + "id": -475 + }, + { + "name": "minecraft:muddy_mangrove_roots", + "id": -483 + }, + { + "name": "minecraft:mule_spawn_egg", + "id": 471 + }, + { + "name": "minecraft:mushroom_stew", + "id": 261 + }, + { + "name": "minecraft:music_disc_11", + "id": 555 + }, + { + "name": "minecraft:music_disc_13", + "id": 545 + }, + { + "name": "minecraft:music_disc_5", + "id": 647 + }, + { + "name": "minecraft:music_disc_blocks", + "id": 547 + }, + { + "name": "minecraft:music_disc_cat", + "id": 546 + }, + { + "name": "minecraft:music_disc_chirp", + "id": 548 + }, + { + "name": "minecraft:music_disc_far", + "id": 549 + }, + { + "name": "minecraft:music_disc_mall", + "id": 550 + }, + { + "name": "minecraft:music_disc_mellohi", + "id": 551 + }, + { + "name": "minecraft:music_disc_otherside", + "id": 637 + }, + { + "name": "minecraft:music_disc_pigstep", + "id": 631 + }, + { + "name": "minecraft:music_disc_relic", + "id": 705 + }, + { + "name": "minecraft:music_disc_stal", + "id": 552 + }, + { + "name": "minecraft:music_disc_strad", + "id": 553 + }, + { + "name": "minecraft:music_disc_wait", + "id": 556 + }, + { + "name": "minecraft:music_disc_ward", + "id": 554 + }, + { + "name": "minecraft:mutton", + "id": 561 + }, + { + "name": "minecraft:mycelium", + "id": 110 + }, + { + "name": "minecraft:name_tag", + "id": 559 + }, + { + "name": "minecraft:nautilus_shell", + "id": 581 + }, + { + "name": "minecraft:nether_brick", + "id": 112 + }, + { + "name": "minecraft:nether_brick_fence", + "id": 113 + }, + { + "name": "minecraft:nether_brick_stairs", + "id": 114 + }, + { + "name": "minecraft:nether_gold_ore", + "id": -288 + }, + { + "name": "minecraft:nether_sprouts", + "id": 632 + }, + { + "name": "minecraft:nether_star", + "id": 529 + }, + { + "name": "minecraft:nether_wart", + "id": 295 + }, + { + "name": "minecraft:nether_wart_block", + "id": 214 + }, + { + "name": "minecraft:netherbrick", + "id": 534 + }, + { + "name": "minecraft:netherite_axe", + "id": 617 + }, + { + "name": "minecraft:netherite_block", + "id": -270 + }, + { + "name": "minecraft:netherite_boots", + "id": 623 + }, + { + "name": "minecraft:netherite_chestplate", + "id": 621 + }, + { + "name": "minecraft:netherite_helmet", + "id": 620 + }, + { + "name": "minecraft:netherite_hoe", + "id": 618 + }, + { + "name": "minecraft:netherite_ingot", + "id": 619 + }, + { + "name": "minecraft:netherite_leggings", + "id": 622 + }, + { + "name": "minecraft:netherite_pickaxe", + "id": 616 + }, + { + "name": "minecraft:netherite_scrap", + "id": 624 + }, + { + "name": "minecraft:netherite_shovel", + "id": 615 + }, + { + "name": "minecraft:netherite_sword", + "id": 614 + }, + { + "name": "minecraft:netherite_upgrade_smithing_template", + "id": 688 + }, + { + "name": "minecraft:netherrack", + "id": 87 + }, + { + "name": "minecraft:netherreactor", + "id": 247 + }, + { + "name": "minecraft:normal_stone_stairs", + "id": -180 + }, + { + "name": "minecraft:noteblock", + "id": 25 + }, + { + "name": "minecraft:npc_spawn_egg", + "id": 475 + }, + { + "name": "minecraft:oak_boat", + "id": 379 + }, + { + "name": "minecraft:oak_chest_boat", + "id": 649 + }, + { + "name": "minecraft:oak_double_slab", + "id": 157 + }, + { + "name": "minecraft:oak_fence", + "id": 85 + }, + { + "name": "minecraft:oak_hanging_sign", + "id": -500 + }, + { + "name": "minecraft:oak_leaves", + "id": 18 + }, + { + "name": "minecraft:oak_log", + "id": 17 + }, + { + "name": "minecraft:oak_planks", + "id": 5 + }, + { + "name": "minecraft:oak_sign", + "id": 361 + }, + { + "name": "minecraft:oak_slab", + "id": 158 + }, + { + "name": "minecraft:oak_stairs", + "id": 53 + }, + { + "name": "minecraft:oak_wood", + "id": -212 + }, + { + "name": "minecraft:observer", + "id": 251 + }, + { + "name": "minecraft:obsidian", + "id": 49 + }, + { + "name": "minecraft:ocelot_spawn_egg", + "id": 455 + }, + { + "name": "minecraft:ochre_froglight", + "id": -471 + }, + { + "name": "minecraft:orange_candle", + "id": -414 + }, + { + "name": "minecraft:orange_candle_cake", + "id": -431 + }, + { + "name": "minecraft:orange_carpet", + "id": -597 + }, + { + "name": "minecraft:orange_concrete", + "id": -628 + }, + { + "name": "minecraft:orange_concrete_powder", + "id": -709 + }, + { + "name": "minecraft:orange_dye", + "id": 413 + }, + { + "name": "minecraft:orange_glazed_terracotta", + "id": 221 + }, + { + "name": "minecraft:orange_shulker_box", + "id": -613 + }, + { + "name": "minecraft:orange_stained_glass", + "id": -673 + }, + { + "name": "minecraft:orange_stained_glass_pane", + "id": -643 + }, + { + "name": "minecraft:orange_terracotta", + "id": -724 + }, + { + "name": "minecraft:orange_wool", + "id": -557 + }, + { + "name": "minecraft:oxidized_chiseled_copper", + "id": -763 + }, + { + "name": "minecraft:oxidized_copper", + "id": -343 + }, + { + "name": "minecraft:oxidized_copper_bulb", + "id": -779 + }, + { + "name": "minecraft:oxidized_copper_door", + "id": -787 + }, + { + "name": "minecraft:oxidized_copper_grate", + "id": -771 + }, + { + "name": "minecraft:oxidized_copper_trapdoor", + "id": -795 + }, + { + "name": "minecraft:oxidized_cut_copper", + "id": -350 + }, + { + "name": "minecraft:oxidized_cut_copper_slab", + "id": -364 + }, + { + "name": "minecraft:oxidized_cut_copper_stairs", + "id": -357 + }, + { + "name": "minecraft:oxidized_double_cut_copper_slab", + "id": -371 + }, + { + "name": "minecraft:packed_ice", + "id": 174 + }, + { + "name": "minecraft:packed_mud", + "id": -477 + }, + { + "name": "minecraft:painting", + "id": 360 + }, + { + "name": "minecraft:panda_spawn_egg", + "id": 494 + }, + { + "name": "minecraft:paper", + "id": 390 + }, + { + "name": "minecraft:parrot_spawn_egg", + "id": 483 + }, + { + "name": "minecraft:pearlescent_froglight", + "id": -469 + }, + { + "name": "minecraft:phantom_membrane", + "id": 585 + }, + { + "name": "minecraft:phantom_spawn_egg", + "id": 491 + }, + { + "name": "minecraft:pig_spawn_egg", + "id": 441 + }, + { + "name": "minecraft:piglin_banner_pattern", + "id": 598 + }, + { + "name": "minecraft:piglin_brute_spawn_egg", + "id": 504 + }, + { + "name": "minecraft:piglin_spawn_egg", + "id": 502 + }, + { + "name": "minecraft:pillager_spawn_egg", + "id": 496 + }, + { + "name": "minecraft:pink_candle", + "id": -419 + }, + { + "name": "minecraft:pink_candle_cake", + "id": -436 + }, + { + "name": "minecraft:pink_carpet", + "id": -602 + }, + { + "name": "minecraft:pink_concrete", + "id": -633 + }, + { + "name": "minecraft:pink_concrete_powder", + "id": -714 + }, + { + "name": "minecraft:pink_dye", + "id": 408 + }, + { + "name": "minecraft:pink_glazed_terracotta", + "id": 226 + }, + { + "name": "minecraft:pink_petals", + "id": -549 + }, + { + "name": "minecraft:pink_shulker_box", + "id": -618 + }, + { + "name": "minecraft:pink_stained_glass", + "id": -678 + }, + { + "name": "minecraft:pink_stained_glass_pane", + "id": -648 + }, + { + "name": "minecraft:pink_terracotta", + "id": -729 + }, + { + "name": "minecraft:pink_wool", + "id": -566 + }, + { + "name": "minecraft:piston", + "id": 33 + }, + { + "name": "minecraft:piston_arm_collision", + "id": 34 + }, + { + "name": "minecraft:pitcher_crop", + "id": -574 + }, + { + "name": "minecraft:pitcher_plant", + "id": -612 + }, + { + "name": "minecraft:pitcher_pod", + "id": 298 + }, + { + "name": "minecraft:planks", + "id": 718 + }, + { + "name": "minecraft:plenty_pottery_sherd", + "id": 681 + }, + { + "name": "minecraft:podzol", + "id": 243 + }, + { + "name": "minecraft:pointed_dripstone", + "id": -308 + }, + { + "name": "minecraft:poisonous_potato", + "id": 283 + }, + { + "name": "minecraft:polar_bear_spawn_egg", + "id": 477 + }, + { + "name": "minecraft:polished_andesite", + "id": -595 + }, + { + "name": "minecraft:polished_andesite_stairs", + "id": -174 + }, + { + "name": "minecraft:polished_basalt", + "id": -235 + }, + { + "name": "minecraft:polished_blackstone", + "id": -291 + }, + { + "name": "minecraft:polished_blackstone_brick_double_slab", + "id": -285 + }, + { + "name": "minecraft:polished_blackstone_brick_slab", + "id": -284 + }, + { + "name": "minecraft:polished_blackstone_brick_stairs", + "id": -275 + }, + { + "name": "minecraft:polished_blackstone_brick_wall", + "id": -278 + }, + { + "name": "minecraft:polished_blackstone_bricks", + "id": -274 + }, + { + "name": "minecraft:polished_blackstone_button", + "id": -296 + }, + { + "name": "minecraft:polished_blackstone_double_slab", + "id": -294 + }, + { + "name": "minecraft:polished_blackstone_pressure_plate", + "id": -295 + }, + { + "name": "minecraft:polished_blackstone_slab", + "id": -293 + }, + { + "name": "minecraft:polished_blackstone_stairs", + "id": -292 + }, + { + "name": "minecraft:polished_blackstone_wall", + "id": -297 + }, + { + "name": "minecraft:polished_deepslate", + "id": -383 + }, + { + "name": "minecraft:polished_deepslate_double_slab", + "id": -397 + }, + { + "name": "minecraft:polished_deepslate_slab", + "id": -384 + }, + { + "name": "minecraft:polished_deepslate_stairs", + "id": -385 + }, + { + "name": "minecraft:polished_deepslate_wall", + "id": -386 + }, + { + "name": "minecraft:polished_diorite", + "id": -593 + }, + { + "name": "minecraft:polished_diorite_stairs", + "id": -173 + }, + { + "name": "minecraft:polished_granite", + "id": -591 + }, + { + "name": "minecraft:polished_granite_stairs", + "id": -172 + }, + { + "name": "minecraft:polished_tuff", + "id": -748 + }, + { + "name": "minecraft:polished_tuff_double_slab", + "id": -750 + }, + { + "name": "minecraft:polished_tuff_slab", + "id": -749 + }, + { + "name": "minecraft:polished_tuff_stairs", + "id": -751 + }, + { + "name": "minecraft:polished_tuff_wall", + "id": -752 + }, + { + "name": "minecraft:popped_chorus_fruit", + "id": 570 + }, + { + "name": "minecraft:porkchop", + "id": 263 + }, + { + "name": "minecraft:portal", + "id": 90 + }, + { + "name": "minecraft:potato", + "id": 281 + }, + { + "name": "minecraft:potatoes", + "id": 142 + }, + { + "name": "minecraft:potion", + "id": 430 + }, + { + "name": "minecraft:powder_snow", + "id": -306 + }, + { + "name": "minecraft:powder_snow_bucket", + "id": 371 + }, + { + "name": "minecraft:powered_comparator", + "id": 150 + }, + { + "name": "minecraft:powered_repeater", + "id": 94 + }, + { + "name": "minecraft:prismarine", + "id": 168 + }, + { + "name": "minecraft:prismarine_bricks_stairs", + "id": -4 + }, + { + "name": "minecraft:prismarine_crystals", + "id": 560 + }, + { + "name": "minecraft:prismarine_shard", + "id": 576 + }, + { + "name": "minecraft:prismarine_stairs", + "id": -2 + }, + { + "name": "minecraft:prize_pottery_sherd", + "id": 682 + }, + { + "name": "minecraft:pufferfish", + "id": 268 + }, + { + "name": "minecraft:pufferfish_bucket", + "id": 370 + }, + { + "name": "minecraft:pufferfish_spawn_egg", + "id": 486 + }, + { + "name": "minecraft:pumpkin", + "id": 86 + }, + { + "name": "minecraft:pumpkin_pie", + "id": 285 + }, + { + "name": "minecraft:pumpkin_seeds", + "id": 293 + }, + { + "name": "minecraft:pumpkin_stem", + "id": 104 + }, + { + "name": "minecraft:purple_candle", + "id": -423 + }, + { + "name": "minecraft:purple_candle_cake", + "id": -440 + }, + { + "name": "minecraft:purple_carpet", + "id": -606 + }, + { + "name": "minecraft:purple_concrete", + "id": -637 + }, + { + "name": "minecraft:purple_concrete_powder", + "id": -718 + }, + { + "name": "minecraft:purple_dye", + "id": 404 + }, + { + "name": "minecraft:purple_glazed_terracotta", + "id": 219 + }, + { + "name": "minecraft:purple_shulker_box", + "id": -622 + }, + { + "name": "minecraft:purple_stained_glass", + "id": -682 + }, + { + "name": "minecraft:purple_stained_glass_pane", + "id": -652 + }, + { + "name": "minecraft:purple_terracotta", + "id": -733 + }, + { + "name": "minecraft:purple_wool", + "id": -564 + }, + { + "name": "minecraft:purpur_block", + "id": 201 + }, + { + "name": "minecraft:purpur_stairs", + "id": 203 + }, + { + "name": "minecraft:quartz", + "id": 535 + }, + { + "name": "minecraft:quartz_block", + "id": 155 + }, + { + "name": "minecraft:quartz_bricks", + "id": -304 + }, + { + "name": "minecraft:quartz_ore", + "id": 153 + }, + { + "name": "minecraft:quartz_stairs", + "id": 156 + }, + { + "name": "minecraft:rabbit", + "id": 289 + }, + { + "name": "minecraft:rabbit_foot", + "id": 539 + }, + { + "name": "minecraft:rabbit_hide", + "id": 540 + }, + { + "name": "minecraft:rabbit_spawn_egg", + "id": 463 + }, + { + "name": "minecraft:rabbit_stew", + "id": 291 + }, + { + "name": "minecraft:rail", + "id": 66 + }, + { + "name": "minecraft:raiser_armor_trim_smithing_template", + "id": 702 + }, + { + "name": "minecraft:rapid_fertilizer", + "id": 608 + }, + { + "name": "minecraft:ravager_spawn_egg", + "id": 498 + }, + { + "name": "minecraft:raw_copper", + "id": 518 + }, + { + "name": "minecraft:raw_copper_block", + "id": -452 + }, + { + "name": "minecraft:raw_gold", + "id": 517 + }, + { + "name": "minecraft:raw_gold_block", + "id": -453 + }, + { + "name": "minecraft:raw_iron", + "id": 516 + }, + { + "name": "minecraft:raw_iron_block", + "id": -451 + }, + { + "name": "minecraft:recovery_compass", + "id": 657 + }, + { + "name": "minecraft:red_candle", + "id": -427 + }, + { + "name": "minecraft:red_candle_cake", + "id": -444 + }, + { + "name": "minecraft:red_carpet", + "id": -610 + }, + { + "name": "minecraft:red_concrete", + "id": -641 + }, + { + "name": "minecraft:red_concrete_powder", + "id": -722 + }, + { + "name": "minecraft:red_dye", + "id": 400 + }, + { + "name": "minecraft:red_flower", + "id": 38 + }, + { + "name": "minecraft:red_glazed_terracotta", + "id": 234 + }, + { + "name": "minecraft:red_mushroom", + "id": 40 + }, + { + "name": "minecraft:red_mushroom_block", + "id": 100 + }, + { + "name": "minecraft:red_nether_brick", + "id": 215 + }, + { + "name": "minecraft:red_nether_brick_stairs", + "id": -184 + }, + { + "name": "minecraft:red_sandstone", + "id": 179 + }, + { + "name": "minecraft:red_sandstone_stairs", + "id": 180 + }, + { + "name": "minecraft:red_shulker_box", + "id": -626 + }, + { + "name": "minecraft:red_stained_glass", + "id": -686 + }, + { + "name": "minecraft:red_stained_glass_pane", + "id": -656 + }, + { + "name": "minecraft:red_terracotta", + "id": -737 + }, + { + "name": "minecraft:red_wool", + "id": -556 + }, + { + "name": "minecraft:redstone", + "id": 376 + }, + { + "name": "minecraft:redstone_block", + "id": 152 + }, + { + "name": "minecraft:redstone_lamp", + "id": 123 + }, + { + "name": "minecraft:redstone_ore", + "id": 73 + }, + { + "name": "minecraft:redstone_torch", + "id": 76 + }, + { + "name": "minecraft:redstone_wire", + "id": 55 + }, + { + "name": "minecraft:reinforced_deepslate", + "id": -466 + }, + { + "name": "minecraft:repeater", + "id": 423 + }, + { + "name": "minecraft:repeating_command_block", + "id": 188 + }, + { + "name": "minecraft:reserved6", + "id": 255 + }, + { + "name": "minecraft:respawn_anchor", + "id": -272 + }, + { + "name": "minecraft:rib_armor_trim_smithing_template", + "id": 698 + }, + { + "name": "minecraft:rotten_flesh", + "id": 278 + }, + { + "name": "minecraft:saddle", + "id": 374 + }, + { + "name": "minecraft:salmon", + "id": 266 + }, + { + "name": "minecraft:salmon_bucket", + "id": 368 + }, + { + "name": "minecraft:salmon_spawn_egg", + "id": 487 + }, + { + "name": "minecraft:sand", + "id": 12 + }, + { + "name": "minecraft:sandstone", + "id": 24 + }, + { + "name": "minecraft:sandstone_stairs", + "id": 128 + }, + { + "name": "minecraft:sapling", + "id": 6 + }, + { + "name": "minecraft:scaffolding", + "id": -165 + }, + { + "name": "minecraft:sculk", + "id": -458 + }, + { + "name": "minecraft:sculk_catalyst", + "id": -460 + }, + { + "name": "minecraft:sculk_sensor", + "id": -307 + }, + { + "name": "minecraft:sculk_shrieker", + "id": -461 + }, + { + "name": "minecraft:sculk_vein", + "id": -459 + }, + { + "name": "minecraft:sea_lantern", + "id": 169 + }, + { + "name": "minecraft:sea_pickle", + "id": -156 + }, + { + "name": "minecraft:seagrass", + "id": -130 + }, + { + "name": "minecraft:sentry_armor_trim_smithing_template", + "id": 689 + }, + { + "name": "minecraft:shaper_armor_trim_smithing_template", + "id": 703 + }, + { + "name": "minecraft:sheaf_pottery_sherd", + "id": 683 + }, + { + "name": "minecraft:shears", + "id": 425 + }, + { + "name": "minecraft:sheep_spawn_egg", + "id": 442 + }, + { + "name": "minecraft:shelter_pottery_sherd", + "id": 684 + }, + { + "name": "minecraft:shield", + "id": 358 + }, + { + "name": "minecraft:shroomlight", + "id": -230 + }, + { + "name": "minecraft:shulker_box", + "id": 725 + }, + { + "name": "minecraft:shulker_shell", + "id": 577 + }, + { + "name": "minecraft:shulker_spawn_egg", + "id": 474 + }, + { + "name": "minecraft:silence_armor_trim_smithing_template", + "id": 700 + }, + { + "name": "minecraft:silver_glazed_terracotta", + "id": 228 + }, + { + "name": "minecraft:silverfish_spawn_egg", + "id": 447 + }, + { + "name": "minecraft:skeleton_horse_spawn_egg", + "id": 472 + }, + { + "name": "minecraft:skeleton_spawn_egg", + "id": 448 + }, + { + "name": "minecraft:skull", + "id": 527 + }, + { + "name": "minecraft:skull_banner_pattern", + "id": 594 + }, + { + "name": "minecraft:skull_pottery_sherd", + "id": 685 + }, + { + "name": "minecraft:slime", + "id": 165 + }, + { + "name": "minecraft:slime_ball", + "id": 392 + }, + { + "name": "minecraft:slime_spawn_egg", + "id": 449 + }, + { + "name": "minecraft:small_amethyst_bud", + "id": -332 + }, + { + "name": "minecraft:small_dripleaf_block", + "id": -336 + }, + { + "name": "minecraft:smithing_table", + "id": -202 + }, + { + "name": "minecraft:smoker", + "id": -198 + }, + { + "name": "minecraft:smooth_basalt", + "id": -377 + }, + { + "name": "minecraft:smooth_quartz_stairs", + "id": -185 + }, + { + "name": "minecraft:smooth_red_sandstone_stairs", + "id": -176 + }, + { + "name": "minecraft:smooth_sandstone_stairs", + "id": -177 + }, + { + "name": "minecraft:smooth_stone", + "id": -183 + }, + { + "name": "minecraft:sniffer_egg", + "id": -596 + }, + { + "name": "minecraft:sniffer_spawn_egg", + "id": 505 + }, + { + "name": "minecraft:snort_pottery_sherd", + "id": 686 + }, + { + "name": "minecraft:snout_armor_trim_smithing_template", + "id": 697 + }, + { + "name": "minecraft:snow", + "id": 80 + }, + { + "name": "minecraft:snow_golem_spawn_egg", + "id": 511 + }, + { + "name": "minecraft:snow_layer", + "id": 78 + }, + { + "name": "minecraft:snowball", + "id": 377 + }, + { + "name": "minecraft:soul_campfire", + "id": 633 + }, + { + "name": "minecraft:soul_fire", + "id": -237 + }, + { + "name": "minecraft:soul_lantern", + "id": -269 + }, + { + "name": "minecraft:soul_sand", + "id": 88 + }, + { + "name": "minecraft:soul_soil", + "id": -236 + }, + { + "name": "minecraft:soul_torch", + "id": -268 + }, + { + "name": "minecraft:sparkler", + "id": 611 + }, + { + "name": "minecraft:spawn_egg", + "id": 732 + }, + { + "name": "minecraft:spider_eye", + "id": 279 + }, + { + "name": "minecraft:spider_spawn_egg", + "id": 450 + }, + { + "name": "minecraft:spire_armor_trim_smithing_template", + "id": 699 + }, + { + "name": "minecraft:splash_potion", + "id": 572 + }, + { + "name": "minecraft:sponge", + "id": 19 + }, + { + "name": "minecraft:spore_blossom", + "id": -321 + }, + { + "name": "minecraft:spruce_boat", + "id": 382 + }, + { + "name": "minecraft:spruce_button", + "id": -144 + }, + { + "name": "minecraft:spruce_chest_boat", + "id": 652 + }, + { + "name": "minecraft:spruce_door", + "id": 564 + }, + { + "name": "minecraft:spruce_double_slab", + "id": -809 + }, + { + "name": "minecraft:spruce_fence", + "id": -579 + }, + { + "name": "minecraft:spruce_fence_gate", + "id": 183 + }, + { + "name": "minecraft:spruce_hanging_sign", + "id": -501 + }, + { + "name": "minecraft:spruce_leaves", + "id": -800 + }, + { + "name": "minecraft:spruce_log", + "id": -569 + }, + { + "name": "minecraft:spruce_planks", + "id": -739 + }, + { + "name": "minecraft:spruce_pressure_plate", + "id": -154 + }, + { + "name": "minecraft:spruce_sign", + "id": 587 + }, + { + "name": "minecraft:spruce_slab", + "id": -804 + }, + { + "name": "minecraft:spruce_stairs", + "id": 134 + }, + { + "name": "minecraft:spruce_standing_sign", + "id": -181 + }, + { + "name": "minecraft:spruce_trapdoor", + "id": -149 + }, + { + "name": "minecraft:spruce_wall_sign", + "id": -182 + }, + { + "name": "minecraft:spruce_wood", + "id": -814 + }, + { + "name": "minecraft:spyglass", + "id": 636 + }, + { + "name": "minecraft:squid_spawn_egg", + "id": 454 + }, + { + "name": "minecraft:stained_glass", + "id": 723 + }, + { + "name": "minecraft:stained_glass_pane", + "id": 724 + }, + { + "name": "minecraft:stained_hardened_clay", + "id": 706 + }, + { + "name": "minecraft:standing_banner", + "id": 176 + }, + { + "name": "minecraft:standing_sign", + "id": 63 + }, + { + "name": "minecraft:stick", + "id": 323 + }, + { + "name": "minecraft:sticky_piston", + "id": 29 + }, + { + "name": "minecraft:sticky_piston_arm_collision", + "id": -217 + }, + { + "name": "minecraft:stone", + "id": 1 + }, + { + "name": "minecraft:stone_axe", + "id": 318 + }, + { + "name": "minecraft:stone_block_slab", + "id": 44 + }, + { + "name": "minecraft:stone_block_slab2", + "id": 182 + }, + { + "name": "minecraft:stone_block_slab3", + "id": -162 + }, + { + "name": "minecraft:stone_block_slab4", + "id": -166 + }, + { + "name": "minecraft:stone_brick_stairs", + "id": 109 + }, + { + "name": "minecraft:stone_button", + "id": 77 + }, + { + "name": "minecraft:stone_hoe", + "id": 333 + }, + { + "name": "minecraft:stone_pickaxe", + "id": 317 + }, + { + "name": "minecraft:stone_pressure_plate", + "id": 70 + }, + { + "name": "minecraft:stone_shovel", + "id": 316 + }, + { + "name": "minecraft:stone_stairs", + "id": 67 + }, + { + "name": "minecraft:stone_sword", + "id": 315 + }, + { + "name": "minecraft:stonebrick", + "id": 98 + }, + { + "name": "minecraft:stonecutter", + "id": 245 + }, + { + "name": "minecraft:stonecutter_block", + "id": -197 + }, + { + "name": "minecraft:stray_spawn_egg", + "id": 466 + }, + { + "name": "minecraft:strider_spawn_egg", + "id": 500 + }, + { + "name": "minecraft:string", + "id": 329 + }, + { + "name": "minecraft:stripped_acacia_log", + "id": -8 + }, + { + "name": "minecraft:stripped_acacia_wood", + "id": -823 + }, + { + "name": "minecraft:stripped_bamboo_block", + "id": -528 + }, + { + "name": "minecraft:stripped_birch_log", + "id": -6 + }, + { + "name": "minecraft:stripped_birch_wood", + "id": -821 + }, + { + "name": "minecraft:stripped_cherry_log", + "id": -535 + }, + { + "name": "minecraft:stripped_cherry_wood", + "id": -545 + }, + { + "name": "minecraft:stripped_crimson_hyphae", + "id": -300 + }, + { + "name": "minecraft:stripped_crimson_stem", + "id": -240 + }, + { + "name": "minecraft:stripped_dark_oak_log", + "id": -9 + }, + { + "name": "minecraft:stripped_dark_oak_wood", + "id": -824 + }, + { + "name": "minecraft:stripped_jungle_log", + "id": -7 + }, + { + "name": "minecraft:stripped_jungle_wood", + "id": -822 + }, + { + "name": "minecraft:stripped_mangrove_log", + "id": -485 + }, + { + "name": "minecraft:stripped_mangrove_wood", + "id": -498 + }, + { + "name": "minecraft:stripped_oak_log", + "id": -10 + }, + { + "name": "minecraft:stripped_oak_wood", + "id": -819 + }, + { + "name": "minecraft:stripped_spruce_log", + "id": -5 + }, + { + "name": "minecraft:stripped_spruce_wood", + "id": -820 + }, + { + "name": "minecraft:stripped_warped_hyphae", + "id": -301 + }, + { + "name": "minecraft:stripped_warped_stem", + "id": -241 + }, + { + "name": "minecraft:structure_block", + "id": 252 + }, + { + "name": "minecraft:structure_void", + "id": 217 + }, + { + "name": "minecraft:sugar", + "id": 420 + }, + { + "name": "minecraft:sugar_cane", + "id": 389 + }, + { + "name": "minecraft:suspicious_gravel", + "id": -573 + }, + { + "name": "minecraft:suspicious_sand", + "id": -529 + }, + { + "name": "minecraft:suspicious_stew", + "id": 601 + }, + { + "name": "minecraft:sweet_berries", + "id": 288 + }, + { + "name": "minecraft:sweet_berry_bush", + "id": -207 + }, + { + "name": "minecraft:tadpole_bucket", + "id": 641 + }, + { + "name": "minecraft:tadpole_spawn_egg", + "id": 640 + }, + { + "name": "minecraft:tallgrass", + "id": 31 + }, + { + "name": "minecraft:target", + "id": -239 + }, + { + "name": "minecraft:tide_armor_trim_smithing_template", + "id": 696 + }, + { + "name": "minecraft:tinted_glass", + "id": -334 + }, + { + "name": "minecraft:tnt", + "id": 46 + }, + { + "name": "minecraft:tnt_minecart", + "id": 536 + }, + { + "name": "minecraft:torch", + "id": 50 + }, + { + "name": "minecraft:torchflower", + "id": -568 + }, + { + "name": "minecraft:torchflower_crop", + "id": -567 + }, + { + "name": "minecraft:torchflower_seeds", + "id": 297 + }, + { + "name": "minecraft:totem_of_undying", + "id": 579 + }, + { + "name": "minecraft:trader_llama_spawn_egg", + "id": 659 + }, + { + "name": "minecraft:trapdoor", + "id": 96 + }, + { + "name": "minecraft:trapped_chest", + "id": 146 + }, + { + "name": "minecraft:trial_key", + "id": 707 + }, + { + "name": "minecraft:trial_spawner", + "id": -315 + }, + { + "name": "minecraft:trident", + "id": 557 + }, + { + "name": "minecraft:trip_wire", + "id": 132 + }, + { + "name": "minecraft:tripwire_hook", + "id": 131 + }, + { + "name": "minecraft:tropical_fish", + "id": 267 + }, + { + "name": "minecraft:tropical_fish_bucket", + "id": 369 + }, + { + "name": "minecraft:tropical_fish_spawn_egg", + "id": 484 + }, + { + "name": "minecraft:tube_coral", + "id": -131 + }, + { + "name": "minecraft:tuff", + "id": -333 + }, + { + "name": "minecraft:tuff_brick_double_slab", + "id": -756 + }, + { + "name": "minecraft:tuff_brick_slab", + "id": -755 + }, + { + "name": "minecraft:tuff_brick_stairs", + "id": -757 + }, + { + "name": "minecraft:tuff_brick_wall", + "id": -758 + }, + { + "name": "minecraft:tuff_bricks", + "id": -754 + }, + { + "name": "minecraft:tuff_double_slab", + "id": -745 + }, + { + "name": "minecraft:tuff_slab", + "id": -744 + }, + { + "name": "minecraft:tuff_stairs", + "id": -746 + }, + { + "name": "minecraft:tuff_wall", + "id": -747 + }, + { + "name": "minecraft:turtle_egg", + "id": -159 + }, + { + "name": "minecraft:turtle_helmet", + "id": 584 + }, + { + "name": "minecraft:turtle_scute", + "id": 583 + }, + { + "name": "minecraft:turtle_spawn_egg", + "id": 490 + }, + { + "name": "minecraft:twisting_vines", + "id": -287 + }, + { + "name": "minecraft:underwater_torch", + "id": 239 + }, + { + "name": "minecraft:undyed_shulker_box", + "id": 205 + }, + { + "name": "minecraft:unknown", + "id": -305 + }, + { + "name": "minecraft:unlit_redstone_torch", + "id": 75 + }, + { + "name": "minecraft:unpowered_comparator", + "id": 149 + }, + { + "name": "minecraft:unpowered_repeater", + "id": 93 + }, + { + "name": "minecraft:vault", + "id": -314 + }, + { + "name": "minecraft:verdant_froglight", + "id": -470 + }, + { + "name": "minecraft:vex_armor_trim_smithing_template", + "id": 695 + }, + { + "name": "minecraft:vex_spawn_egg", + "id": 481 + }, + { + "name": "minecraft:villager_spawn_egg", + "id": 453 + }, + { + "name": "minecraft:vindicator_spawn_egg", + "id": 479 + }, + { + "name": "minecraft:vine", + "id": 106 + }, + { + "name": "minecraft:wall_banner", + "id": 177 + }, + { + "name": "minecraft:wall_sign", + "id": 68 + }, + { + "name": "minecraft:wandering_trader_spawn_egg", + "id": 497 + }, + { + "name": "minecraft:ward_armor_trim_smithing_template", + "id": 693 + }, + { + "name": "minecraft:warden_spawn_egg", + "id": 643 + }, + { + "name": "minecraft:warped_button", + "id": -261 + }, + { + "name": "minecraft:warped_door", + "id": 628 + }, + { + "name": "minecraft:warped_double_slab", + "id": -267 + }, + { + "name": "minecraft:warped_fence", + "id": -257 + }, + { + "name": "minecraft:warped_fence_gate", + "id": -259 + }, + { + "name": "minecraft:warped_fungus", + "id": -229 + }, + { + "name": "minecraft:warped_fungus_on_a_stick", + "id": 629 + }, + { + "name": "minecraft:warped_hanging_sign", + "id": -507 + }, + { + "name": "minecraft:warped_hyphae", + "id": -298 + }, + { + "name": "minecraft:warped_nylium", + "id": -233 + }, + { + "name": "minecraft:warped_planks", + "id": -243 + }, + { + "name": "minecraft:warped_pressure_plate", + "id": -263 + }, + { + "name": "minecraft:warped_roots", + "id": -224 + }, + { + "name": "minecraft:warped_sign", + "id": 626 + }, + { + "name": "minecraft:warped_slab", + "id": -265 + }, + { + "name": "minecraft:warped_stairs", + "id": -255 + }, + { + "name": "minecraft:warped_standing_sign", + "id": -251 + }, + { + "name": "minecraft:warped_stem", + "id": -226 + }, + { + "name": "minecraft:warped_trapdoor", + "id": -247 + }, + { + "name": "minecraft:warped_wall_sign", + "id": -253 + }, + { + "name": "minecraft:warped_wart_block", + "id": -227 + }, + { + "name": "minecraft:water", + "id": 9 + }, + { + "name": "minecraft:water_bucket", + "id": 365 + }, + { + "name": "minecraft:waterlily", + "id": 111 + }, + { + "name": "minecraft:waxed_chiseled_copper", + "id": -764 + }, + { + "name": "minecraft:waxed_copper", + "id": -344 + }, + { + "name": "minecraft:waxed_copper_bulb", + "id": -780 + }, + { + "name": "minecraft:waxed_copper_door", + "id": -788 + }, + { + "name": "minecraft:waxed_copper_grate", + "id": -772 + }, + { + "name": "minecraft:waxed_copper_trapdoor", + "id": -796 + }, + { + "name": "minecraft:waxed_cut_copper", + "id": -351 + }, + { + "name": "minecraft:waxed_cut_copper_slab", + "id": -365 + }, + { + "name": "minecraft:waxed_cut_copper_stairs", + "id": -358 + }, + { + "name": "minecraft:waxed_double_cut_copper_slab", + "id": -372 + }, + { + "name": "minecraft:waxed_exposed_chiseled_copper", + "id": -765 + }, + { + "name": "minecraft:waxed_exposed_copper", + "id": -345 + }, + { + "name": "minecraft:waxed_exposed_copper_bulb", + "id": -781 + }, + { + "name": "minecraft:waxed_exposed_copper_door", + "id": -789 + }, + { + "name": "minecraft:waxed_exposed_copper_grate", + "id": -773 + }, + { + "name": "minecraft:waxed_exposed_copper_trapdoor", + "id": -797 + }, + { + "name": "minecraft:waxed_exposed_cut_copper", + "id": -352 + }, + { + "name": "minecraft:waxed_exposed_cut_copper_slab", + "id": -366 + }, + { + "name": "minecraft:waxed_exposed_cut_copper_stairs", + "id": -359 + }, + { + "name": "minecraft:waxed_exposed_double_cut_copper_slab", + "id": -373 + }, + { + "name": "minecraft:waxed_oxidized_chiseled_copper", + "id": -766 + }, + { + "name": "minecraft:waxed_oxidized_copper", + "id": -446 + }, + { + "name": "minecraft:waxed_oxidized_copper_bulb", + "id": -783 + }, + { + "name": "minecraft:waxed_oxidized_copper_door", + "id": -791 + }, + { + "name": "minecraft:waxed_oxidized_copper_grate", + "id": -775 + }, + { + "name": "minecraft:waxed_oxidized_copper_trapdoor", + "id": -799 + }, + { + "name": "minecraft:waxed_oxidized_cut_copper", + "id": -447 + }, + { + "name": "minecraft:waxed_oxidized_cut_copper_slab", + "id": -449 + }, + { + "name": "minecraft:waxed_oxidized_cut_copper_stairs", + "id": -448 + }, + { + "name": "minecraft:waxed_oxidized_double_cut_copper_slab", + "id": -450 + }, + { + "name": "minecraft:waxed_weathered_chiseled_copper", + "id": -767 + }, + { + "name": "minecraft:waxed_weathered_copper", + "id": -346 + }, + { + "name": "minecraft:waxed_weathered_copper_bulb", + "id": -782 + }, + { + "name": "minecraft:waxed_weathered_copper_door", + "id": -790 + }, + { + "name": "minecraft:waxed_weathered_copper_grate", + "id": -774 + }, + { + "name": "minecraft:waxed_weathered_copper_trapdoor", + "id": -798 + }, + { + "name": "minecraft:waxed_weathered_cut_copper", + "id": -353 + }, + { + "name": "minecraft:waxed_weathered_cut_copper_slab", + "id": -367 + }, + { + "name": "minecraft:waxed_weathered_cut_copper_stairs", + "id": -360 + }, + { + "name": "minecraft:waxed_weathered_double_cut_copper_slab", + "id": -374 + }, + { + "name": "minecraft:wayfinder_armor_trim_smithing_template", + "id": 701 + }, + { + "name": "minecraft:weathered_chiseled_copper", + "id": -762 + }, + { + "name": "minecraft:weathered_copper", + "id": -342 + }, + { + "name": "minecraft:weathered_copper_bulb", + "id": -778 + }, + { + "name": "minecraft:weathered_copper_door", + "id": -786 + }, + { + "name": "minecraft:weathered_copper_grate", + "id": -770 + }, + { + "name": "minecraft:weathered_copper_trapdoor", + "id": -794 + }, + { + "name": "minecraft:weathered_cut_copper", + "id": -349 + }, + { + "name": "minecraft:weathered_cut_copper_slab", + "id": -363 + }, + { + "name": "minecraft:weathered_cut_copper_stairs", + "id": -356 + }, + { + "name": "minecraft:weathered_double_cut_copper_slab", + "id": -370 + }, + { + "name": "minecraft:web", + "id": 30 + }, + { + "name": "minecraft:weeping_vines", + "id": -231 + }, + { + "name": "minecraft:wheat", + "id": 337 + }, + { + "name": "minecraft:wheat_seeds", + "id": 292 + }, + { + "name": "minecraft:white_candle", + "id": -413 + }, + { + "name": "minecraft:white_candle_cake", + "id": -430 + }, + { + "name": "minecraft:white_carpet", + "id": 171 + }, + { + "name": "minecraft:white_concrete", + "id": 236 + }, + { + "name": "minecraft:white_concrete_powder", + "id": 237 + }, + { + "name": "minecraft:white_dye", + "id": 414 + }, + { + "name": "minecraft:white_glazed_terracotta", + "id": 220 + }, + { + "name": "minecraft:white_shulker_box", + "id": 218 + }, + { + "name": "minecraft:white_stained_glass", + "id": 241 + }, + { + "name": "minecraft:white_stained_glass_pane", + "id": 160 + }, + { + "name": "minecraft:white_terracotta", + "id": 159 + }, + { + "name": "minecraft:white_wool", + "id": 35 + }, + { + "name": "minecraft:wild_armor_trim_smithing_template", + "id": 692 + }, + { + "name": "minecraft:wind_charge", + "id": 378 + }, + { + "name": "minecraft:witch_spawn_egg", + "id": 456 + }, + { + "name": "minecraft:wither_rose", + "id": -216 + }, + { + "name": "minecraft:wither_skeleton_spawn_egg", + "id": 469 + }, + { + "name": "minecraft:wither_spawn_egg", + "id": 513 + }, + { + "name": "minecraft:wolf_armor", + "id": 710 + }, + { + "name": "minecraft:wolf_spawn_egg", + "id": 443 + }, + { + "name": "minecraft:wood", + "id": 726 + }, + { + "name": "minecraft:wooden_axe", + "id": 314 + }, + { + "name": "minecraft:wooden_button", + "id": 143 + }, + { + "name": "minecraft:wooden_door", + "id": 362 + }, + { + "name": "minecraft:wooden_hoe", + "id": 332 + }, + { + "name": "minecraft:wooden_pickaxe", + "id": 313 + }, + { + "name": "minecraft:wooden_pressure_plate", + "id": 72 + }, + { + "name": "minecraft:wooden_shovel", + "id": 312 + }, + { + "name": "minecraft:wooden_slab", + "id": 717 + }, + { + "name": "minecraft:wooden_sword", + "id": 311 + }, + { + "name": "minecraft:wool", + "id": 711 + }, + { + "name": "minecraft:writable_book", + "id": 521 + }, + { + "name": "minecraft:written_book", + "id": 522 + }, + { + "name": "minecraft:yellow_candle", + "id": -417 + }, + { + "name": "minecraft:yellow_candle_cake", + "id": -434 + }, + { + "name": "minecraft:yellow_carpet", + "id": -600 + }, + { + "name": "minecraft:yellow_concrete", + "id": -631 + }, + { + "name": "minecraft:yellow_concrete_powder", + "id": -712 + }, + { + "name": "minecraft:yellow_dye", + "id": 410 + }, + { + "name": "minecraft:yellow_flower", + "id": 37 + }, + { + "name": "minecraft:yellow_glazed_terracotta", + "id": 224 + }, + { + "name": "minecraft:yellow_shulker_box", + "id": -616 + }, + { + "name": "minecraft:yellow_stained_glass", + "id": -676 + }, + { + "name": "minecraft:yellow_stained_glass_pane", + "id": -646 + }, + { + "name": "minecraft:yellow_terracotta", + "id": -727 + }, + { + "name": "minecraft:yellow_wool", + "id": -558 + }, + { + "name": "minecraft:zoglin_spawn_egg", + "id": 503 + }, + { + "name": "minecraft:zombie_horse_spawn_egg", + "id": 473 + }, + { + "name": "minecraft:zombie_pigman_spawn_egg", + "id": 452 + }, + { + "name": "minecraft:zombie_spawn_egg", + "id": 451 + }, + { + "name": "minecraft:zombie_villager_spawn_egg", + "id": 482 + } +] \ No newline at end of file diff --git a/core/src/main/resources/mappings b/core/src/main/resources/mappings index 522967d6e..c96c53850 160000 --- a/core/src/main/resources/mappings +++ b/core/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 522967d6ee76972994ad05a992dc9d7bb4e889ba +Subproject commit c96c53850b720a0238e1a398a49b24b0a0887da7 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4ce5dda1a..41e1ebaec 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -9,10 +9,10 @@ netty = "4.1.103.Final" guava = "29.0-jre" gson = "2.3.1" # Provided by Spigot 1.8.8 websocket = "1.5.1" -protocol = "3.0.0.Beta1-20240204.134050-120" -protocol-connection = "3.0.0.Beta1-20240204.134050-119" +protocol = "3.0.0.Beta1-20240226.201527-125" +protocol-connection = "3.0.0.Beta1-20240226.201527-124" raknet = "1.0.0.CR1-20231206.145325-12" -blockstateupdater="1.20.60-20240129.140535-1" +blockstateupdater="1.20.70-20240303.125052-2" mcauthlib = "d9d773e" mcprotocollib = "1.20.4-2-20240116.220521-7" adventure = "4.14.0" From 7e4d97f6e135d3c80b26f7f17248b90ec6e83266 Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Wed, 13 Mar 2024 02:05:41 -0700 Subject: [PATCH 017/272] Fix wooden slabs (#4489) * Fix wooden slabs Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Update submodule Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Also indicate 1.20.71 support Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> --------- Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> --- README.md | 2 +- .../org/geysermc/geyser/network/GameProtocol.java | 2 +- .../geyser/registry/populator/Conversion662_649.java | 11 +++++++++++ core/src/main/resources/mappings | 2 +- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c6445155f..76a62a462 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here! -### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.70 and Minecraft Java 1.20.4 +### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.71 and Minecraft Java 1.20.4 ## Setting Up Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser. diff --git a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java index 3ead79d9e..80d2038d9 100644 --- a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java +++ b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java @@ -72,7 +72,7 @@ public final class GameProtocol { .minecraftVersion("1.20.60/1.20.62") .build()); SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC.toBuilder() - .minecraftVersion("1.20.70") + .minecraftVersion("1.20.70/1.20.71") .build()); } diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java index 6dc6b01a0..cddeae7bf 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java @@ -67,6 +67,17 @@ public class Conversion662_649 { } } + if (NEW_SLABS.contains(identifer)) { + switch (identifer) { + case "minecraft:oak_slab" -> { return mapping.withBedrockIdentifier("minecraft:wooden_slab").withBedrockData(0); } + case "minecraft:spruce_slab" -> { return mapping.withBedrockIdentifier("minecraft:wooden_slab").withBedrockData(1); } + case "minecraft:birch_slab" -> { return mapping.withBedrockIdentifier("minecraft:wooden_slab").withBedrockData(2); } + case "minecraft:jungle_slab" -> { return mapping.withBedrockIdentifier("minecraft:wooden_slab").withBedrockData(3); } + case "minecraft:acacia_slab" -> { return mapping.withBedrockIdentifier("minecraft:wooden_slab").withBedrockData(4); } + case "minecraft:dark_oak_slab" -> { return mapping.withBedrockIdentifier("minecraft:wooden_slab").withBedrockData(5); } + } + } + if (NEW_LEAVES.contains(identifer) || NEW_LEAVES2.contains(identifer)) { switch (identifer) { case "minecraft:oak_leaves" -> { return mapping.withBedrockIdentifier("minecraft:leaves").withBedrockData(0); } diff --git a/core/src/main/resources/mappings b/core/src/main/resources/mappings index c96c53850..b1883ca53 160000 --- a/core/src/main/resources/mappings +++ b/core/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit c96c53850b720a0238e1a398a49b24b0a0887da7 +Subproject commit b1883ca53afc082de98aeb062ba2fad00e069617 From a9467cf150bf2f0af36849b6a47abd23db8be83b Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Wed, 13 Mar 2024 02:54:39 -0700 Subject: [PATCH 018/272] Temporary bad fix for command crashing (#4490) Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> --- .../java/org/geysermc/geyser/session/GeyserSession.java | 7 +++++++ .../translator/protocol/java/JavaCommandsTranslator.java | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 7a4a8ff6f..b95b5af8d 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -602,6 +602,13 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { @Setter private @Nullable ItemData currentBook = null; + /** + * Stores if we've sent AvailibleCommandsPacket to the client due to it crashing if sent twice on 1.20.70/71 + * Hopefully bedrock will have a hotfix so we can remove this + */ + @Setter + private boolean sentAvailibleCommands = false; + private final GeyserCameraData cameraData; private final GeyserEntityData entityData; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java index 0d7f45c7d..7ded656dd 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java @@ -46,6 +46,7 @@ import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.event.java.ServerDefineCommandsEvent; import org.geysermc.geyser.command.GeyserCommandManager; import org.geysermc.geyser.inventory.item.Enchantment; +import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; @@ -115,6 +116,12 @@ public class JavaCommandsTranslator extends PacketTranslator commandData = new ArrayList<>(); @@ -191,6 +198,7 @@ public class JavaCommandsTranslator extends PacketTranslator Date: Wed, 13 Mar 2024 20:25:30 +0100 Subject: [PATCH 019/272] update protocol lib to resolve command crashing (#4493) --- .../java/org/geysermc/geyser/session/GeyserSession.java | 7 ------- .../translator/protocol/java/JavaCommandsTranslator.java | 8 -------- gradle/libs.versions.toml | 4 ++-- 3 files changed, 2 insertions(+), 17 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index b95b5af8d..7a4a8ff6f 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -602,13 +602,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { @Setter private @Nullable ItemData currentBook = null; - /** - * Stores if we've sent AvailibleCommandsPacket to the client due to it crashing if sent twice on 1.20.70/71 - * Hopefully bedrock will have a hotfix so we can remove this - */ - @Setter - private boolean sentAvailibleCommands = false; - private final GeyserCameraData cameraData; private final GeyserEntityData entityData; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java index 7ded656dd..0d7f45c7d 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java @@ -46,7 +46,6 @@ import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.event.java.ServerDefineCommandsEvent; import org.geysermc.geyser.command.GeyserCommandManager; import org.geysermc.geyser.inventory.item.Enchantment; -import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; @@ -116,12 +115,6 @@ public class JavaCommandsTranslator extends PacketTranslator commandData = new ArrayList<>(); @@ -198,7 +191,6 @@ public class JavaCommandsTranslator extends PacketTranslator Date: Thu, 14 Mar 2024 10:27:49 +0100 Subject: [PATCH 020/272] Fix virtual lecterns - again (#4494) --- .../geyser/inventory/LecternContainer.java | 32 ++++++++++++++++++- .../inventory/LecternInventoryTranslator.java | 5 +++ .../inventory/JavaOpenBookTranslator.java | 5 +-- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/inventory/LecternContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/LecternContainer.java index f5aa7b0d6..7ac2fed99 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/LecternContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/LecternContainer.java @@ -26,10 +26,13 @@ package org.geysermc.geyser.inventory; import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; -import org.cloudburstmc.math.vector.Vector3i; import lombok.Getter; import lombok.Setter; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.protocol.java.inventory.JavaOpenBookTranslator; public class LecternContainer extends Container { @Getter @Setter @@ -39,7 +42,34 @@ public class LecternContainer extends Container { @Getter @Setter private Vector3i position; + // Sigh. When the lectern container is created, we don't know (yet) if it's fake or not. + // So... time for a manual check :/ + @Getter + private boolean isFakeLectern = false; + public LecternContainer(String title, int id, int size, ContainerType containerType, PlayerInventory playerInventory) { super(title, id, size, containerType, playerInventory); } + + /** + * When we are using a fake lectern, the Java server expects us to still be in a player inventory. + * We can't use {@link #isUsingRealBlock()} as that may not be determined yet. + */ + @Override + public void setItem(int slot, @NonNull GeyserItemStack newItem, GeyserSession session) { + if (isFakeLectern) { + session.getPlayerInventory().setItem(slot, newItem, session); + } else { + super.setItem(slot, newItem, session); + } + } + + /** + * This is used ONLY once to set the book of a fake lectern in {@link JavaOpenBookTranslator}. + * See {@link LecternContainer#setItem(int, GeyserItemStack, GeyserSession)} as for why this is separate. + */ + public void setFakeLecternBook(GeyserItemStack book, GeyserSession session) { + this.isFakeLectern = true; + super.setItem(0, book, session); + } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java index 7a1ec7573..9d0661b08 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java @@ -129,6 +129,11 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator @Override public void updateSlot(GeyserSession session, Inventory inventory, int slot) { + // If we're not in a real lectern, the Java server thinks we are still in the player inventory. + if (((LecternContainer) inventory).isFakeLectern()) { + InventoryTranslator.PLAYER_INVENTORY_TRANSLATOR.updateSlot(session, session.getPlayerInventory(), slot); + return; + } super.updateSlot(session, inventory, slot); if (slot == 0) { updateBook(session, inventory, inventory.getItem(0)); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenBookTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenBookTranslator.java index f9cf4ee28..24b964b7c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenBookTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenBookTranslator.java @@ -30,6 +30,7 @@ import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.Cli import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.inventory.Inventory; +import org.geysermc.geyser.inventory.LecternContainer; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.session.GeyserSession; @@ -79,8 +80,8 @@ public class JavaOpenBookTranslator extends PacketTranslator Date: Fri, 15 Mar 2024 13:52:34 +0100 Subject: [PATCH 021/272] More error-robust kernel version parsing (#4496) * should resolve https://github.com/GeyserMC/Geyser/issues/4492 * Use regex to parse version * yeet debug * Only log the throwable message --- .../geyser/network/netty/Bootstraps.java | 50 ++++++++----------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/network/netty/Bootstraps.java b/core/src/main/java/org/geysermc/geyser/network/netty/Bootstraps.java index 9ffc45650..9f889a6e7 100644 --- a/core/src/main/java/org/geysermc/geyser/network/netty/Bootstraps.java +++ b/core/src/main/java/org/geysermc/geyser/network/netty/Bootstraps.java @@ -31,18 +31,18 @@ import io.netty.channel.ChannelFuture; import io.netty.channel.epoll.Native; import io.netty.channel.unix.UnixChannelOption; import lombok.experimental.UtilityClass; +import org.geysermc.geyser.GeyserImpl; -import java.util.Optional; import java.util.concurrent.CompletableFuture; +import java.util.regex.Matcher; +import java.util.regex.Pattern; -@SuppressWarnings("OptionalUsedAsFieldOrParameterType") @UtilityClass public final class Bootstraps { - private static final Optional KERNEL_VERSION; // The REUSEPORT_AVAILABLE socket option is available starting from kernel version 3.9. // This option allows multiple sockets to listen on the same IP address and port without conflict. - private static final int[] REUSEPORT_VERSION = new int[]{3, 9, 0}; + private static final int[] REUSEPORT_VERSION = new int[]{3, 9}; private static final boolean REUSEPORT_AVAILABLE; static { @@ -50,24 +50,16 @@ public final class Bootstraps { try { kernelVersion = Native.KERNEL_VERSION; } catch (Throwable e) { + GeyserImpl.getInstance().getLogger().debug("Could not determine kernel version! " + e.getMessage()); kernelVersion = null; } - if (kernelVersion != null && kernelVersion.contains("-")) { - int index = kernelVersion.indexOf('-'); - if (index > -1) { - kernelVersion = kernelVersion.substring(0, index); - } - int[] kernelVer = fromString(kernelVersion); - KERNEL_VERSION = Optional.of(kernelVer); - REUSEPORT_AVAILABLE = checkVersion(kernelVer, 0); - } else { - KERNEL_VERSION = Optional.empty(); - REUSEPORT_AVAILABLE = false; - } - } - public static Optional getKernelVersion() { - return KERNEL_VERSION; + if (kernelVersion == null) { + REUSEPORT_AVAILABLE = false; + } else { + int[] kernelVer = fromString(kernelVersion); + REUSEPORT_AVAILABLE = checkVersion(kernelVer, 0); + } } public static boolean isReusePortAvailable() { @@ -81,17 +73,19 @@ public final class Bootstraps { } } - private static int[] fromString(String ver) { - String[] parts = ver.split("\\."); - if (parts.length < 2) { - throw new IllegalArgumentException("At least 2 version numbers required"); + private static int[] fromString(String input) { + // Match only beginning of string for at least two digits separated by dot + Pattern pattern = Pattern.compile("^(\\d+)\\.(\\d+)"); + Matcher matcher = pattern.matcher(input); + + int[] version = {0, 0}; + + if (matcher.find()) { + version[0] = Integer.parseInt(matcher.group(1)); + version[1] = Integer.parseInt(matcher.group(2)); } - return new int[]{ - Integer.parseInt(parts[0]), - Integer.parseInt(parts[1]), - parts.length == 2 ? 0 : Integer.parseInt(parts[2]) - }; + return version; } private static boolean checkVersion(int[] ver, int i) { From 112f4ddb8d8ef6d2518f6adde57300f31c6c5be1 Mon Sep 17 00:00:00 2001 From: chris Date: Fri, 15 Mar 2024 17:33:48 +0100 Subject: [PATCH 022/272] Fix: Inventory handling when client tries to open the player inventory when it shouldn't (#4499) * attempt at fixing * Fix wrong handling of OPEN_INVENTORY case in BedrockInteractTranslator --- .../bedrock/entity/player/BedrockInteractTranslator.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockInteractTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockInteractTranslator.java index 80141f849..07e192bb7 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockInteractTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockInteractTranslator.java @@ -127,9 +127,9 @@ public class BedrockInteractTranslator extends PacketTranslator InventoryUtils.openInventory(session, session.getPlayerInventory()); } } else { - // Case: Player opens a player inventory, while we think it shouldn't have! - // Close all inventories, reset to player inventory. - InventoryUtils.closeInventory(session, session.getOpenInventory().getJavaId(), false); + // Case: Player tries to open a player inventory, while we think it should be in a different inventory + // Now: Open the inventory that we're supposed to be in. + InventoryUtils.openInventory(session, session.getOpenInventory()); } break; } From e1e09a6ccbb517bddfd4f93b6881743a760fd941 Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Sat, 16 Mar 2024 08:19:09 -0700 Subject: [PATCH 023/272] Fix KQueue loading crashing macOS; Closes #4474 (#4506) --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c7138e2d8..73417f23a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,7 +5,7 @@ erosion = "1.0-20230406.174837-8" events = "1.1-SNAPSHOT" jackson = { strictly = "2.14.0" } # Don't let other dependencies override fastutil = "8.5.2" -netty = "4.1.103.Final" +netty = "4.1.107.Final" guava = "29.0-jre" gson = "2.3.1" # Provided by Spigot 1.8.8 websocket = "1.5.1" From b03818a0c44da311c5d163a106ce7747899df1f7 Mon Sep 17 00:00:00 2001 From: chris Date: Mon, 18 Mar 2024 19:41:36 +0100 Subject: [PATCH 024/272] Add attack damage indicator to custom items (#4495) --- .../item/custom/NonVanillaCustomItemData.java | 10 +++ .../item/GeyserNonVanillaCustomItemData.java | 15 +++++ .../java/org/geysermc/geyser/item/Items.java | 62 +++++++++---------- .../geyser/item/components/ToolTier.java | 4 -- .../org/geysermc/geyser/item/type/Item.java | 15 +++-- .../CustomItemRegistryPopulator.java | 17 ++--- 6 files changed, 76 insertions(+), 47 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java index 37a4247d1..59e2faad8 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java @@ -64,6 +64,14 @@ public interface NonVanillaCustomItemData extends CustomItemData { */ int maxDamage(); + /** + * Gets the attack damage of the item. + * This is purely visual, and only applied to tools + * + * @return the attack damage of the item + */ + int attackDamage(); + /** * Gets the tool type of the item. * @@ -169,6 +177,8 @@ public interface NonVanillaCustomItemData extends CustomItemData { Builder maxDamage(int maxDamage); + Builder attackDamage(int attackDamage); + Builder toolType(@Nullable String toolType); Builder toolTier(@Nullable String toolTier); diff --git a/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java b/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java index 14f8c3a39..9d86bfa96 100644 --- a/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java +++ b/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java @@ -42,6 +42,7 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i private final int javaId; private final int stackSize; private final int maxDamage; + private final int attackDamage; private final String toolType; private final String toolTier; private final String armorType; @@ -64,6 +65,7 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i this.javaId = builder.javaId; this.stackSize = builder.stackSize; this.maxDamage = builder.maxDamage; + this.attackDamage = builder.attackDamage; this.toolType = builder.toolType; this.toolTier = builder.toolTier; this.armorType = builder.armorType; @@ -98,6 +100,11 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i return maxDamage; } + @Override + public int attackDamage() { + return attackDamage; + } + @Override public String toolType() { return toolType; @@ -161,6 +168,8 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i private int maxDamage = 0; + private int attackDamage = 0; + private String toolType = null; private String toolTier = null; @@ -248,6 +257,12 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i return this; } + @Override + public NonVanillaCustomItemData.Builder attackDamage(int attackDamage) { + this.attackDamage = attackDamage; + return this; + } + @Override public Builder toolType(@Nullable String toolType) { this.toolType = toolType; diff --git a/core/src/main/java/org/geysermc/geyser/item/Items.java b/core/src/main/java/org/geysermc/geyser/item/Items.java index e84315fd8..2147ebb2c 100644 --- a/core/src/main/java/org/geysermc/geyser/item/Items.java +++ b/core/src/main/java/org/geysermc/geyser/item/Items.java @@ -852,36 +852,36 @@ public final class Items { public static final Item GOLD_INGOT = register(new Item("gold_ingot", builder())); public static final Item NETHERITE_INGOT = register(new Item("netherite_ingot", builder())); public static final Item NETHERITE_SCRAP = register(new Item("netherite_scrap", builder())); - public static final Item WOODEN_SWORD = register(new TieredItem("wooden_sword", ToolTier.WOODEN, builder().stackSize(1).maxDamage(59))); - public static final Item WOODEN_SHOVEL = register(new TieredItem("wooden_shovel", ToolTier.WOODEN, builder().stackSize(1).maxDamage(59))); - public static final Item WOODEN_PICKAXE = register(new TieredItem("wooden_pickaxe", ToolTier.WOODEN, builder().stackSize(1).maxDamage(59))); - public static final Item WOODEN_AXE = register(new TieredItem("wooden_axe", ToolTier.WOODEN, builder().stackSize(1).maxDamage(59))); - public static final Item WOODEN_HOE = register(new TieredItem("wooden_hoe", ToolTier.WOODEN, builder().stackSize(1).maxDamage(59))); - public static final Item STONE_SWORD = register(new TieredItem("stone_sword", ToolTier.STONE, builder().stackSize(1).maxDamage(131))); - public static final Item STONE_SHOVEL = register(new TieredItem("stone_shovel", ToolTier.STONE, builder().stackSize(1).maxDamage(131))); - public static final Item STONE_PICKAXE = register(new TieredItem("stone_pickaxe", ToolTier.STONE, builder().stackSize(1).maxDamage(131))); - public static final Item STONE_AXE = register(new TieredItem("stone_axe", ToolTier.STONE, builder().stackSize(1).maxDamage(131))); - public static final Item STONE_HOE = register(new TieredItem("stone_hoe", ToolTier.STONE, builder().stackSize(1).maxDamage(131))); - public static final Item GOLDEN_SWORD = register(new TieredItem("golden_sword", ToolTier.GOLDEN, builder().stackSize(1).maxDamage(32))); - public static final Item GOLDEN_SHOVEL = register(new TieredItem("golden_shovel", ToolTier.GOLDEN, builder().stackSize(1).maxDamage(32))); - public static final Item GOLDEN_PICKAXE = register(new TieredItem("golden_pickaxe", ToolTier.GOLDEN, builder().stackSize(1).maxDamage(32))); - public static final Item GOLDEN_AXE = register(new TieredItem("golden_axe", ToolTier.GOLDEN, builder().stackSize(1).maxDamage(32))); - public static final Item GOLDEN_HOE = register(new TieredItem("golden_hoe", ToolTier.GOLDEN, builder().stackSize(1).maxDamage(32))); - public static final Item IRON_SWORD = register(new TieredItem("iron_sword", ToolTier.IRON, builder().stackSize(1).maxDamage(250))); - public static final Item IRON_SHOVEL = register(new TieredItem("iron_shovel", ToolTier.IRON, builder().stackSize(1).maxDamage(250))); - public static final Item IRON_PICKAXE = register(new TieredItem("iron_pickaxe", ToolTier.IRON, builder().stackSize(1).maxDamage(250))); - public static final Item IRON_AXE = register(new TieredItem("iron_axe", ToolTier.IRON, builder().stackSize(1).maxDamage(250))); - public static final Item IRON_HOE = register(new TieredItem("iron_hoe", ToolTier.IRON, builder().stackSize(1).maxDamage(250))); - public static final Item DIAMOND_SWORD = register(new TieredItem("diamond_sword", ToolTier.DIAMOND, builder().stackSize(1).maxDamage(1561))); - public static final Item DIAMOND_SHOVEL = register(new TieredItem("diamond_shovel", ToolTier.DIAMOND, builder().stackSize(1).maxDamage(1561))); - public static final Item DIAMOND_PICKAXE = register(new TieredItem("diamond_pickaxe", ToolTier.DIAMOND, builder().stackSize(1).maxDamage(1561))); - public static final Item DIAMOND_AXE = register(new TieredItem("diamond_axe", ToolTier.DIAMOND, builder().stackSize(1).maxDamage(1561))); - public static final Item DIAMOND_HOE = register(new TieredItem("diamond_hoe", ToolTier.DIAMOND, builder().stackSize(1).maxDamage(1561))); - public static final Item NETHERITE_SWORD = register(new TieredItem("netherite_sword", ToolTier.NETHERITE, builder().stackSize(1).maxDamage(2031))); - public static final Item NETHERITE_SHOVEL = register(new TieredItem("netherite_shovel", ToolTier.NETHERITE, builder().stackSize(1).maxDamage(2031))); - public static final Item NETHERITE_PICKAXE = register(new TieredItem("netherite_pickaxe", ToolTier.NETHERITE, builder().stackSize(1).maxDamage(2031))); - public static final Item NETHERITE_AXE = register(new TieredItem("netherite_axe", ToolTier.NETHERITE, builder().stackSize(1).maxDamage(2031))); - public static final Item NETHERITE_HOE = register(new TieredItem("netherite_hoe", ToolTier.NETHERITE, builder().stackSize(1).maxDamage(2031))); + public static final Item WOODEN_SWORD = register(new TieredItem("wooden_sword", ToolTier.WOODEN, builder().stackSize(1).attackDamage(4).maxDamage(59))); + public static final Item WOODEN_SHOVEL = register(new TieredItem("wooden_shovel", ToolTier.WOODEN, builder().stackSize(1).attackDamage(2.5).maxDamage(59))); + public static final Item WOODEN_PICKAXE = register(new TieredItem("wooden_pickaxe", ToolTier.WOODEN, builder().stackSize(1).attackDamage(2).maxDamage(59))); + public static final Item WOODEN_AXE = register(new TieredItem("wooden_axe", ToolTier.WOODEN, builder().stackSize(1).attackDamage(7).maxDamage(59))); + public static final Item WOODEN_HOE = register(new TieredItem("wooden_hoe", ToolTier.WOODEN, builder().stackSize(1).attackDamage(1).maxDamage(59))); + public static final Item STONE_SWORD = register(new TieredItem("stone_sword", ToolTier.STONE, builder().stackSize(1).attackDamage(5).maxDamage(131))); + public static final Item STONE_SHOVEL = register(new TieredItem("stone_shovel", ToolTier.STONE, builder().stackSize(1).attackDamage(3.5).maxDamage(131))); + public static final Item STONE_PICKAXE = register(new TieredItem("stone_pickaxe", ToolTier.STONE, builder().stackSize(1).attackDamage(3).maxDamage(131))); + public static final Item STONE_AXE = register(new TieredItem("stone_axe", ToolTier.STONE, builder().stackSize(1).attackDamage(9).maxDamage(131))); + public static final Item STONE_HOE = register(new TieredItem("stone_hoe", ToolTier.STONE, builder().stackSize(1).attackDamage(1).maxDamage(131))); + public static final Item GOLDEN_SWORD = register(new TieredItem("golden_sword", ToolTier.GOLDEN, builder().stackSize(1).attackDamage(4).maxDamage(32))); + public static final Item GOLDEN_SHOVEL = register(new TieredItem("golden_shovel", ToolTier.GOLDEN, builder().stackSize(1).attackDamage(2.5).maxDamage(32))); + public static final Item GOLDEN_PICKAXE = register(new TieredItem("golden_pickaxe", ToolTier.GOLDEN, builder().stackSize(1).attackDamage(2).maxDamage(32))); + public static final Item GOLDEN_AXE = register(new TieredItem("golden_axe", ToolTier.GOLDEN, builder().stackSize(1).attackDamage(7).maxDamage(32))); + public static final Item GOLDEN_HOE = register(new TieredItem("golden_hoe", ToolTier.GOLDEN, builder().stackSize(1).attackDamage(1).maxDamage(32))); + public static final Item IRON_SWORD = register(new TieredItem("iron_sword", ToolTier.IRON, builder().stackSize(1).attackDamage(6).maxDamage(250))); + public static final Item IRON_SHOVEL = register(new TieredItem("iron_shovel", ToolTier.IRON, builder().stackSize(1).attackDamage(4.5).maxDamage(250))); + public static final Item IRON_PICKAXE = register(new TieredItem("iron_pickaxe", ToolTier.IRON, builder().stackSize(1).attackDamage(4).maxDamage(250))); + public static final Item IRON_AXE = register(new TieredItem("iron_axe", ToolTier.IRON, builder().stackSize(1).attackDamage(9).maxDamage(250))); + public static final Item IRON_HOE = register(new TieredItem("iron_hoe", ToolTier.IRON, builder().stackSize(1).attackDamage(1).maxDamage(250))); + public static final Item DIAMOND_SWORD = register(new TieredItem("diamond_sword", ToolTier.DIAMOND, builder().stackSize(1).attackDamage(7).maxDamage(1561))); + public static final Item DIAMOND_SHOVEL = register(new TieredItem("diamond_shovel", ToolTier.DIAMOND, builder().stackSize(1).attackDamage(5.5).maxDamage(1561))); + public static final Item DIAMOND_PICKAXE = register(new TieredItem("diamond_pickaxe", ToolTier.DIAMOND, builder().stackSize(1).attackDamage(5).maxDamage(1561))); + public static final Item DIAMOND_AXE = register(new TieredItem("diamond_axe", ToolTier.DIAMOND, builder().stackSize(1).attackDamage(9).maxDamage(1561))); + public static final Item DIAMOND_HOE = register(new TieredItem("diamond_hoe", ToolTier.DIAMOND, builder().stackSize(1).attackDamage(1).maxDamage(1561))); + public static final Item NETHERITE_SWORD = register(new TieredItem("netherite_sword", ToolTier.NETHERITE, builder().stackSize(1).attackDamage(8).maxDamage(2031))); + public static final Item NETHERITE_SHOVEL = register(new TieredItem("netherite_shovel", ToolTier.NETHERITE, builder().stackSize(1).attackDamage(6.5).maxDamage(2031))); + public static final Item NETHERITE_PICKAXE = register(new TieredItem("netherite_pickaxe", ToolTier.NETHERITE, builder().stackSize(1).attackDamage(6).maxDamage(2031))); + public static final Item NETHERITE_AXE = register(new TieredItem("netherite_axe", ToolTier.NETHERITE, builder().stackSize(1).attackDamage(10).maxDamage(2031))); + public static final Item NETHERITE_HOE = register(new TieredItem("netherite_hoe", ToolTier.NETHERITE, builder().stackSize(1).attackDamage(1).maxDamage(2031))); public static final Item STICK = register(new Item("stick", builder())); public static final Item BOWL = register(new Item("bowl", builder())); public static final Item MUSHROOM_STEW = register(new Item("mushroom_stew", builder().stackSize(1))); @@ -1216,7 +1216,7 @@ public final class Items { public static final Item MUSIC_DISC_5 = register(new Item("music_disc_5", builder().stackSize(1))); public static final Item MUSIC_DISC_PIGSTEP = register(new Item("music_disc_pigstep", builder().stackSize(1))); public static final Item DISC_FRAGMENT_5 = register(new Item("disc_fragment_5", builder())); - public static final Item TRIDENT = register(new Item("trident", builder().stackSize(1).maxDamage(250))); + public static final Item TRIDENT = register(new Item("trident", builder().stackSize(1).attackDamage(9).maxDamage(250))); public static final Item PHANTOM_MEMBRANE = register(new Item("phantom_membrane", builder())); public static final Item NAUTILUS_SHELL = register(new Item("nautilus_shell", builder())); public static final Item HEART_OF_THE_SEA = register(new Item("heart_of_the_sea", builder())); diff --git a/core/src/main/java/org/geysermc/geyser/item/components/ToolTier.java b/core/src/main/java/org/geysermc/geyser/item/components/ToolTier.java index 8484eb185..a8832df1e 100644 --- a/core/src/main/java/org/geysermc/geyser/item/components/ToolTier.java +++ b/core/src/main/java/org/geysermc/geyser/item/components/ToolTier.java @@ -53,10 +53,6 @@ public enum ToolTier { this.repairIngredients = Suppliers.memoize(repairIngredients::get); } - public int getSpeed() { - return speed; - } - public Set getRepairIngredients() { return repairIngredients.get(); } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/Item.java b/core/src/main/java/org/geysermc/geyser/item/type/Item.java index 94bb3324e..3701b5189 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/Item.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/Item.java @@ -50,14 +50,14 @@ public class Item { private final String javaIdentifier; private int javaId = -1; private final int stackSize; - private final String toolType; + private final int attackDamage; private final int maxDamage; public Item(String javaIdentifier, Builder builder) { this.javaIdentifier = Identifier.formalize(javaIdentifier).intern(); this.stackSize = builder.stackSize; - this.toolType = builder.toolType; this.maxDamage = builder.maxDamage; + this.attackDamage = builder.attackDamage; } public String javaIdentifier() { @@ -72,6 +72,10 @@ public class Item { return maxDamage; } + public int attackDamage() { + return attackDamage; + } + public int maxStackSize() { return stackSize; } @@ -279,16 +283,17 @@ public class Item { public static final class Builder { private int stackSize = 64; - private String toolType; private int maxDamage; + private int attackDamage; public Builder stackSize(int stackSize) { this.stackSize = stackSize; return this; } - public Builder setToolType(String toolType) { - this.toolType = toolType; + public Builder attackDamage(double attackDamage) { + // TODO properly store/send a double value once Bedrock supports it.. pls + this.attackDamage = (int) attackDamage; return this; } diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java index 2e00bd4ad..baaa61204 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java @@ -153,7 +153,7 @@ public class CustomItemRegistryPopulator { .build(); NbtMapBuilder builder = createComponentNbt(customItemData, customItemData.identifier(), customItemId, - customItemData.creativeCategory(), customItemData.creativeGroup(), customItemData.isHat(), customItemData.displayHandheld(), protocolVersion); + customItemData.isHat(), customItemData.displayHandheld(), protocolVersion); ComponentItemData componentItemData = new ComponentItemData(customIdentifier, builder.build()); return new NonVanillaItemRegistration(componentItemData, item, customItemMapping); @@ -172,7 +172,7 @@ public class CustomItemRegistryPopulator { boolean canDestroyInCreative = true; if (mapping.getToolType() != null) { // This is not using the isTool boolean because it is not just a render type here. - canDestroyInCreative = computeToolProperties(mapping.getToolType(), itemProperties, componentBuilder); + canDestroyInCreative = computeToolProperties(mapping.getToolType(), itemProperties, componentBuilder, javaItem.attackDamage()); } itemProperties.putBoolean("can_destroy_in_creative", canDestroyInCreative); @@ -208,10 +208,8 @@ public class CustomItemRegistryPopulator { return builder; } - @SuppressWarnings("OptionalUsedAsFieldOrParameterType") private static NbtMapBuilder createComponentNbt(NonVanillaCustomItemData customItemData, String customItemName, - int customItemId, OptionalInt creativeCategory, - String creativeGroup, boolean isHat, boolean displayHandheld, int protocolVersion) { + int customItemId, boolean isHat, boolean displayHandheld, int protocolVersion) { NbtMapBuilder builder = NbtMap.builder(); builder.putString("name", customItemName) .putInt("id", customItemId); @@ -223,7 +221,7 @@ public class CustomItemRegistryPopulator { boolean canDestroyInCreative = true; if (customItemData.toolType() != null) { // This is not using the isTool boolean because it is not just a render type here. - canDestroyInCreative = computeToolProperties(Objects.requireNonNull(customItemData.toolType()), itemProperties, componentBuilder); + canDestroyInCreative = computeToolProperties(Objects.requireNonNull(customItemData.toolType()), itemProperties, componentBuilder, customItemData.attackDamage()); } itemProperties.putBoolean("can_destroy_in_creative", canDestroyInCreative); @@ -311,7 +309,7 @@ public class CustomItemRegistryPopulator { /** * @return can destroy in creative */ - private static boolean computeToolProperties(String toolType, NbtMapBuilder itemProperties, NbtMapBuilder componentBuilder) { + private static boolean computeToolProperties(String toolType, NbtMapBuilder itemProperties, NbtMapBuilder componentBuilder, int attackDamage) { boolean canDestroyInCreative = true; float miningSpeed = 1.0f; @@ -362,6 +360,11 @@ public class CustomItemRegistryPopulator { itemProperties.putInt("enchantable_value", 1); itemProperties.putString("enchantable_slot", toolType); + // Adds a "attack damage" indicator. Purely visual! + if (attackDamage > 0) { + itemProperties.putInt("damage", attackDamage); + } + return canDestroyInCreative; } From 867cf6da05c56ea5ead21533a6bfdebc601e60bf Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 19 Mar 2024 23:05:30 +0100 Subject: [PATCH 025/272] Feature: JiJ dependencies on modded platforms (#4502) * Use JiJ inclusion for Fabric/NeoForge to prevent mod conflicts. Further: Don't publish shadow jars to maven. * Shade and relocate dependencies that don't conform to SemVer on Fabric * Shade/Relocate dependencies on Fabric to avoid version warnings * Use relocate function from the build-logic plugin --- bootstrap/bungeecord/build.gradle.kts | 2 +- bootstrap/mod/fabric/build.gradle.kts | 41 +++++++++-- bootstrap/mod/neoforge/build.gradle.kts | 19 +++-- bootstrap/spigot/build.gradle.kts | 17 ++--- bootstrap/velocity/build.gradle.kts | 2 + bootstrap/viaproxy/build.gradle.kts | 2 + build-logic/src/main/kotlin/extensions.kt | 15 ++-- .../geyser.modded-conventions.gradle.kts | 72 +++++++++++++------ .../geyser.publish-conventions.gradle.kts | 6 ++ .../geyser.shadow-conventions.gradle.kts | 1 - 10 files changed, 117 insertions(+), 60 deletions(-) diff --git a/bootstrap/bungeecord/build.gradle.kts b/bootstrap/bungeecord/build.gradle.kts index 4025569dd..1b57ffa5a 100644 --- a/bootstrap/bungeecord/build.gradle.kts +++ b/bootstrap/bungeecord/build.gradle.kts @@ -1,7 +1,7 @@ dependencies { api(projects.core) - implementation(libs.adventure.text.serializer.bungeecord) + compileOnlyApi(libs.bungeecord.proxy) } platformRelocate("net.md_5.bungee.jni") diff --git a/bootstrap/mod/fabric/build.gradle.kts b/bootstrap/mod/fabric/build.gradle.kts index dac042ad7..eb28e0e93 100644 --- a/bootstrap/mod/fabric/build.gradle.kts +++ b/bootstrap/mod/fabric/build.gradle.kts @@ -7,6 +7,8 @@ architectury { fabric() } +val includeTransitive: Configuration = configurations.getByName("includeTransitive") + dependencies { modImplementation(libs.fabric.loader) modApi(libs.fabric.api) @@ -15,14 +17,29 @@ dependencies { shadow(project(path = ":mod", configuration = "transformProductionFabric")) { isTransitive = false } - shadow(projects.core) { - exclude(group = "com.google.guava", module = "guava") - exclude(group = "com.google.code.gson", module = "gson") - exclude(group = "org.slf4j") - exclude(group = "com.nukkitx.fastutil") - exclude(group = "io.netty.incubator") - } + shadow(projects.core) { isTransitive = false } + includeTransitive(projects.core) + // These are NOT transitively included, and instead shadowed + relocated. + // Avoids fabric complaining about non-SemVer versioning + // TODO: re-evaluate after loom 1.6 (https://github.com/FabricMC/fabric-loom/pull/1075) + shadow(libs.protocol.connection) { isTransitive = false } + shadow(libs.protocol.common) { isTransitive = false } + shadow(libs.protocol.codec) { isTransitive = false } + shadow(libs.mcauthlib) { isTransitive = false } + shadow(libs.raknet) { isTransitive = false } + shadow(libs.netty.codec.haproxy) { isTransitive = false } + shadow("org.cloudburstmc:nbt:3.0.2.Final") { isTransitive = false } + shadow("io.netty:netty-codec-dns:4.1.103.Final") { isTransitive = false } + shadow("io.netty:netty-resolver-dns-classes-macos:4.1.103.Final") { isTransitive = false } + + // Consequences of shading + relocating mcauthlib: shadow/relocate mcpl! + shadow(libs.mcprotocollib) { isTransitive = false } + + // Since we also relocate cloudburst protocol: shade erosion common + shadow(libs.erosion.common) { isTransitive = false } + + // Permissions modImplementation(libs.fabric.permissions) include(libs.fabric.permissions) } @@ -31,6 +48,16 @@ application { mainClass.set("org.geysermc.geyser.platform.fabric.GeyserFabricMain") } +relocate("org.cloudburstmc.nbt") +relocate("org.cloudburstmc.netty") +relocate("org.cloudburstmc.protocol") +relocate("io.netty.handler.codec.dns") +relocate("io.netty.handler.codec.haproxy") +relocate("io.netty.resolver.dns.macos") +relocate("com.github.steveice10.mc.protocol") +relocate("com.github.steveice10.mc.auth") +relocate("com.github.steveice10.packetlib") + tasks { remapJar { archiveBaseName.set("Geyser-Fabric") diff --git a/bootstrap/mod/neoforge/build.gradle.kts b/bootstrap/mod/neoforge/build.gradle.kts index d85087542..2a414e6dd 100644 --- a/bootstrap/mod/neoforge/build.gradle.kts +++ b/bootstrap/mod/neoforge/build.gradle.kts @@ -2,11 +2,17 @@ plugins { application } +// This is provided by "org.cloudburstmc.math.mutable" too, so yeet. +// NeoForge's class loader is *really* annoying. +provided("org.cloudburstmc.math", "api") + architectury { platformSetupLoomIde() neoForge() } +val includeTransitive: Configuration = configurations.getByName("includeTransitive") + dependencies { // See https://github.com/google/guava/issues/6618 modules { @@ -21,12 +27,9 @@ dependencies { shadow(project(path = ":mod", configuration = "transformProductionNeoForge")) { isTransitive = false } - shadow(projects.core) { - exclude(group = "com.google.guava", module = "guava") - exclude(group = "com.google.code.gson", module = "gson") - exclude(group = "org.slf4j") - exclude(group = "io.netty.incubator") - } + shadow(project(path = ":core")) { isTransitive = false } + + includeTransitive(projects.core) } application { @@ -34,10 +37,6 @@ application { } tasks { - shadowJar { - relocate("it.unimi.dsi.fastutil", "org.geysermc.relocate.fastutil") - } - remapJar { archiveBaseName.set("Geyser-NeoForge") } diff --git a/bootstrap/spigot/build.gradle.kts b/bootstrap/spigot/build.gradle.kts index 129064cd4..41da1a0de 100644 --- a/bootstrap/spigot/build.gradle.kts +++ b/bootstrap/spigot/build.gradle.kts @@ -11,18 +11,11 @@ dependencies { implementation(libs.commodore) implementation(libs.adventure.text.serializer.bungeecord) - - // Both folia-api and paper-mojangapi only provide Java 17 versions for 1.19 - compileOnly(libs.folia.api) { - attributes { - attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 17) - } - } - compileOnly(libs.paper.mojangapi) { - attributes { - attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 17) - } - } + + compileOnly(libs.folia.api) + compileOnly(libs.paper.mojangapi) + + compileOnlyApi(libs.viaversion) } platformRelocate("it.unimi.dsi.fastutil") diff --git a/bootstrap/velocity/build.gradle.kts b/bootstrap/velocity/build.gradle.kts index 8908b2afd..a21fb2349 100644 --- a/bootstrap/velocity/build.gradle.kts +++ b/bootstrap/velocity/build.gradle.kts @@ -1,6 +1,8 @@ dependencies { annotationProcessor(libs.velocity.api) api(projects.core) + + compileOnlyApi(libs.velocity.api) } platformRelocate("com.fasterxml.jackson") diff --git a/bootstrap/viaproxy/build.gradle.kts b/bootstrap/viaproxy/build.gradle.kts index 4d5d4f949..01c5b5b34 100644 --- a/bootstrap/viaproxy/build.gradle.kts +++ b/bootstrap/viaproxy/build.gradle.kts @@ -1,5 +1,7 @@ dependencies { api(projects.core) + + compileOnlyApi(libs.viaproxy) } platformRelocate("net.kyori") diff --git a/build-logic/src/main/kotlin/extensions.kt b/build-logic/src/main/kotlin/extensions.kt index b4a14f678..41e11344b 100644 --- a/build-logic/src/main/kotlin/extensions.kt +++ b/build-logic/src/main/kotlin/extensions.kt @@ -58,19 +58,20 @@ fun Project.platformRelocate(pattern: String, exclusion: String = "") { val providedDependencies = mutableMapOf>() -fun Project.provided(pattern: String, name: String, version: String, excludedOn: Int = 0b110) { +fun getProvidedDependenciesForProject(projectName: String): MutableSet { + return providedDependencies.getOrDefault(projectName, emptySet()).toMutableSet() +} + +fun Project.provided(pattern: String, name: String, excludedOn: Int = 0b110) { providedDependencies.getOrPut(project.name) { mutableSetOf() } - .add("${calcExclusion(pattern, 0b100, excludedOn)}:" + - "${calcExclusion(name, 0b10, excludedOn)}:" + - calcExclusion(version, 0b1, excludedOn)) - dependencies.add("compileOnlyApi", "$pattern:$name:$version") + .add("${calcExclusion(pattern, 0b100, excludedOn)}:${calcExclusion(name, 0b10, excludedOn)}") } fun Project.provided(dependency: ProjectDependency) = - provided(dependency.group!!, dependency.name, dependency.version!!) + provided(dependency.group!!, dependency.name) fun Project.provided(dependency: MinimalExternalModuleDependency) = - provided(dependency.module.group, dependency.module.name, dependency.versionConstraint.requiredVersion) + provided(dependency.module.group, dependency.module.name) fun Project.provided(provider: Provider) = provided(provider.get()) diff --git a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts index 0842eae84..91bde525e 100644 --- a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts @@ -11,6 +11,31 @@ plugins { id("com.modrinth.minotaur") } +// These are provided by Minecraft/modded platforms already, no need to include them +provided("com.google.code.gson", "gson") +provided("com.google.guava", ".*") +provided("org.slf4j", "slf4j-api") +provided("com.nukkitx.fastutil", ".*") +provided("org.cloudburstmc.fastutil.maps", ".*") +provided("org.cloudburstmc.fastutil.sets", ".*") +provided("org.cloudburstmc.fastutil.commons", ".*") +provided("org.cloudburstmc.fastutil", ".*") +provided("org.checkerframework", "checker-qual") +provided("io.netty", "netty-transport-classes-epoll") +provided("io.netty", "netty-transport-native-epoll") +provided("io.netty", "netty-transport-native-unix-common") +provided("io.netty", "netty-transport-classes-kqueue") +provided("io.netty", "netty-transport-native-kqueue") +provided("io.netty", "netty-handler") +provided("io.netty", "netty-common") +provided("io.netty", "netty-buffer") +provided("io.netty", "netty-resolver") +provided("io.netty", "netty-transport") +provided("io.netty", "netty-codec") +provided("io.netty", "netty-resolver-dns") +provided("io.netty", "netty-resolver-dns-native-macos") +provided("org.ow2.asm", "asm") + architectury { minecraft = "1.20.4" } @@ -19,6 +44,10 @@ loom { silentMojangMappingsLicense() } +configurations { + create("includeTransitive").isTransitive = true +} + tasks { // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task // if it is present. @@ -34,28 +63,6 @@ tasks { // The remapped shadowJar is the final desired mod jar archiveVersion.set(project.version.toString()) archiveClassifier.set("shaded") - - relocate("org.objectweb.asm", "org.geysermc.relocate.asm") - relocate("org.yaml", "org.geysermc.relocate.yaml") // https://github.com/CardboardPowered/cardboard/issues/139 - relocate("com.fasterxml.jackson", "org.geysermc.relocate.jackson") - relocate("net.kyori", "org.geysermc.relocate.kyori") - - dependencies { - // Exclude everything EXCEPT some DNS stuff required for HAProxy - exclude(dependency("io.netty:netty-transport-classes-epoll:.*")) - exclude(dependency("io.netty:netty-transport-native-epoll:.*")) - exclude(dependency("io.netty:netty-transport-native-unix-common:.*")) - exclude(dependency("io.netty:netty-transport-classes-kqueue:.*")) - exclude(dependency("io.netty:netty-transport-native-kqueue:.*")) - exclude(dependency("io.netty:netty-handler:.*")) - exclude(dependency("io.netty:netty-common:.*")) - exclude(dependency("io.netty:netty-buffer:.*")) - exclude(dependency("io.netty:netty-resolver:.*")) - exclude(dependency("io.netty:netty-transport:.*")) - exclude(dependency("io.netty:netty-codec:.*")) - exclude(dependency("io.netty:netty-resolver-dns:.*")) - exclude(dependency("io.netty:netty-resolver-dns-native-macos:.*")) - } } remapJar { @@ -73,6 +80,27 @@ tasks { } } +afterEvaluate { + val providedDependencies = getProvidedDependenciesForProject(project.name) + + // These are shaded, no need to JiJ them + configurations["shadow"].dependencies.forEach {shadowed -> + println("Not including shadowed dependency: ${shadowed.group}:${shadowed.name}") + providedDependencies.add("${shadowed.group}:${shadowed.name}") + } + + // Now: Include all transitive dependencies that aren't excluded + configurations["includeTransitive"].resolvedConfiguration.resolvedArtifacts.forEach { dep -> + if (!providedDependencies.contains("${dep.moduleVersion.id.group}:${dep.moduleVersion.id.name}") + and !providedDependencies.contains("${dep.moduleVersion.id.group}:.*")) { + println("Including dependency via JiJ: ${dep.id}") + dependencies.add("include", dep.moduleVersion.id.toString()) + } else { + println("Not including ${dep.id} for ${project.name}!") + } + } +} + dependencies { minecraft("com.mojang:minecraft:1.20.4") mappings(loom.officialMojangMappings()) diff --git a/build-logic/src/main/kotlin/geyser.publish-conventions.gradle.kts b/build-logic/src/main/kotlin/geyser.publish-conventions.gradle.kts index 036ee803c..eca587721 100644 --- a/build-logic/src/main/kotlin/geyser.publish-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/geyser.publish-conventions.gradle.kts @@ -7,3 +7,9 @@ indra { publishSnapshotsTo("geysermc", "https://repo.opencollab.dev/maven-snapshots") publishReleasesTo("geysermc", "https://repo.opencollab.dev/maven-releases") } + +publishing { + // skip shadow jar from publishing. Workaround for https://github.com/johnrengelman/shadow/issues/651 + val javaComponent = project.components["java"] as AdhocComponentWithVariants + javaComponent.withVariantsFromConfiguration(configurations["shadowRuntimeElements"]) { skip() } +} \ No newline at end of file diff --git a/build-logic/src/main/kotlin/geyser.shadow-conventions.gradle.kts b/build-logic/src/main/kotlin/geyser.shadow-conventions.gradle.kts index dde85c33a..c160e5ec6 100644 --- a/build-logic/src/main/kotlin/geyser.shadow-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/geyser.shadow-conventions.gradle.kts @@ -7,7 +7,6 @@ plugins { tasks { named("jar") { - archiveClassifier.set("unshaded") from(project.rootProject.file("LICENSE")) } val shadowJar = named("shadowJar") { From 4fa0bcd01b9ca897bf33f4e6d2187997caadb22b Mon Sep 17 00:00:00 2001 From: chris Date: Thu, 21 Mar 2024 19:05:41 +0100 Subject: [PATCH 026/272] Update Jackson (#4512) * Update jackson * relocate yaml on velocity --- bootstrap/velocity/build.gradle.kts | 1 + .../geysermc/geyser/extension/GeyserExtensionDescription.java | 3 ++- gradle/libs.versions.toml | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/bootstrap/velocity/build.gradle.kts b/bootstrap/velocity/build.gradle.kts index a21fb2349..97e9d1f57 100644 --- a/bootstrap/velocity/build.gradle.kts +++ b/bootstrap/velocity/build.gradle.kts @@ -8,6 +8,7 @@ dependencies { platformRelocate("com.fasterxml.jackson") platformRelocate("it.unimi.dsi.fastutil") platformRelocate("net.kyori.adventure.text.serializer.gson.legacyimpl") +platformRelocate("org.yaml") exclude("com.google.*:*") diff --git a/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionDescription.java b/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionDescription.java index 716b763f5..239ffc450 100644 --- a/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionDescription.java +++ b/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionDescription.java @@ -31,6 +31,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.api.extension.ExtensionDescription; import org.geysermc.geyser.api.extension.exception.InvalidDescriptionException; import org.geysermc.geyser.text.GeyserLocale; +import org.yaml.snakeyaml.LoaderOptions; import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.constructor.CustomClassLoaderConstructor; @@ -48,7 +49,7 @@ public record GeyserExtensionDescription(@NonNull String id, @NonNull String version, @NonNull List authors) implements ExtensionDescription { - private static final Yaml YAML = new Yaml(new CustomClassLoaderConstructor(Source.class.getClassLoader())); + private static final Yaml YAML = new Yaml(new CustomClassLoaderConstructor(Source.class.getClassLoader(), new LoaderOptions())); public static final Pattern ID_PATTERN = Pattern.compile("[a-z][a-z0-9-_]{0,63}"); public static final Pattern NAME_PATTERN = Pattern.compile("^[A-Za-z_.-]+$"); diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 73417f23a..377172346 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,7 +3,7 @@ base-api = "1.0.0-SNAPSHOT" cumulus = "1.1.2" erosion = "1.0-20230406.174837-8" events = "1.1-SNAPSHOT" -jackson = { strictly = "2.14.0" } # Don't let other dependencies override +jackson = "2.17.0" fastutil = "8.5.2" netty = "4.1.107.Final" guava = "29.0-jre" @@ -38,7 +38,7 @@ mixin = "0.8.5" # plugin versions indra = "3.1.3" -shadow = "7.1.3-SNAPSHOT" +shadow = "8.1.1" architectury-plugin = "3.4-SNAPSHOT" architectury-loom = "1.4-SNAPSHOT" minotaur = "2.8.7" From c64e8afccebebd8cf23f0c3562dba7bd1350b2c5 Mon Sep 17 00:00:00 2001 From: CloudyOrk <120650272+CloudyOrk@users.noreply.github.com> Date: Sat, 23 Mar 2024 00:33:17 +0530 Subject: [PATCH 027/272] Indicate existing 1.20.72 support (#4515) * update supported version * Update GameProtocol.java * Update GameProtocol.java --------- Co-authored-by: Kas-tle <26531652+Kas-tle@users.noreply.github.com> --- README.md | 2 +- .../src/main/java/org/geysermc/geyser/network/GameProtocol.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 76a62a462..8a28e7177 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here! -### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.71 and Minecraft Java 1.20.4 +### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.72 and Minecraft Java 1.20.4 ## Setting Up Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser. diff --git a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java index 80d2038d9..900463c5c 100644 --- a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java +++ b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java @@ -72,7 +72,7 @@ public final class GameProtocol { .minecraftVersion("1.20.60/1.20.62") .build()); SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC.toBuilder() - .minecraftVersion("1.20.70/1.20.71") + .minecraftVersion("1.20.70/1.20.72") .build()); } From d24a4766b4e332f5964165f66f57ae7d0f7d0f83 Mon Sep 17 00:00:00 2001 From: chris Date: Sun, 24 Mar 2024 17:12:40 +0100 Subject: [PATCH 028/272] Shade the Geyser api on modded platforms (#4520) --- bootstrap/mod/fabric/build.gradle.kts | 3 +++ bootstrap/mod/neoforge/build.gradle.kts | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/bootstrap/mod/fabric/build.gradle.kts b/bootstrap/mod/fabric/build.gradle.kts index eb28e0e93..538147b15 100644 --- a/bootstrap/mod/fabric/build.gradle.kts +++ b/bootstrap/mod/fabric/build.gradle.kts @@ -39,6 +39,9 @@ dependencies { // Since we also relocate cloudburst protocol: shade erosion common shadow(libs.erosion.common) { isTransitive = false } + // Let's shade in our own api + shadow(projects.api) { isTransitive = false } + // Permissions modImplementation(libs.fabric.permissions) include(libs.fabric.permissions) diff --git a/bootstrap/mod/neoforge/build.gradle.kts b/bootstrap/mod/neoforge/build.gradle.kts index 2a414e6dd..f7204332b 100644 --- a/bootstrap/mod/neoforge/build.gradle.kts +++ b/bootstrap/mod/neoforge/build.gradle.kts @@ -27,8 +27,12 @@ dependencies { shadow(project(path = ":mod", configuration = "transformProductionNeoForge")) { isTransitive = false } - shadow(project(path = ":core")) { isTransitive = false } + shadow(projects.core) { isTransitive = false } + // Let's shade in our own api + shadow(projects.api) { isTransitive = false } + + // Include all transitive deps of core via JiJ includeTransitive(projects.core) } From 4ea94f89a2a54775330fdca3096cbad6d89255d3 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Sun, 24 Mar 2024 21:30:00 +0000 Subject: [PATCH 029/272] Fix entity pick request for cherry and bamboo boats (#4522) --- .../bedrock/BedrockEntityPickRequestTranslator.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockEntityPickRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockEntityPickRequestTranslator.java index f64ddeac6..e85456c33 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockEntityPickRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockEntityPickRequestTranslator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -62,13 +62,17 @@ public class BedrockEntityPickRequestTranslator extends PacketTranslator "birch"; case 3 -> "jungle"; case 4 -> "acacia"; - //case 5 -> "cherry"; TODO + case 5 -> "cherry"; case 6 -> "dark_oak"; case 7 -> "mangrove"; - //case 8 -> "bamboo"; + case 8 -> "bamboo"; default -> "oak"; }; itemName = typeOfBoat + "_" + entity.getDefinition().entityType().name().toLowerCase(Locale.ROOT); + // Bamboo boat is a raft + if (variant == 8) { + itemName = itemName.replace("boat", "raft"); + } } case LEASH_KNOT -> itemName = "lead"; case CHEST_MINECART, COMMAND_BLOCK_MINECART, FURNACE_MINECART, HOPPER_MINECART, TNT_MINECART -> From 85908690a340120f3cafe45eb2d286b15a1f83c2 Mon Sep 17 00:00:00 2001 From: chris Date: Wed, 27 Mar 2024 01:47:21 +0100 Subject: [PATCH 030/272] Revert inventory "fix" that's causing issues with quickly opening & closing inventories (#4523) --- .../bedrock/entity/player/BedrockInteractTranslator.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockInteractTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockInteractTranslator.java index 07e192bb7..a45690ab1 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockInteractTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockInteractTranslator.java @@ -126,12 +126,7 @@ public class BedrockInteractTranslator extends PacketTranslator } else { InventoryUtils.openInventory(session, session.getPlayerInventory()); } - } else { - // Case: Player tries to open a player inventory, while we think it should be in a different inventory - // Now: Open the inventory that we're supposed to be in. - InventoryUtils.openInventory(session, session.getOpenInventory()); } - break; } } } From f1828419d631c43ef27b06d62a646229d2482236 Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Thu, 28 Mar 2024 17:28:49 -0700 Subject: [PATCH 031/272] Update raknet (#4528) --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 377172346..b34f37d76 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,7 +11,7 @@ gson = "2.3.1" # Provided by Spigot 1.8.8 websocket = "1.5.1" protocol = "3.0.0.Beta1-20240313.120922-126" protocol-connection = "3.0.0.Beta1-20240313.120922-125" -raknet = "1.0.0.CR1-20231206.145325-12" +raknet = "1.0.0.CR1-20240328.213920-13" blockstateupdater="1.20.70-20240303.125052-2" mcauthlib = "d9d773e" mcprotocollib = "1.20.4-2-20240116.220521-7" From 7da3afef603dad61b3504ab5486bf577c0d7d336 Mon Sep 17 00:00:00 2001 From: Redned Date: Fri, 29 Mar 2024 12:25:57 +0000 Subject: [PATCH 032/272] Update RakNet --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b34f37d76..35ba90597 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,7 +11,7 @@ gson = "2.3.1" # Provided by Spigot 1.8.8 websocket = "1.5.1" protocol = "3.0.0.Beta1-20240313.120922-126" protocol-connection = "3.0.0.Beta1-20240313.120922-125" -raknet = "1.0.0.CR1-20240328.213920-13" +raknet = "1.0.0.CR1-20240329.101527-14" blockstateupdater="1.20.70-20240303.125052-2" mcauthlib = "d9d773e" mcprotocollib = "1.20.4-2-20240116.220521-7" From b469904951bfa38ad5e950d58bb3e0dcbe2b9d73 Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Sat, 30 Mar 2024 03:27:55 -0700 Subject: [PATCH 033/272] Update Raknet (#4529) --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 35ba90597..0e446a48f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,7 +11,7 @@ gson = "2.3.1" # Provided by Spigot 1.8.8 websocket = "1.5.1" protocol = "3.0.0.Beta1-20240313.120922-126" protocol-connection = "3.0.0.Beta1-20240313.120922-125" -raknet = "1.0.0.CR1-20240329.101527-14" +raknet = "1.0.0.CR1-20240330.101522-15" blockstateupdater="1.20.70-20240303.125052-2" mcauthlib = "d9d773e" mcprotocollib = "1.20.4-2-20240116.220521-7" From fbafdbb2a708971917cb51e0d088e247370d601f Mon Sep 17 00:00:00 2001 From: rtm516 Date: Sun, 31 Mar 2024 12:01:59 +0100 Subject: [PATCH 034/272] Allow NonVanillaCustomItemData to have a block assigned (#4530) --- .../item/custom/NonVanillaCustomItemData.java | 11 ++++++++++- .../item/GeyserNonVanillaCustomItemData.java | 16 +++++++++++++++- .../populator/CustomItemRegistryPopulator.java | 7 ++++++- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java index 59e2faad8..2c283780c 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -161,6 +161,13 @@ public interface NonVanillaCustomItemData extends CustomItemData { return displayHandheld(); } + /** + * Gets the block the item places. + * + * @return the block the item places + */ + String block(); + static NonVanillaCustomItemData.Builder builder() { return GeyserApi.api().provider(NonVanillaCustomItemData.Builder.class); } @@ -201,6 +208,8 @@ public interface NonVanillaCustomItemData extends CustomItemData { Builder chargeable(boolean isChargeable); + Builder block(String block); + /** * @deprecated Use {@link #displayHandheld(boolean)} instead. */ diff --git a/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java b/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java index 9d86bfa96..9c9269df3 100644 --- a/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java +++ b/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -55,6 +55,7 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i private final boolean isEdible; private final boolean canAlwaysEat; private final boolean isChargeable; + private final String block; public GeyserNonVanillaCustomItemData(Builder builder) { super(builder.name, builder.customItemOptions, builder.displayName, builder.icon, builder.allowOffhand, @@ -78,6 +79,7 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i this.isEdible = builder.edible; this.canAlwaysEat = builder.canAlwaysEat; this.isChargeable = builder.chargeable; + this.block = builder.block; } @Override @@ -160,6 +162,11 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i return isChargeable; } + @Override + public String block() { + return block; + } + public static class Builder extends GeyserCustomItemData.Builder implements NonVanillaCustomItemData.Builder { private String identifier = null; private int javaId = -1; @@ -186,6 +193,7 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i private boolean edible = false; private boolean canAlwaysEat = false; private boolean chargeable = false; + private String block = null; @Override public Builder name(@NonNull String name) { @@ -339,6 +347,12 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i return this; } + @Override + public Builder block(String block) { + this.block = block; + return this; + } + @Override public NonVanillaCustomItemData build() { if (identifier == null || javaId == -1) { diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java index baaa61204..10d87a8a9 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -248,6 +248,11 @@ public class CustomItemRegistryPopulator { itemProperties.putBoolean("foil", true); } + String block = customItemData.block(); + if (block != null) { + computeBlockItemProperties(block, componentBuilder); + } + componentBuilder.putCompound("item_properties", itemProperties.build()); builder.putCompound("components", componentBuilder.build()); From c9ca4c82f73f6ac0d8d5028753f73e4d7db3cdba Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Sun, 31 Mar 2024 21:42:31 -0700 Subject: [PATCH 035/272] Allow configuration of RakNet limits (#4532) * Allow configuration of RakNet limits Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Validate packet limiter system properties Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> --------- Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> --- .../GeyserJacksonConfiguration.java | 15 ++++- .../geyser/network/netty/GeyserServer.java | 55 ++++++++++++++++++- .../org/geysermc/geyser/util/FileUtils.java | 3 + .../org/geysermc/geyser/util/WebUtils.java | 30 ++++++++++ core/src/main/resources/config.yml | 4 +- gradle/libs.versions.toml | 2 +- 6 files changed, 102 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java b/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java index b3b7e8cd4..a55e4af8f 100644 --- a/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java +++ b/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java @@ -40,9 +40,11 @@ import org.geysermc.geyser.api.network.AuthType; import org.geysermc.geyser.network.CIDRMatcher; import org.geysermc.geyser.text.AsteriskSerializer; import org.geysermc.geyser.text.GeyserLocale; +import org.geysermc.geyser.util.WebUtils; import java.io.IOException; import java.nio.file.Path; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.UUID; @@ -233,7 +235,18 @@ public abstract class GeyserJacksonConfiguration implements GeyserConfiguration List matchers = this.whitelistedIPsMatchers; if (matchers == null) { synchronized (this) { - this.whitelistedIPsMatchers = matchers = proxyProtocolWhitelistedIPs.stream() + // Check if proxyProtocolWhitelistedIPs contains URLs we need to fetch and parse by line + List whitelistedCIDRs = new ArrayList<>(); + for (String ip: proxyProtocolWhitelistedIPs) { + if (!ip.startsWith("http")) { + whitelistedCIDRs.add(ip); + continue; + } + + WebUtils.getLineStream(ip).forEach(whitelistedCIDRs::add); + } + + this.whitelistedIPsMatchers = matchers = whitelistedCIDRs.stream() .map(CIDRMatcher::new) .collect(Collectors.toList()); } diff --git a/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java b/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java index ea1dcb509..ce904d465 100644 --- a/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java +++ b/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java @@ -46,6 +46,7 @@ import net.jodah.expiringmap.ExpiringMap; import org.cloudburstmc.netty.channel.raknet.RakChannelFactory; import org.cloudburstmc.netty.channel.raknet.config.RakChannelOption; import org.cloudburstmc.netty.handler.codec.raknet.server.RakServerOfflineHandler; +import org.cloudburstmc.netty.handler.codec.raknet.server.RakServerRateLimiter; import org.cloudburstmc.protocol.bedrock.BedrockPong; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.command.defaults.ConnectionTestCommand; @@ -71,6 +72,10 @@ import java.util.concurrent.TimeUnit; import java.util.function.IntFunction; import java.util.function.Supplier; +import static org.cloudburstmc.netty.channel.raknet.RakConstants.DEFAULT_GLOBAL_PACKET_LIMIT; +import static org.cloudburstmc.netty.channel.raknet.RakConstants.DEFAULT_OFFLINE_PACKET_LIMIT; +import static org.cloudburstmc.netty.channel.raknet.RakConstants.DEFAULT_PACKET_LIMIT; + public final class GeyserServer { private static final boolean PRINT_DEBUG_PINGS = Boolean.parseBoolean(System.getProperty("Geyser.PrintPingsInDebugMode", "true")); @@ -141,23 +146,31 @@ public final class GeyserServer { bootstrapFutures = new ChannelFuture[listenCount]; for (int i = 0; i < listenCount; i++) { ChannelFuture future = bootstrap.bind(address); - addHandlers(future); + modifyHandlers(future); bootstrapFutures[i] = future; } return Bootstraps.allOf(bootstrapFutures); } - private void addHandlers(ChannelFuture future) { + private void modifyHandlers(ChannelFuture future) { Channel channel = future.channel(); // Add our ping handler channel.pipeline() .addFirst(RakConnectionRequestHandler.NAME, new RakConnectionRequestHandler(this)) .addAfter(RakServerOfflineHandler.NAME, RakPingHandler.NAME, new RakPingHandler(this)); + // Add proxy handler - if (this.geyser.getConfig().getBedrock().isEnableProxyProtocol()) { + boolean isProxyProtocol = this.geyser.getConfig().getBedrock().isEnableProxyProtocol(); + if (isProxyProtocol) { channel.pipeline().addFirst("proxy-protocol-decoder", new ProxyServerHandler()); } + + boolean isWhitelistedProxyProtocol = isProxyProtocol && !this.geyser.getConfig().getBedrock().getProxyProtocolWhitelistedIPs().isEmpty(); + if (Boolean.parseBoolean(System.getProperty("Geyser.RakRateLimitingDisabled", "false")) || isWhitelistedProxyProtocol) { + // We would already block any non-whitelisted IP addresses in onConnectionRequest so we can remove the rate limiter + channel.pipeline().remove(RakServerRateLimiter.NAME); + } } public void shutdown() { @@ -199,11 +212,26 @@ public final class GeyserServer { GeyserServerInitializer serverInitializer = new GeyserServerInitializer(this.geyser); playerGroup = serverInitializer.getEventLoopGroup(); this.geyser.getLogger().debug("Setting MTU to " + this.geyser.getConfig().getMtu()); + + int rakPacketLimit = positivePropOrDefault("Geyser.RakPacketLimit", DEFAULT_PACKET_LIMIT); + this.geyser.getLogger().debug("Setting RakNet packet limit to " + rakPacketLimit); + + boolean isWhitelistedProxyProtocol = this.geyser.getConfig().getBedrock().isEnableProxyProtocol() + && !this.geyser.getConfig().getBedrock().getProxyProtocolWhitelistedIPs().isEmpty(); + int rakOfflinePacketLimit = positivePropOrDefault("Geyser.RakOfflinePacketLimit", isWhitelistedProxyProtocol ? Integer.MAX_VALUE : DEFAULT_OFFLINE_PACKET_LIMIT); + this.geyser.getLogger().debug("Setting RakNet offline packet limit to " + rakOfflinePacketLimit); + + int rakGlobalPacketLimit = positivePropOrDefault("Geyser.RakGlobalPacketLimit", DEFAULT_GLOBAL_PACKET_LIMIT); + this.geyser.getLogger().debug("Setting RakNet global packet limit to " + rakGlobalPacketLimit); + return new ServerBootstrap() .channelFactory(RakChannelFactory.server(TRANSPORT.datagramChannel())) .group(group, childGroup) .option(RakChannelOption.RAK_HANDLE_PING, true) .option(RakChannelOption.RAK_MAX_MTU, this.geyser.getConfig().getMtu()) + .option(RakChannelOption.RAK_PACKET_LIMIT, rakPacketLimit) + .option(RakChannelOption.RAK_OFFLINE_PACKET_LIMIT, rakOfflinePacketLimit) + .option(RakChannelOption.RAK_GLOBAL_PACKET_LIMIT, rakGlobalPacketLimit) .childHandler(serverInitializer); } @@ -352,6 +380,27 @@ public final class GeyserServer { } } + private static int positivePropOrDefault(String property, int defaultValue) { + String value = System.getProperty(property); + try { + int parsed = value != null ? Integer.parseInt(value) : defaultValue; + + if (parsed < 1) { + GeyserImpl.getInstance().getLogger().warning( + "Non-postive integer value for " + property + ": " + value + ". Using default value: " + defaultValue + ); + return defaultValue; + } + + return parsed; + } catch (NumberFormatException e) { + GeyserImpl.getInstance().getLogger().warning( + "Invalid integer value for " + property + ": " + value + ". Using default value: " + defaultValue + ); + return defaultValue; + } + } + private static Transport compatibleTransport() { TransportHelper.TransportMethod transportMethod = TransportHelper.determineTransportMethod(); if (transportMethod == TransportHelper.TransportMethod.EPOLL) { diff --git a/core/src/main/java/org/geysermc/geyser/util/FileUtils.java b/core/src/main/java/org/geysermc/geyser/util/FileUtils.java index c8cd31058..c8423c3be 100644 --- a/core/src/main/java/org/geysermc/geyser/util/FileUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/FileUtils.java @@ -27,6 +27,7 @@ package org.geysermc.geyser.util; import com.fasterxml.jackson.annotation.JsonSetter; import com.fasterxml.jackson.annotation.Nulls; +import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import org.geysermc.geyser.GeyserBootstrap; @@ -56,6 +57,8 @@ public class FileUtils { */ public static T loadConfig(File src, Class valueType) throws IOException { ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory()) + // Allow inference of single values as arrays + .enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY) .setDefaultSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY)); return objectMapper.readValue(src, valueType); } diff --git a/core/src/main/java/org/geysermc/geyser/util/WebUtils.java b/core/src/main/java/org/geysermc/geyser/util/WebUtils.java index fbcbd4a3c..f453092b3 100644 --- a/core/src/main/java/org/geysermc/geyser/util/WebUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/WebUtils.java @@ -40,6 +40,7 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.Map; +import java.util.stream.Stream; public class WebUtils { @@ -176,6 +177,13 @@ public class WebUtils { return connectionToString(con); } + /** + * Find a SRV record for the given address + * + * @param geyser Geyser instance + * @param remoteAddress Address to find the SRV record for + * @return The SRV record or null if not found + */ public static String @Nullable [] findSrvRecord(GeyserImpl geyser, String remoteAddress) { try { // Searches for a server address and a port from a SRV record of the specified host name @@ -193,4 +201,26 @@ public class WebUtils { } return null; } + + /** + * Get a stream of lines from the given URL + * + * @param reqURL URL to fetch + * @return Stream of lines from the URL or an empty stream if the request fails + */ + public static Stream getLineStream(String reqURL) { + try { + URL url = new URL(reqURL); + HttpURLConnection con = (HttpURLConnection) url.openConnection(); + con.setRequestMethod("GET"); + con.setRequestProperty("User-Agent", "Geyser-" + GeyserImpl.getInstance().getPlatformType().toString() + "/" + GeyserImpl.VERSION); // Otherwise Java 8 fails on checking updates + con.setConnectTimeout(10000); + con.setReadTimeout(10000); + + return connectionToString(con).lines(); + } catch (Exception e) { + GeyserImpl.getInstance().getLogger().error("Error while trying to get a stream from " + reqURL, e); + return Stream.empty(); + } + } } diff --git a/core/src/main/resources/config.yml b/core/src/main/resources/config.yml index 0617b316c..c70b0d7ab 100644 --- a/core/src/main/resources/config.yml +++ b/core/src/main/resources/config.yml @@ -39,8 +39,8 @@ bedrock: # A list of allowed PROXY protocol speaking proxy IP addresses/subnets. Only effective when "enable-proxy-protocol" is enabled, and # should really only be used when you are not able to use a proper firewall (usually true with shared hosting providers etc.). # Keeping this list empty means there is no IP address whitelist. - # Both IP addresses and subnets are supported. - #proxy-protocol-whitelisted-ips: [ "127.0.0.1", "172.18.0.0/16" ] + # IP addresses, subnets, and links to plain text files are supported. + #proxy-protocol-whitelisted-ips: [ "127.0.0.1", "172.18.0.0/16", "https://example.com/whitelist.txt" ] remote: # The IP address of the remote (Java Edition) server # If it is "auto", for standalone version the remote address will be set to 127.0.0.1, diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0e446a48f..b194c5a4b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,7 +11,7 @@ gson = "2.3.1" # Provided by Spigot 1.8.8 websocket = "1.5.1" protocol = "3.0.0.Beta1-20240313.120922-126" protocol-connection = "3.0.0.Beta1-20240313.120922-125" -raknet = "1.0.0.CR1-20240330.101522-15" +raknet = "1.0.0.CR1-20240330.103819-16" blockstateupdater="1.20.70-20240303.125052-2" mcauthlib = "d9d773e" mcprotocollib = "1.20.4-2-20240116.220521-7" From fa441f1c7b85da8174fc535a8efb00885b9de9ba Mon Sep 17 00:00:00 2001 From: Sage Date: Mon, 1 Apr 2024 23:33:12 +0200 Subject: [PATCH 036/272] Add ConnectionRequestEvent (#4533) * Add ConnectionRequestEvent and implement it * Add debug message and use InetSocketAddress instead of string * Provide both proxy and real client ip And add some minor javadocs * Make ProxyIp nullable * Apply changes from pr Co-authored-by: rtm516 * Apply changes from pr Co-authored-by: rtm516 * Apply changes from pr Co-authored-by: rtm516 * Bump API version * Dont JiJ common on mod platforms --------- Co-authored-by: rtm516 Co-authored-by: Kas-tle <26531652+Kas-tle@users.noreply.github.com> --- .../connection/ConnectionRequestEvent.java | 88 +++++++++++++++++++ bootstrap/mod/fabric/build.gradle.kts | 1 + bootstrap/mod/neoforge/build.gradle.kts | 1 + .../geyser/network/netty/GeyserServer.java | 9 ++ gradle.properties | 4 +- 5 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 api/src/main/java/org/geysermc/geyser/api/event/connection/ConnectionRequestEvent.java diff --git a/api/src/main/java/org/geysermc/geyser/api/event/connection/ConnectionRequestEvent.java b/api/src/main/java/org/geysermc/geyser/api/event/connection/ConnectionRequestEvent.java new file mode 100644 index 000000000..5c1f4ef51 --- /dev/null +++ b/api/src/main/java/org/geysermc/geyser/api/event/connection/ConnectionRequestEvent.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.api.event.connection; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.geysermc.event.Cancellable; +import org.geysermc.event.Event; + +import java.net.InetSocketAddress; + +/** + * Called whenever a client attempts to connect to the server, before the connection is accepted. + */ +public final class ConnectionRequestEvent implements Event, Cancellable { + + private boolean cancelled; + private final InetSocketAddress ip; + private final InetSocketAddress proxyIp; + + public ConnectionRequestEvent(@NonNull InetSocketAddress ip, @Nullable InetSocketAddress proxyIp) { + this.ip = ip; + this.proxyIp = proxyIp; + } + + /** + * The IP address of the client attempting to connect + * + * @return the IP address of the client attempting to connect + */ + @NonNull + public InetSocketAddress getInetSocketAddress() { + return ip; + } + + /** + * The IP address of the proxy handling the connection. It will return null if there is no proxy. + * + * @return the IP address of the proxy handling the connection + */ + @Nullable + public InetSocketAddress getProxyIp() { + return proxyIp; + } + + /** + * The cancel status of this event. If this event is cancelled, the connection will be rejected. + * + * @return the cancel status of this event + */ + @Override + public boolean isCancelled() { + return cancelled; + } + + /** + * Sets the cancel status of this event. If this event is canceled, the connection will be rejected. + * + * @param cancelled the cancel status of this event. + */ + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } +} diff --git a/bootstrap/mod/fabric/build.gradle.kts b/bootstrap/mod/fabric/build.gradle.kts index 538147b15..ec8ae03bc 100644 --- a/bootstrap/mod/fabric/build.gradle.kts +++ b/bootstrap/mod/fabric/build.gradle.kts @@ -41,6 +41,7 @@ dependencies { // Let's shade in our own api shadow(projects.api) { isTransitive = false } + shadow(projects.common) { isTransitive = false } // Permissions modImplementation(libs.fabric.permissions) diff --git a/bootstrap/mod/neoforge/build.gradle.kts b/bootstrap/mod/neoforge/build.gradle.kts index f7204332b..ff77bcc5c 100644 --- a/bootstrap/mod/neoforge/build.gradle.kts +++ b/bootstrap/mod/neoforge/build.gradle.kts @@ -31,6 +31,7 @@ dependencies { // Let's shade in our own api shadow(projects.api) { isTransitive = false } + shadow(projects.common) { isTransitive = false } // Include all transitive deps of core via JiJ includeTransitive(projects.core) diff --git a/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java b/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java index ce904d465..f4059a9e7 100644 --- a/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java +++ b/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java @@ -49,6 +49,7 @@ import org.cloudburstmc.netty.handler.codec.raknet.server.RakServerOfflineHandle import org.cloudburstmc.netty.handler.codec.raknet.server.RakServerRateLimiter; import org.cloudburstmc.protocol.bedrock.BedrockPong; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.api.event.connection.ConnectionRequestEvent; import org.geysermc.geyser.command.defaults.ConnectionTestCommand; import org.geysermc.geyser.configuration.GeyserConfiguration; import org.geysermc.geyser.event.type.GeyserBedrockPingEventImpl; @@ -261,6 +262,14 @@ public final class GeyserServer { } else { ip = ""; } + + ConnectionRequestEvent requestEvent = new ConnectionRequestEvent(inetSocketAddress, this.proxiedAddresses.get(inetSocketAddress)); + geyser.eventBus().fire(requestEvent); + if (requestEvent.isCancelled()) { + geyser.getLogger().debug("Connection request from " + ip + " was cancelled using the API!"); + return false; + } + geyser.getLogger().info(GeyserLocale.getLocaleStringLog("geyser.network.attempt_connect", ip)); return true; } diff --git a/gradle.properties b/gradle.properties index a8e5eaaaf..a7c0bf93d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,5 +7,5 @@ org.gradle.vfs.watch=false group=org.geysermc id=geyser -version=2.2.2-SNAPSHOT -description=Allows for players from Minecraft: Bedrock Edition to join Minecraft: Java Edition servers. \ No newline at end of file +version=2.2.3-SNAPSHOT +description=Allows for players from Minecraft: Bedrock Edition to join Minecraft: Java Edition servers. From 08aa5282d4a8e42acfaba3315e2e62c54e9efc06 Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Mon, 1 Apr 2024 15:50:58 -0700 Subject: [PATCH 037/272] Ensure proxiedAddresses is not null before lookup (#4539) --- .../java/org/geysermc/geyser/network/netty/GeyserServer.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java b/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java index f4059a9e7..db103d10e 100644 --- a/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java +++ b/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java @@ -263,7 +263,10 @@ public final class GeyserServer { ip = ""; } - ConnectionRequestEvent requestEvent = new ConnectionRequestEvent(inetSocketAddress, this.proxiedAddresses.get(inetSocketAddress)); + ConnectionRequestEvent requestEvent = new ConnectionRequestEvent( + inetSocketAddress, + this.proxiedAddresses != null ? this.proxiedAddresses.get(inetSocketAddress) : null + ); geyser.eventBus().fire(requestEvent); if (requestEvent.isCancelled()) { geyser.getLogger().debug("Connection request from " + ip + " was cancelled using the API!"); From 47237e07b789e93056a0761376c688f03b86b8ae Mon Sep 17 00:00:00 2001 From: rtm516 Date: Tue, 2 Apr 2024 00:10:12 +0100 Subject: [PATCH 038/272] Fix block custom registration failing with simmilar named items (#4540) --- .../CustomBlockRegistryPopulator.java | 32 ++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java index 36b1fc859..b2d238ddb 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java @@ -1,3 +1,28 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + package org.geysermc.geyser.registry.populator; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; @@ -80,7 +105,6 @@ public class CustomBlockRegistryPopulator { } private static Set CUSTOM_BLOCKS; - private static Set CUSTOM_BLOCK_NAMES; private static Map CUSTOM_BLOCK_ITEM_OVERRIDES; private static Map NON_VANILLA_BLOCK_STATE_OVERRIDES; private static Map BLOCK_STATE_OVERRIDES_QUEUE; @@ -90,19 +114,19 @@ public class CustomBlockRegistryPopulator { */ private static void populateBedrock() { CUSTOM_BLOCKS = new ObjectOpenHashSet<>(); - CUSTOM_BLOCK_NAMES = new ObjectOpenHashSet<>(); CUSTOM_BLOCK_ITEM_OVERRIDES = new HashMap<>(); NON_VANILLA_BLOCK_STATE_OVERRIDES = new HashMap<>(); BLOCK_STATE_OVERRIDES_QUEUE = new HashMap<>(); + Set customBlockIdentifiers = new ObjectOpenHashSet<>(); GeyserImpl.getInstance().getEventBus().fire(new GeyserDefineCustomBlocksEvent() { @Override public void register(@NonNull CustomBlockData customBlockData) { if (customBlockData.name().isEmpty()) { throw new IllegalArgumentException("Custom block name must have at least 1 character."); } - if (!CUSTOM_BLOCK_NAMES.add(customBlockData.name())) { - throw new IllegalArgumentException("Another custom block was already registered under the name: " + customBlockData.name()); + if (!customBlockIdentifiers.add(customBlockData.identifier())) { + throw new IllegalArgumentException("Another custom block was already registered under the identifier: " + customBlockData.identifier()); } if (Character.isDigit(customBlockData.name().charAt(0))) { throw new IllegalArgumentException("Custom block can not start with a digit. Name: " + customBlockData.name()); From 29bd8966820c9e0bb836de870caff457c5f5fbf6 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Tue, 2 Apr 2024 02:11:03 +0100 Subject: [PATCH 039/272] Fix CreativeCategory enum numbers (#4542) --- .../org/geysermc/geyser/api/util/CreativeCategory.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/util/CreativeCategory.java b/api/src/main/java/org/geysermc/geyser/api/util/CreativeCategory.java index 207320b1e..a3f9d069c 100644 --- a/api/src/main/java/org/geysermc/geyser/api/util/CreativeCategory.java +++ b/api/src/main/java/org/geysermc/geyser/api/util/CreativeCategory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -31,12 +31,11 @@ import org.checkerframework.checker.nullness.qual.NonNull; * Represents the creative menu categories or tabs. */ public enum CreativeCategory { - COMMANDS("commands", 1), - CONSTRUCTION("construction", 2), + CONSTRUCTION("construction", 1), + NATURE("nature", 2), EQUIPMENT("equipment", 3), ITEMS("items", 4), - NATURE("nature", 5), - NONE("none", 6); + NONE("none", 5); private final String internalName; private final int id; From 1819ed4dbdb328f559ed87361f5f7326028ed94e Mon Sep 17 00:00:00 2001 From: Eclipse <116838833+eclipseisoffline@users.noreply.github.com> Date: Thu, 4 Apr 2024 18:55:00 +0000 Subject: [PATCH 040/272] Remove Java custom armor trims when translating item to Bedrock to prevent visual issues (#4548) * Fix (or workaround) armor items with custom armor trims having no texture on bedrock * Fix armor items with custom trims causing issues on entity models by removing the Trim tag entirely * Refer to minecraft namespace inline for consistency --- .../java/org/geysermc/geyser/item/type/ArmorItem.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java index 38144f318..b58f760d1 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java @@ -47,6 +47,14 @@ public class ArmorItem extends Item { if (tag.get("Trim") instanceof CompoundTag trim) { StringTag material = trim.remove("material"); StringTag pattern = trim.remove("pattern"); + + // discard custom trim patterns/materials to prevent visual glitches on bedrock + if (!material.getValue().startsWith("minecraft:") + || !pattern.getValue().startsWith("minecraft:")) { + tag.remove("Trim"); + return; + } + // bedrock has an uppercase first letter key, and the value is not namespaced trim.put(new StringTag("Material", stripNamespace(material.getValue()))); trim.put(new StringTag("Pattern", stripNamespace(pattern.getValue()))); From 0972e4f4d7892f1387a87eb918f3137b86a590aa Mon Sep 17 00:00:00 2001 From: rtm516 Date: Fri, 5 Apr 2024 22:21:27 +0100 Subject: [PATCH 041/272] Update CreativeCategory none to have the correct value (#4549) --- .../java/org/geysermc/geyser/api/util/CreativeCategory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/util/CreativeCategory.java b/api/src/main/java/org/geysermc/geyser/api/util/CreativeCategory.java index a3f9d069c..245eb9bc2 100644 --- a/api/src/main/java/org/geysermc/geyser/api/util/CreativeCategory.java +++ b/api/src/main/java/org/geysermc/geyser/api/util/CreativeCategory.java @@ -35,7 +35,7 @@ public enum CreativeCategory { NATURE("nature", 2), EQUIPMENT("equipment", 3), ITEMS("items", 4), - NONE("none", 5); + NONE("none", 6); private final String internalName; private final int id; From 3d9f3ac64582886a85a9c5bb28e8d2a0ca6376fc Mon Sep 17 00:00:00 2001 From: Denys Loshkarev <26629861+denysloshkarev@users.noreply.github.com> Date: Sun, 7 Apr 2024 01:12:56 +0300 Subject: [PATCH 042/272] Show 1.20.73 as being supported (#4543) * update version supported by plugin * Update README.md --- README.md | 2 +- .../src/main/java/org/geysermc/geyser/network/GameProtocol.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8a28e7177..8dcbfb186 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here! -### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.72 and Minecraft Java 1.20.4 +### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.73 and Minecraft Java 1.20.4 ## Setting Up Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser. diff --git a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java index 900463c5c..d975ebbf6 100644 --- a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java +++ b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java @@ -72,7 +72,7 @@ public final class GameProtocol { .minecraftVersion("1.20.60/1.20.62") .build()); SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC.toBuilder() - .minecraftVersion("1.20.70/1.20.72") + .minecraftVersion("1.20.70/1.20.73") .build()); } From fa2e4e5a9418080cd9bd3b1ae464099928c49ffc Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sun, 7 Apr 2024 22:44:58 -0400 Subject: [PATCH 043/272] Reduce processing for incoming TrimDataPackets --- .../geysermc/geyser/network/GameProtocol.java | 32 +++++++++++++------ .../geyser/network/LoggingPacketHandler.java | 5 +++ 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java index d975ebbf6..f43706db0 100644 --- a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java +++ b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java @@ -27,13 +27,17 @@ package org.geysermc.geyser.network; import com.github.steveice10.mc.protocol.codec.MinecraftCodec; import com.github.steveice10.mc.protocol.codec.PacketCodec; +import io.netty.buffer.ByteBuf; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec; +import org.cloudburstmc.protocol.bedrock.codec.BedrockCodecHelper; +import org.cloudburstmc.protocol.bedrock.codec.v582.serializer.TrimDataSerializer_v582; import org.cloudburstmc.protocol.bedrock.codec.v622.Bedrock_v622; import org.cloudburstmc.protocol.bedrock.codec.v630.Bedrock_v630; import org.cloudburstmc.protocol.bedrock.codec.v649.Bedrock_v649; import org.cloudburstmc.protocol.bedrock.codec.v662.Bedrock_v662; import org.cloudburstmc.protocol.bedrock.netty.codec.packet.BedrockPacketCodec; +import org.cloudburstmc.protocol.bedrock.packet.TrimDataPacket; import org.geysermc.geyser.session.GeyserSession; import java.util.ArrayList; @@ -48,7 +52,7 @@ public final class GameProtocol { * Default Bedrock codec that should act as a fallback. Should represent the latest available * release of the game that Geyser supports. */ - public static final BedrockCodec DEFAULT_BEDROCK_CODEC = Bedrock_v662.CODEC; + public static final BedrockCodec DEFAULT_BEDROCK_CODEC = processCodec(Bedrock_v662.CODEC); /** * A list of all supported Bedrock versions that can join Geyser @@ -62,18 +66,18 @@ public final class GameProtocol { private static final PacketCodec DEFAULT_JAVA_CODEC = MinecraftCodec.CODEC; static { - SUPPORTED_BEDROCK_CODECS.add(Bedrock_v622.CODEC.toBuilder() + SUPPORTED_BEDROCK_CODECS.add(processCodec(Bedrock_v622.CODEC.toBuilder() .minecraftVersion("1.20.40/1.20.41") - .build()); - SUPPORTED_BEDROCK_CODECS.add(Bedrock_v630.CODEC.toBuilder() + .build())); + SUPPORTED_BEDROCK_CODECS.add(processCodec(Bedrock_v630.CODEC.toBuilder() .minecraftVersion("1.20.50/1.20.51") - .build()); - SUPPORTED_BEDROCK_CODECS.add(Bedrock_v649.CODEC.toBuilder() + .build())); + SUPPORTED_BEDROCK_CODECS.add(processCodec(Bedrock_v649.CODEC.toBuilder() .minecraftVersion("1.20.60/1.20.62") - .build()); - SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC.toBuilder() + .build())); + SUPPORTED_BEDROCK_CODECS.add(processCodec(DEFAULT_BEDROCK_CODEC.toBuilder() .minecraftVersion("1.20.70/1.20.73") - .build()); + .build())); } /** @@ -164,6 +168,16 @@ public final class GameProtocol { return joiner.toString(); } + private static BedrockCodec processCodec(BedrockCodec codec) { + return codec.toBuilder() + .updateSerializer(TrimDataPacket.class, new TrimDataSerializer_v582() { + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, TrimDataPacket packet) { + } + }) + .build(); + } + private GameProtocol() { } } diff --git a/core/src/main/java/org/geysermc/geyser/network/LoggingPacketHandler.java b/core/src/main/java/org/geysermc/geyser/network/LoggingPacketHandler.java index 0cfcc3d46..910f76ffb 100644 --- a/core/src/main/java/org/geysermc/geyser/network/LoggingPacketHandler.java +++ b/core/src/main/java/org/geysermc/geyser/network/LoggingPacketHandler.java @@ -891,4 +891,9 @@ public class LoggingPacketHandler implements BedrockPacketHandler { public PacketSignal handle(ToggleCrafterSlotRequestPacket packet) { return defaultHandler(packet); } + + @Override + public PacketSignal handle(TrimDataPacket packet) { + return defaultHandler(packet); + } } \ No newline at end of file From c91182132c78cb4575fce15260a9bf4abd4dce94 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Mon, 8 Apr 2024 10:05:48 +0100 Subject: [PATCH 044/272] Update Crowdin on README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8dcbfb186..ce2b67af1 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) [![Discord](https://img.shields.io/discord/613163671870242838.svg?color=%237289da&label=discord)](https://discord.gg/geysermc) -[![Crowdin](https://badges.crowdin.net/geyser/localized.svg)](https://translate.geysermc.org/) +[![Crowdin](https://badges.crowdin.net/e/51361b7f8a01644a238d0fe8f3bddc62/localized.svg)](https://translate.geysermc.org/) Geyser is a bridge between Minecraft: Bedrock Edition and Minecraft: Java Edition, closing the gap from those wanting to play true cross-platform. From ca0e226aac445ad8b0c213c10a3647a1874eae03 Mon Sep 17 00:00:00 2001 From: Eclipse <116838833+eclipseisoffline@users.noreply.github.com> Date: Thu, 11 Apr 2024 01:05:15 +0000 Subject: [PATCH 045/272] Fix breaking of custom head blocks added by Polymer by adding a default fallback to block mappings (#4557) --- .../bedrock/entity/player/BedrockActionTranslator.java | 4 ++-- .../protocol/java/level/JavaBlockDestructionTranslator.java | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java index 90a841ac2..33410f240 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java @@ -163,7 +163,7 @@ public class BedrockActionTranslator extends PacketTranslator Date: Fri, 12 Apr 2024 13:12:38 +0100 Subject: [PATCH 046/272] Fix user agent strings (#4562) --- .../org/geysermc/geyser/skin/SkinProvider.java | 4 ++-- .../org/geysermc/geyser/util/WebUtils.java | 18 +++++++++++------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/skin/SkinProvider.java b/core/src/main/java/org/geysermc/geyser/skin/SkinProvider.java index 12a1e8b2b..683712c22 100644 --- a/core/src/main/java/org/geysermc/geyser/skin/SkinProvider.java +++ b/core/src/main/java/org/geysermc/geyser/skin/SkinProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -674,7 +674,7 @@ public class SkinProvider { image = readFiveZigCape(imageUrl); } else { HttpURLConnection con = (HttpURLConnection) new URL(imageUrl).openConnection(); - con.setRequestProperty("User-Agent", "Geyser-" + GeyserImpl.getInstance().getPlatformType().toString() + "/" + GeyserImpl.VERSION); + con.setRequestProperty("User-Agent", WebUtils.getUserAgent()); con.setConnectTimeout(10000); con.setReadTimeout(10000); diff --git a/core/src/main/java/org/geysermc/geyser/util/WebUtils.java b/core/src/main/java/org/geysermc/geyser/util/WebUtils.java index f453092b3..1b7f2d9d9 100644 --- a/core/src/main/java/org/geysermc/geyser/util/WebUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/WebUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -55,7 +55,7 @@ public class WebUtils { URL url = new URL(reqURL); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("GET"); - con.setRequestProperty("User-Agent", "Geyser-" + GeyserImpl.getInstance().getPlatformType().toString() + "/" + GeyserImpl.VERSION); // Otherwise Java 8 fails on checking updates + con.setRequestProperty("User-Agent", getUserAgent()); // Otherwise Java 8 fails on checking updates con.setConnectTimeout(10000); con.setReadTimeout(10000); @@ -73,7 +73,7 @@ public class WebUtils { */ public static JsonNode getJson(String reqURL) throws IOException { HttpURLConnection con = (HttpURLConnection) new URL(reqURL).openConnection(); - con.setRequestProperty("User-Agent", "Geyser-" + GeyserImpl.getInstance().getPlatformType().toString() + "/" + GeyserImpl.VERSION); + con.setRequestProperty("User-Agent", getUserAgent()); con.setConnectTimeout(10000); con.setReadTimeout(10000); return GeyserImpl.JSON_MAPPER.readTree(con.getInputStream()); @@ -88,7 +88,7 @@ public class WebUtils { public static void downloadFile(String reqURL, String fileLocation) { try { HttpURLConnection con = (HttpURLConnection) new URL(reqURL).openConnection(); - con.setRequestProperty("User-Agent", "Geyser-" + GeyserImpl.getInstance().getPlatformType().toString() + "/" + GeyserImpl.VERSION); + con.setRequestProperty("User-Agent", getUserAgent()); InputStream in = con.getInputStream(); Files.copy(in, Paths.get(fileLocation), StandardCopyOption.REPLACE_EXISTING); } catch (Exception e) { @@ -109,7 +109,7 @@ public class WebUtils { HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("POST"); con.setRequestProperty("Content-Type", "text/plain"); - con.setRequestProperty("User-Agent", "Geyser-" + GeyserImpl.getInstance().getPlatformType().toString() + "/" + GeyserImpl.VERSION); + con.setRequestProperty("User-Agent", getUserAgent()); con.setDoOutput(true); OutputStream out = con.getOutputStream(); @@ -164,7 +164,7 @@ public class WebUtils { HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("POST"); con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); - con.setRequestProperty("User-Agent", "Geyser-" + GeyserImpl.getInstance().getPlatformType().toString() + "/" + GeyserImpl.VERSION); + con.setRequestProperty("User-Agent", getUserAgent()); con.setDoOutput(true); try (OutputStream out = con.getOutputStream()) { @@ -213,7 +213,7 @@ public class WebUtils { URL url = new URL(reqURL); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("GET"); - con.setRequestProperty("User-Agent", "Geyser-" + GeyserImpl.getInstance().getPlatformType().toString() + "/" + GeyserImpl.VERSION); // Otherwise Java 8 fails on checking updates + con.setRequestProperty("User-Agent", getUserAgent()); // Otherwise Java 8 fails on checking updates con.setConnectTimeout(10000); con.setReadTimeout(10000); @@ -223,4 +223,8 @@ public class WebUtils { return Stream.empty(); } } + + public static String getUserAgent() { + return "Geyser-" + GeyserImpl.getInstance().getPlatformType().platformName() + "/" + GeyserImpl.VERSION; + } } From a24f68412315fdabe93053d7722f9c9f15fc6511 Mon Sep 17 00:00:00 2001 From: chris Date: Sun, 14 Apr 2024 00:16:26 +0200 Subject: [PATCH 047/272] Update to Gradle 8.7, bump loom to 1.6 (#4565) * Update to Gradle 8.6, bump loom to 1.6 * update to gradle 8.7 --- bootstrap/mod/fabric/build.gradle.kts | 11 +------ gradle/libs.versions.toml | 2 +- gradle/wrapper/gradle-wrapper.jar | Bin 60756 -> 43462 bytes gradle/wrapper/gradle-wrapper.properties | 4 ++- gradlew | 35 ++++++++++++++--------- gradlew.bat | 21 +++++++------- 6 files changed, 38 insertions(+), 35 deletions(-) diff --git a/bootstrap/mod/fabric/build.gradle.kts b/bootstrap/mod/fabric/build.gradle.kts index ec8ae03bc..53e4dfe53 100644 --- a/bootstrap/mod/fabric/build.gradle.kts +++ b/bootstrap/mod/fabric/build.gradle.kts @@ -22,16 +22,11 @@ dependencies { // These are NOT transitively included, and instead shadowed + relocated. // Avoids fabric complaining about non-SemVer versioning - // TODO: re-evaluate after loom 1.6 (https://github.com/FabricMC/fabric-loom/pull/1075) shadow(libs.protocol.connection) { isTransitive = false } shadow(libs.protocol.common) { isTransitive = false } shadow(libs.protocol.codec) { isTransitive = false } shadow(libs.mcauthlib) { isTransitive = false } shadow(libs.raknet) { isTransitive = false } - shadow(libs.netty.codec.haproxy) { isTransitive = false } - shadow("org.cloudburstmc:nbt:3.0.2.Final") { isTransitive = false } - shadow("io.netty:netty-codec-dns:4.1.103.Final") { isTransitive = false } - shadow("io.netty:netty-resolver-dns-classes-macos:4.1.103.Final") { isTransitive = false } // Consequences of shading + relocating mcauthlib: shadow/relocate mcpl! shadow(libs.mcprotocollib) { isTransitive = false } @@ -39,7 +34,7 @@ dependencies { // Since we also relocate cloudburst protocol: shade erosion common shadow(libs.erosion.common) { isTransitive = false } - // Let's shade in our own api + // Let's shade in our own api/common module shadow(projects.api) { isTransitive = false } shadow(projects.common) { isTransitive = false } @@ -52,12 +47,8 @@ application { mainClass.set("org.geysermc.geyser.platform.fabric.GeyserFabricMain") } -relocate("org.cloudburstmc.nbt") relocate("org.cloudburstmc.netty") relocate("org.cloudburstmc.protocol") -relocate("io.netty.handler.codec.dns") -relocate("io.netty.handler.codec.haproxy") -relocate("io.netty.resolver.dns.macos") relocate("com.github.steveice10.mc.protocol") relocate("com.github.steveice10.mc.auth") relocate("com.github.steveice10.packetlib") diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b194c5a4b..04c83ac78 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -40,7 +40,7 @@ mixin = "0.8.5" indra = "3.1.3" shadow = "8.1.1" architectury-plugin = "3.4-SNAPSHOT" -architectury-loom = "1.4-SNAPSHOT" +architectury-loom = "1.6-SNAPSHOT" minotaur = "2.8.7" lombok = "8.4" blossom = "1.2.0" diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 249e5832f090a2944b7473328c07c9755baa3196..d64cd4917707c1f8861d8cb53dd15194d4248596 100644 GIT binary patch literal 43462 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 literal 60756 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 /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,22 +131,29 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -193,11 +198,15 @@ if "$cygwin" || "$msys" ; then done fi -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/gradlew.bat b/gradlew.bat index f127cfd49..25da30dbd 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -26,6 +26,7 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -42,11 +43,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -56,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail From 5151c25e1a28a9096a411711a9e6ae57b8314654 Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Tue, 16 Apr 2024 20:52:46 -0700 Subject: [PATCH 048/272] Support RakNet Cookies (#4554) * Support cookies Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Use cloudburst upstream raknet * Comment out mavenLocal() --------- Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> --- .../kotlin/geyser.modded-conventions.gradle.kts | 1 + core/build.gradle.kts | 4 ++++ .../java/org/geysermc/geyser/dump/DumpInfo.java | 3 +++ .../geyser/network/netty/GeyserServer.java | 17 +++++++++-------- gradle/libs.versions.toml | 2 +- settings.gradle.kts | 3 ++- 6 files changed, 20 insertions(+), 10 deletions(-) diff --git a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts index 91bde525e..e011b7139 100644 --- a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts @@ -107,6 +107,7 @@ dependencies { } repositories { + // mavenLocal() maven("https://repo.opencollab.dev/maven-releases/") maven("https://repo.opencollab.dev/maven-snapshots/") maven("https://jitpack.io") diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 054f4f0ae..93c9f4f13 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -6,6 +6,10 @@ plugins { } dependencies { + constraints { + implementation(libs.raknet) // Ensure protocol does not override the RakNet version + } + api(projects.common) api(projects.api) diff --git a/core/src/main/java/org/geysermc/geyser/dump/DumpInfo.java b/core/src/main/java/org/geysermc/geyser/dump/DumpInfo.java index 818607314..e54bbc1eb 100644 --- a/core/src/main/java/org/geysermc/geyser/dump/DumpInfo.java +++ b/core/src/main/java/org/geysermc/geyser/dump/DumpInfo.java @@ -78,6 +78,7 @@ public class DumpInfo { private final GeyserConfiguration config; private final Floodgate floodgate; private final Object2IntMap userPlatforms; + private final int connectionAttempts; private final HashInfo hashInfo; private final RamInfo ramInfo; private LogsInfo logsInfo; @@ -129,6 +130,8 @@ public class DumpInfo { userPlatforms.put(device, userPlatforms.getOrDefault(device, 0) + 1); } + this.connectionAttempts = GeyserImpl.getInstance().getGeyserServer().getConnectionAttempts(); + this.bootstrapInfo = GeyserImpl.getInstance().getBootstrap().getDumpInfo(); this.flagsInfo = new FlagsInfo(); diff --git a/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java b/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java index db103d10e..8ead16623 100644 --- a/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java +++ b/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java @@ -74,7 +74,6 @@ import java.util.function.IntFunction; import java.util.function.Supplier; import static org.cloudburstmc.netty.channel.raknet.RakConstants.DEFAULT_GLOBAL_PACKET_LIMIT; -import static org.cloudburstmc.netty.channel.raknet.RakConstants.DEFAULT_OFFLINE_PACKET_LIMIT; import static org.cloudburstmc.netty.channel.raknet.RakConstants.DEFAULT_PACKET_LIMIT; public final class GeyserServer { @@ -111,6 +110,10 @@ public final class GeyserServer { private ChannelFuture[] bootstrapFutures; + // Keep track of connection attempts for dump info + @Getter + private int connectionAttempts = 0; + /** * The port to broadcast in the pong. This can be different from the port the server is bound to, e.g. due to port forwarding. */ @@ -217,11 +220,6 @@ public final class GeyserServer { int rakPacketLimit = positivePropOrDefault("Geyser.RakPacketLimit", DEFAULT_PACKET_LIMIT); this.geyser.getLogger().debug("Setting RakNet packet limit to " + rakPacketLimit); - boolean isWhitelistedProxyProtocol = this.geyser.getConfig().getBedrock().isEnableProxyProtocol() - && !this.geyser.getConfig().getBedrock().getProxyProtocolWhitelistedIPs().isEmpty(); - int rakOfflinePacketLimit = positivePropOrDefault("Geyser.RakOfflinePacketLimit", isWhitelistedProxyProtocol ? Integer.MAX_VALUE : DEFAULT_OFFLINE_PACKET_LIMIT); - this.geyser.getLogger().debug("Setting RakNet offline packet limit to " + rakOfflinePacketLimit); - int rakGlobalPacketLimit = positivePropOrDefault("Geyser.RakGlobalPacketLimit", DEFAULT_GLOBAL_PACKET_LIMIT); this.geyser.getLogger().debug("Setting RakNet global packet limit to " + rakGlobalPacketLimit); @@ -231,8 +229,8 @@ public final class GeyserServer { .option(RakChannelOption.RAK_HANDLE_PING, true) .option(RakChannelOption.RAK_MAX_MTU, this.geyser.getConfig().getMtu()) .option(RakChannelOption.RAK_PACKET_LIMIT, rakPacketLimit) - .option(RakChannelOption.RAK_OFFLINE_PACKET_LIMIT, rakOfflinePacketLimit) .option(RakChannelOption.RAK_GLOBAL_PACKET_LIMIT, rakGlobalPacketLimit) + .option(RakChannelOption.RAK_SEND_COOKIE, true) .childHandler(serverInitializer); } @@ -248,6 +246,7 @@ public final class GeyserServer { } if (!isWhitelistedIP) { + connectionAttempts++; return false; } } @@ -270,10 +269,12 @@ public final class GeyserServer { geyser.eventBus().fire(requestEvent); if (requestEvent.isCancelled()) { geyser.getLogger().debug("Connection request from " + ip + " was cancelled using the API!"); + connectionAttempts++; return false; } - geyser.getLogger().info(GeyserLocale.getLocaleStringLog("geyser.network.attempt_connect", ip)); + geyser.getLogger().debug(GeyserLocale.getLocaleStringLog("geyser.network.attempt_connect", ip)); + connectionAttempts++; return true; } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 04c83ac78..3111750a8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,7 +11,7 @@ gson = "2.3.1" # Provided by Spigot 1.8.8 websocket = "1.5.1" protocol = "3.0.0.Beta1-20240313.120922-126" protocol-connection = "3.0.0.Beta1-20240313.120922-125" -raknet = "1.0.0.CR1-20240330.103819-16" +raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.70-20240303.125052-2" mcauthlib = "d9d773e" mcprotocollib = "1.20.4-2-20240116.220521-7" diff --git a/settings.gradle.kts b/settings.gradle.kts index 68848bca4..a39bfa3d2 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -4,6 +4,8 @@ enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") dependencyResolutionManagement { repositories { + // mavenLocal() + // Floodgate, Cumulus etc. maven("https://repo.opencollab.dev/main") @@ -30,7 +32,6 @@ dependencyResolutionManagement { mavenContent { releasesOnly() } } - mavenLocal() mavenCentral() // ViaVersion From c8475d8100f6272a9c892ac81635f720c4d0ee58 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Wed, 17 Apr 2024 03:18:17 -0400 Subject: [PATCH 049/272] Always remove entities from cache (#4577) * Always remove entities from cache * Despawn throwable entities in the void --- .../geysermc/geyser/entity/type/Entity.java | 7 ++----- .../geyser/entity/type/FireballEntity.java | 3 +++ .../geyser/entity/type/FishingHookEntity.java | 3 +++ .../geyser/entity/type/ItemEntity.java | 2 +- .../geyser/entity/type/ItemFrameEntity.java | 3 +-- .../geyser/entity/type/ThrowableEntity.java | 20 +++++++++++++++++-- .../entity/type/living/ArmorStandEntity.java | 4 ++-- .../living/monster/EnderDragonEntity.java | 4 ++-- .../geyser/session/cache/EntityCache.java | 12 ++++++----- .../entity/JavaRemoveEntitiesTranslator.java | 2 +- 10 files changed, 40 insertions(+), 20 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java index a2b7cc6ec..306c244b3 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java @@ -200,11 +200,9 @@ public class Entity implements GeyserEntity { /** * Despawns the entity - * - * @return can be deleted */ - public boolean despawnEntity() { - if (!valid) return true; + public void despawnEntity() { + if (!valid) return; for (Entity passenger : passengers) { // Make sure all passengers on the despawned entity are updated if (passenger == null) continue; @@ -218,7 +216,6 @@ public class Entity implements GeyserEntity { session.sendUpstreamPacket(removeEntityPacket); valid = false; - return true; } public void moveRelative(double relX, double relY, double relZ, float yaw, float pitch, boolean isOnGround) { diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/FireballEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/FireballEntity.java index 3db032f0f..904596b3a 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/FireballEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/FireballEntity.java @@ -72,6 +72,9 @@ public class FireballEntity extends ThrowableEntity { @Override public void tick() { + if (removedInVoid()) { + return; + } moveAbsoluteImmediate(tickMovement(position), getYaw(), getPitch(), getHeadYaw(), false, false); } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java index bcbff16ce..0de11c382 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java @@ -133,6 +133,9 @@ public class FishingHookEntity extends ThrowableEntity { @Override public void tick() { + if (removedInVoid()) { + return; + } if (hooked || !isInAir() && !isInWater() || isOnGround()) { motion = Vector3f.ZERO; return; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java index bb67a60f6..69fb3faab 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java @@ -74,7 +74,7 @@ public class ItemEntity extends ThrowableEntity { @Override public void tick() { - if (isInWater()) { + if (removedInVoid() || isInWater()) { return; } if (!isOnGround() || (motion.getX() * motion.getX() + motion.getZ() * motion.getZ()) > 0.00001) { diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java index 295972200..ad1d4b928 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java @@ -148,7 +148,7 @@ public class ItemFrameEntity extends Entity { } @Override - public boolean despawnEntity() { + public void despawnEntity() { UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); updateBlockPacket.setDataLayer(0); updateBlockPacket.setBlockPosition(bedrockPosition); @@ -161,7 +161,6 @@ public class ItemFrameEntity extends Entity { session.getItemFrameCache().remove(bedrockPosition, this); valid = false; - return true; } private NbtMap getDefaultTag() { diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEntity.java index 60840e65b..47884e60a 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEntity.java @@ -55,6 +55,9 @@ public class ThrowableEntity extends Entity implements Tickable { */ @Override public void tick() { + if (removedInVoid()) { + return; + } moveAbsoluteImmediate(position.add(motion), getYaw(), getPitch(), getHeadYaw(), isOnGround(), false); float drag = getDrag(); float gravity = getGravity(); @@ -170,14 +173,14 @@ public class ThrowableEntity extends Entity implements Tickable { } @Override - public boolean despawnEntity() { + public void despawnEntity() { if (definition.entityType() == EntityType.ENDER_PEARL) { LevelEventPacket particlePacket = new LevelEventPacket(); particlePacket.setType(LevelEvent.PARTICLE_TELEPORT); particlePacket.setPosition(position); session.sendUpstreamPacket(particlePacket); } - return super.despawnEntity(); + super.despawnEntity(); } @Override @@ -191,4 +194,17 @@ public class ThrowableEntity extends Entity implements Tickable { moveAbsoluteImmediate(position, yaw, pitch, headYaw, isOnGround, teleported); lastJavaPosition = position; } + + /** + * Removes the entity if it is 64 blocks below the world. + * + * @return true if the entity was removed + */ + public boolean removedInVoid() { + if (position.getY() < session.getDimensionType().minY() - 64) { + session.getEntityCache().removeEntity(this); + return true; + } + return false; + } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java index c64776f18..9c56568c8 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java @@ -99,11 +99,11 @@ public class ArmorStandEntity extends LivingEntity { } @Override - public boolean despawnEntity() { + public void despawnEntity() { if (secondEntity != null) { secondEntity.despawnEntity(); } - return super.despawnEntity(); + super.despawnEntity(); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonEntity.java index bb09a23f4..8c00d065a 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonEntity.java @@ -148,11 +148,11 @@ public class EnderDragonEntity extends MobEntity implements Tickable { } @Override - public boolean despawnEntity() { + public void despawnEntity() { for (EnderDragonPartEntity part : allParts) { part.despawnEntity(); } - return super.despawnEntity(); + super.despawnEntity(); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/EntityCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/EntityCache.java index 8a4b9cb6c..6524e1ddc 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/EntityCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/EntityCache.java @@ -85,27 +85,29 @@ public class EntityCache { return false; } - public boolean removeEntity(Entity entity, boolean force) { + public void removeEntity(Entity entity) { if (entity instanceof PlayerEntity player) { session.getPlayerWithCustomHeads().remove(player.getUuid()); } - if (entity != null && entity.isValid() && (force || entity.despawnEntity())) { + if (entity != null) { + if (entity.isValid()) { + entity.despawnEntity(); + } + long geyserId = entityIdTranslations.remove(entity.getEntityId()); entities.remove(geyserId); if (entity instanceof Tickable) { tickableEntities.remove(entity); } - return true; } - return false; } public void removeAllEntities() { List entities = new ArrayList<>(this.entities.values()); for (Entity entity : entities) { - removeEntity(entity, false); + removeEntity(entity); } session.getPlayerWithCustomHeads().clear(); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRemoveEntitiesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRemoveEntitiesTranslator.java index 65229f29d..776cfb4d7 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRemoveEntitiesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRemoveEntitiesTranslator.java @@ -39,7 +39,7 @@ public class JavaRemoveEntitiesTranslator extends PacketTranslator Date: Wed, 17 Apr 2024 23:21:25 +0200 Subject: [PATCH 050/272] Feature: Structure block translation (#4521) * ported camotoy's attempt of implementing structure blocks, removal of a few TODO's * no more parsing of java structure templates * Don't attempt to re-request structure size * ensure we can load structures in even if we know the size * init: send correct structure size/offset/rotation to java, not fully working yet * restore offsets so we are sending correct values to the java server regarding where we want the structure to be placed * something something mirror * attempt at proper offsets for mirroring AND rotations. this was not fun at all * rotation, mirror, offsetting all seem to work * undo import changes * fix NPE * Proper handling of empty structures, ensure that we can clear the structure block outline when a zero vector was sent for structure size * oops * Update core/src/main/java/org/geysermc/geyser/session/cache/StructureBlockCache.java Co-authored-by: rtm516 * Update core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java Co-authored-by: rtm516 * Update core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureBlockUpdateTranslator.java Co-authored-by: rtm516 * Update core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureTemplateDataRequestTranslator.java Co-authored-by: rtm516 * consolidate java structure sending into one method * fix merge conflict --------- Co-authored-by: rtm516 --- README.md | 1 - .../populator/BlockRegistryPopulator.java | 16 +- .../geyser/registry/type/BlockMappings.java | 5 + .../geyser/session/GeyserSession.java | 2 + .../session/cache/StructureBlockCache.java | 59 +++++++ .../StructureBlockBlockEntityTranslator.java | 138 +++++++++++++++ ...BedrockInventoryTransactionTranslator.java | 7 + ...BedrockStructureBlockUpdateTranslator.java | 65 +++++++ ...tructureTemplateDataRequestTranslator.java | 91 ++++++++++ .../level/JavaBlockEntityDataTranslator.java | 59 +++++++ .../geysermc/geyser/util/InventoryUtils.java | 2 +- .../geyser/util/StructureBlockUtils.java | 164 ++++++++++++++++++ 12 files changed, 606 insertions(+), 3 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/session/cache/StructureBlockCache.java create mode 100644 core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java create mode 100644 core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureBlockUpdateTranslator.java create mode 100644 core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureTemplateDataRequestTranslator.java create mode 100644 core/src/main/java/org/geysermc/geyser/util/StructureBlockUtils.java diff --git a/README.md b/README.md index ce2b67af1..0aa9d009a 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,6 @@ Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Ge ## What's Left to be Added/Fixed - Near-perfect movement (to the point where anticheat on large servers is unlikely to ban you) - Some Entity Flags -- Structure block UI ## What can't be fixed There are a few things Geyser is unable to support due to various differences between Minecraft Bedrock and Java. For a list of these limitations, see the [Current Limitations](https://wiki.geysermc.org/geyser/current-limitations/) page. diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java index 4c52a1530..c54431fbe 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java @@ -144,7 +144,7 @@ public final class BlockRegistryPopulator { builder.remove("version"); // Remove all nbt tags which are not needed for differentiating states builder.remove("name_hash"); // Quick workaround - was added in 1.19.20 builder.remove("network_id"); // Added in 1.19.80 - ???? - builder.remove("block_id"); // Added in 1.20.60 //TODO verify this can be just removed + builder.remove("block_id"); // Added in 1.20.60 //noinspection UnstableApiUsage builder.putCompound("states", statesInterner.intern((NbtMap) builder.remove("states"))); vanillaBlockStates.set(i, builder.build()); @@ -229,6 +229,7 @@ public final class BlockRegistryPopulator { Map itemFrames = new Object2ObjectOpenHashMap<>(); Set jigsawDefinitions = new ObjectOpenHashSet<>(); + Map structureBlockDefinitions = new Object2ObjectOpenHashMap<>(); BlockMappings.BlockMappingsBuilder builder = BlockMappings.builder(); while (blocksIterator.hasNext()) { @@ -272,6 +273,18 @@ public final class BlockRegistryPopulator { jigsawDefinitions.add(bedrockDefinition); } + if (javaId.contains("structure_block")) { + int modeIndex = javaId.indexOf("mode="); + if (modeIndex != -1) { + int startIndex = modeIndex + 5; // Length of "mode=" is 5 + int endIndex = javaId.indexOf("]", startIndex); + if (endIndex != -1) { + String modeValue = javaId.substring(startIndex, endIndex); + structureBlockDefinitions.put(modeValue.toUpperCase(), bedrockDefinition); + } + } + } + boolean waterlogged = entry.getKey().contains("waterlogged=true") || javaId.contains("minecraft:bubble_column") || javaId.contains("minecraft:kelp") || javaId.contains("seagrass"); @@ -358,6 +371,7 @@ public final class BlockRegistryPopulator { .itemFrames(itemFrames) .flowerPotBlocks(flowerPotBlocks) .jigsawStates(jigsawDefinitions) + .structureBlockStates(structureBlockDefinitions) .remappedVanillaIds(remappedVanillaIds) .blockProperties(customBlockProperties) .customBlockStateDefinitions(customBlockStateDefinitions) diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java b/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java index 8c0414a6d..c76f024af 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java +++ b/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java @@ -61,6 +61,7 @@ public class BlockMappings implements DefinitionRegistry { Map flowerPotBlocks; Set jigsawStates; + Map structureBlockStates; List blockProperties; Object2ObjectMap customBlockStateDefinitions; @@ -96,6 +97,10 @@ public class BlockMappings implements DefinitionRegistry { return false; } + public BlockDefinition getStructureBlockFromMode(String mode) { + return structureBlockStates.get(mode); + } + @Override public @Nullable GeyserBedrockBlock getDefinition(int bedrockId) { if (bedrockId < 0 || bedrockId >= this.bedrockRuntimeMap.length) { diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 7a4a8ff6f..c0749400a 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -214,6 +214,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { private final PistonCache pistonCache; private final PreferencesCache preferencesCache; private final SkullCache skullCache; + private final StructureBlockCache structureBlockCache; private final TagCache tagCache; private final WorldCache worldCache; @@ -625,6 +626,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { this.pistonCache = new PistonCache(this); this.preferencesCache = new PreferencesCache(this); this.skullCache = new SkullCache(this); + this.structureBlockCache = new StructureBlockCache(); this.tagCache = new TagCache(); this.worldCache = new WorldCache(this); this.cameraData = new GeyserCameraData(this); diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/StructureBlockCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/StructureBlockCache.java new file mode 100644 index 000000000..170f80d0a --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/session/cache/StructureBlockCache.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.session.cache; + +import lombok.Getter; +import lombok.Setter; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.cloudburstmc.math.vector.Vector3i; + +@Setter +@Getter +public final class StructureBlockCache { + + /** + * Stores the current structure's name to be able to detect changes in the loaded structure + */ + private @Nullable String currentStructureName; + + /** + * Stores the offset changes added by Geyser that ensure that structure bounds + * are the same for Java and Bedrock + */ + private @Nullable Vector3i bedrockOffset; + + /** + * Stores the current structure block position while we're waiting on the Java + * server to send the data we need. + */ + private @Nullable Vector3i currentStructureBlock; + + public void clear() { + this.currentStructureName = null; + this.currentStructureBlock = null; + this.bedrockOffset = null; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java new file mode 100644 index 000000000..a24d010b7 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.translator.level.block.entity; + +import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import org.cloudburstmc.math.vector.Vector3i; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.protocol.bedrock.data.structure.StructureMirror; +import org.cloudburstmc.protocol.bedrock.data.structure.StructureRotation; +import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.util.StructureBlockUtils; + +@BlockEntity(type = BlockEntityType.STRUCTURE_BLOCK) +public class StructureBlockBlockEntityTranslator extends BlockEntityTranslator { + + @Override + public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, CompoundTag tag, int blockState) { + // Sending a structure with size 0 doesn't clear the outline. Hence, we have to force it by replacing the block :/ + int xStructureSize = getOrDefault(tag.get("sizeX"), 0); + int yStructureSize = getOrDefault(tag.get("sizeY"), 0); + int zStructureSize = getOrDefault(tag.get("sizeZ"), 0); + + Vector3i size = Vector3i.from(xStructureSize, yStructureSize, zStructureSize); + + if (size.equals(Vector3i.ZERO)) { + Vector3i position = Vector3i.from(x, y, z); + String mode = getOrDefault(tag.get("mode"), ""); + + // Set to air and back to reset the structure block + UpdateBlockPacket emptyBlockPacket = new UpdateBlockPacket(); + emptyBlockPacket.setDataLayer(0); + emptyBlockPacket.setBlockPosition(position); + emptyBlockPacket.setDefinition(session.getBlockMappings().getBedrockAir()); + session.sendUpstreamPacket(emptyBlockPacket); + + UpdateBlockPacket spawnerBlockPacket = new UpdateBlockPacket(); + spawnerBlockPacket.setDataLayer(0); + spawnerBlockPacket.setBlockPosition(position); + spawnerBlockPacket.setDefinition(session.getBlockMappings().getStructureBlockFromMode(mode)); + session.sendUpstreamPacket(spawnerBlockPacket); + } + + return super.getBlockEntityTag(session, type, x, y, z, tag, blockState); + } + + @Override + public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { + if (tag.size() < 5) { + return; // These values aren't here + } + + builder.putString("structureName", getOrDefault(tag.get("name"), "")); + + String mode = getOrDefault(tag.get("mode"), ""); + int bedrockData = switch (mode) { + case "LOAD" -> 2; + case "CORNER" -> 3; + case "DATA" -> 4; + default -> 1; // SAVE + }; + + builder.putInt("data", bedrockData); + builder.putString("dataField", ""); // ??? possibly related to Java's "metadata" + + // Mirror behaves different in Java and Bedrock - it requires modifying the position in space as well + String mirror = getOrDefault(tag.get("mirror"), ""); + StructureMirror bedrockMirror = switch (mirror) { + case "FRONT_BACK" -> StructureMirror.X; + case "LEFT_RIGHT" -> StructureMirror.Z; + default -> StructureMirror.NONE; + }; + builder.putByte("mirror", (byte) bedrockMirror.ordinal()); + + builder.putByte("ignoreEntities", getOrDefault(tag.get("ignoreEntities"), (byte) 0)); + builder.putByte("isPowered", getOrDefault(tag.get("powered"), (byte) 0)); + builder.putLong("seed", getOrDefault(tag.get("seed"), 0L)); + builder.putByte("showBoundingBox", getOrDefault(tag.get("showboundingbox"), (byte) 0)); + + String rotation = getOrDefault(tag.get("rotation"), ""); + StructureRotation bedrockRotation = switch (rotation) { + case "CLOCKWISE_90" -> StructureRotation.ROTATE_90; + case "CLOCKWISE_180" -> StructureRotation.ROTATE_180; + case "COUNTERCLOCKWISE_90" -> StructureRotation.ROTATE_270; + default -> StructureRotation.NONE; + }; + builder.putByte("rotation", (byte) bedrockRotation.ordinal()); + + int xStructureSize = getOrDefault(tag.get("sizeX"), 0); + int yStructureSize = getOrDefault(tag.get("sizeY"), 0); + int zStructureSize = getOrDefault(tag.get("sizeZ"), 0); + + // The "positions" are also offsets on Java + int posX = getOrDefault(tag.get("posX"), 0); + int posY = getOrDefault(tag.get("posY"), 0); + int posZ = getOrDefault(tag.get("posZ"), 0); + + Vector3i offset = StructureBlockUtils.calculateOffset(bedrockRotation, bedrockMirror, + xStructureSize, zStructureSize); + + builder.putInt("xStructureOffset", posX + offset.getX()); + builder.putInt("yStructureOffset", posY); + builder.putInt("zStructureOffset", posZ + offset.getZ()); + + builder.putInt("xStructureSize", xStructureSize); + builder.putInt("yStructureSize", yStructureSize); + builder.putInt("zStructureSize", zStructureSize); + + builder.putFloat("integrity", getOrDefault(tag.get("integrity"), 0f)); // Is 1.0f by default on Java but 100.0f on Bedrock + + // Java's "showair" is unrepresented + } +} \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java index 101035cb5..4ac835268 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java @@ -348,6 +348,13 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator { + + @Override + public void translate(GeyserSession session, StructureBlockUpdatePacket packet) { + StructureEditorData data = packet.getEditorData(); + + UpdateStructureBlockAction action = UpdateStructureBlockAction.UPDATE_DATA; + if (packet.isPowered()) { + if (data.getType() == StructureBlockType.LOAD) { + action = UpdateStructureBlockAction.LOAD_STRUCTURE; + } else if (data.getType() == StructureBlockType.SAVE) { + action = UpdateStructureBlockAction.SAVE_STRUCTURE; + } + } + + UpdateStructureBlockMode mode = switch (data.getType()) { + case CORNER -> UpdateStructureBlockMode.CORNER; + case DATA -> UpdateStructureBlockMode.DATA; + case LOAD -> UpdateStructureBlockMode.LOAD; + default -> UpdateStructureBlockMode.SAVE; + }; + + StructureBlockUtils.sendJavaStructurePacket(session, packet.getBlockPosition(), data.getSettings().getSize(), mode, action, data.getSettings(), + data.isBoundingBoxVisible(), data.getName()); + session.getStructureBlockCache().clear(); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureTemplateDataRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureTemplateDataRequestTranslator.java new file mode 100644 index 000000000..947946f36 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureTemplateDataRequestTranslator.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.translator.protocol.bedrock; + +import com.github.steveice10.mc.protocol.data.game.inventory.UpdateStructureBlockAction; +import com.github.steveice10.mc.protocol.data.game.inventory.UpdateStructureBlockMode; +import org.cloudburstmc.math.vector.Vector3i; +import org.cloudburstmc.protocol.bedrock.data.structure.StructureSettings; +import org.cloudburstmc.protocol.bedrock.data.structure.StructureTemplateRequestOperation; +import org.cloudburstmc.protocol.bedrock.packet.StructureTemplateDataRequestPacket; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.protocol.PacketTranslator; +import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.geyser.util.StructureBlockUtils; + +/** + * Packet used in Bedrock to load structure size into the structure block GUI. It is sent every time the GUI is opened. + * Or, if the player updates the structure name. Which we can use to request the structure size from the Java server! + *

+ * Java does not have this preview, instead, Java clients are forced out of the GUI to look at the area. + */ +@Translator(packet = StructureTemplateDataRequestPacket.class) +public class BedrockStructureTemplateDataRequestTranslator extends PacketTranslator { + + @Override + public void translate(GeyserSession session, StructureTemplateDataRequestPacket packet) { + // All other operation types are ignored by Geyser since we do not support exporting/importing structures + if (packet.getOperation().equals(StructureTemplateRequestOperation.QUERY_SAVED_STRUCTURE)) { + Vector3i size = packet.getSettings().getSize(); + StructureSettings settings = packet.getSettings(); + + // If we send a load packet to the Java server when the structure size is known, it would place the structure. + String currentStructureName = session.getStructureBlockCache().getCurrentStructureName(); + + // Case 1: Opening a structure block with information about structure size, but not yet saved by us + // Case 2: Getting an update from Bedrock with new information, doesn't bother us if it's the same structure + if (!packet.getSettings().getSize().equals(Vector3i.ZERO)) { + if (currentStructureName == null) { + Vector3i offset = StructureBlockUtils.calculateOffset(settings.getRotation(), settings.getMirror(), + settings.getSize().getX(), settings.getSize().getZ()); + session.getStructureBlockCache().setBedrockOffset(offset); + session.getStructureBlockCache().setCurrentStructureName(packet.getName()); + StructureBlockUtils.sendStructureData(session, size, packet.getName()); + return; + } else if (packet.getName().equals(currentStructureName)) { + StructureBlockUtils.sendStructureData(session, size, packet.getName()); + return; + } + } + + // Request a "structure load" from Java server, so it sends us the structure's size + // See the block entity translator for more info + session.getStructureBlockCache().setCurrentStructureBlock(packet.getPosition()); + + StructureBlockUtils.sendJavaStructurePacket(session, + packet.getPosition(), + Vector3i.ZERO, // We expect the Java server to tell us the size + UpdateStructureBlockMode.LOAD, + UpdateStructureBlockAction.LOAD_STRUCTURE, + settings, + true, + packet.getName() + ); + } else { + StructureBlockUtils.sendEmptyStructureData(session); + } + } +} \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java index c67a6dee4..325bae593 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java @@ -28,9 +28,13 @@ package org.geysermc.geyser.translator.protocol.java.level; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundBlockEntityDataPacket; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; +import org.cloudburstmc.protocol.bedrock.data.structure.StructureMirror; +import org.cloudburstmc.protocol.bedrock.data.structure.StructureRotation; import org.cloudburstmc.protocol.bedrock.packet.ContainerOpenPacket; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; import org.geysermc.geyser.level.block.BlockStateValues; @@ -41,6 +45,7 @@ import org.geysermc.geyser.translator.level.block.entity.SkullBlockEntityTransla import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.BlockEntityUtils; +import org.geysermc.geyser.util.StructureBlockUtils; @Translator(packet = ClientboundBlockEntityDataPacket.class) public class JavaBlockEntityDataTranslator extends PacketTranslator { @@ -95,5 +100,59 @@ public class JavaBlockEntityDataTranslator extends PacketTranslator 5 + ) { + CompoundTag map = packet.getNbt(); + + String mode = getOrDefault(map.get("mode"), ""); + if (!mode.equalsIgnoreCase("LOAD")) { + return; + } + + String mirror = getOrDefault(map.get("mirror"), ""); + StructureMirror bedrockMirror = switch (mirror) { + case "FRONT_BACK" -> StructureMirror.X; + case "LEFT_RIGHT" -> StructureMirror.Z; + default -> StructureMirror.NONE; + }; + + String rotation = getOrDefault(map.get("rotation"), ""); + StructureRotation bedrockRotation = switch (rotation) { + case "CLOCKWISE_90" -> StructureRotation.ROTATE_90; + case "CLOCKWISE_180" -> StructureRotation.ROTATE_180; + case "COUNTERCLOCKWISE_90" -> StructureRotation.ROTATE_270; + default -> StructureRotation.NONE; + }; + + String name = getOrDefault(map.get("name"), ""); + int sizeX = getOrDefault(map.get("sizeX"), 0); + int sizeY = getOrDefault(map.get("sizeY"), 0); + int sizeZ = getOrDefault(map.get("sizeZ"), 0); + + session.getStructureBlockCache().setCurrentStructureBlock(null); + + Vector3i size = Vector3i.from(sizeX, sizeY, sizeZ); + if (size.equals(Vector3i.ZERO)) { + StructureBlockUtils.sendEmptyStructureData(session); + return; + } + + Vector3i offset = StructureBlockUtils.calculateOffset(bedrockRotation, bedrockMirror, + sizeX, sizeZ); + session.getStructureBlockCache().setBedrockOffset(offset); + session.getStructureBlockCache().setCurrentStructureName(name); + StructureBlockUtils.sendStructureData(session, size, name); + } + } + + + protected T getOrDefault(Tag tag, T defaultValue) { + //noinspection unchecked + return (tag != null && tag.getValue() != null) ? (T) tag.getValue() : defaultValue; } } diff --git a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java index 30b2907cc..25976f0f5 100644 --- a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java @@ -125,7 +125,7 @@ public class InventoryUtils { InventoryTranslator translator = session.getInventoryTranslator(); translator.closeInventory(session, inventory); if (confirm && inventory.isDisplayed() && !inventory.isPending() - && !(translator instanceof LecternInventoryTranslator) // TODO: double-check + && !(translator instanceof LecternInventoryTranslator) // Closing lecterns is not followed with a close confirmation ) { session.setClosingInventory(true); } diff --git a/core/src/main/java/org/geysermc/geyser/util/StructureBlockUtils.java b/core/src/main/java/org/geysermc/geyser/util/StructureBlockUtils.java new file mode 100644 index 000000000..9b3cfb53f --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/util/StructureBlockUtils.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.util; + +import com.github.steveice10.mc.protocol.data.game.inventory.UpdateStructureBlockAction; +import com.github.steveice10.mc.protocol.data.game.inventory.UpdateStructureBlockMode; +import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetStructureBlockPacket; +import org.cloudburstmc.math.vector.Vector3i; +import org.cloudburstmc.nbt.NbtList; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.nbt.NbtType; +import org.cloudburstmc.protocol.bedrock.data.structure.StructureMirror; +import org.cloudburstmc.protocol.bedrock.data.structure.StructureRotation; +import org.cloudburstmc.protocol.bedrock.data.structure.StructureSettings; +import org.cloudburstmc.protocol.bedrock.data.structure.StructureTemplateResponseType; +import org.cloudburstmc.protocol.bedrock.packet.StructureTemplateDataResponsePacket; +import org.geysermc.geyser.session.GeyserSession; + +public class StructureBlockUtils { + + private static final NbtMap EMPTY_STRUCTURE_DATA; + + static { + NbtMapBuilder builder = NbtMap.builder(); + builder.putInt("format_version", 1); + builder.putCompound("structure", NbtMap.builder() + .putList("block_indices", NbtType.LIST, NbtList.EMPTY, NbtList.EMPTY) + .putList("entities", NbtType.COMPOUND) + .putCompound("palette", NbtMap.EMPTY) + .build()); + builder.putList("structure_world_origin", NbtType.INT, 0, 0, 0); + EMPTY_STRUCTURE_DATA = builder.build(); + } + + public static void sendEmptyStructureData(GeyserSession session) { + StructureTemplateDataResponsePacket responsePacket = new StructureTemplateDataResponsePacket(); + responsePacket.setName(""); + responsePacket.setSave(false); + responsePacket.setType(StructureTemplateResponseType.QUERY); + session.sendUpstreamPacket(responsePacket); + } + + public static void sendStructureData(GeyserSession session,Vector3i size, String name) { + StructureTemplateDataResponsePacket responsePacket = new StructureTemplateDataResponsePacket(); + responsePacket.setName(name); + responsePacket.setSave(true); + responsePacket.setTag(EMPTY_STRUCTURE_DATA.toBuilder() + // Bedrock does not like negative sizes here + .putList("size", NbtType.INT, Math.abs(size.getX()), size.getY(), Math.abs(size.getZ())) + .build()); + responsePacket.setType(StructureTemplateResponseType.QUERY); + session.sendUpstreamPacket(responsePacket); + } + + public static Vector3i calculateOffset(StructureRotation structureRotation, StructureMirror structureMirror, + int sizeX, int sizeZ) { + int newOffsetX = 0; + int newOffsetZ = 0; + + switch (structureRotation) { + case ROTATE_90 -> { + switch (structureMirror) { + case NONE -> newOffsetX -= sizeZ - 1; + case X -> { + newOffsetZ -= sizeX - 1; + newOffsetX -= sizeZ - 1; + } + } + } + case ROTATE_180 -> { + switch (structureMirror) { + case NONE -> { + newOffsetX -= sizeX - 1; + newOffsetZ -= sizeZ - 1; + } + case Z -> newOffsetX -= sizeX - 1; + case X -> newOffsetZ -= sizeZ - 1; + } + } + case ROTATE_270 -> { + switch (structureMirror) { + case NONE -> newOffsetZ -= sizeX - 1; + case Z -> { + newOffsetZ -= sizeX - 1; + newOffsetX -= sizeZ - 1; + } + } + } + default -> { + switch (structureMirror) { + case Z -> newOffsetZ -= sizeZ - 1; + case X -> newOffsetX -= sizeX - 1; + } + } + } + + return Vector3i.from(newOffsetX, 0, newOffsetZ); + } + + public static void sendJavaStructurePacket(GeyserSession session, Vector3i blockPosition, Vector3i size, UpdateStructureBlockMode mode, UpdateStructureBlockAction action, + StructureSettings settings, boolean boundingBoxVisible, String structureName) { + + com.github.steveice10.mc.protocol.data.game.level.block.StructureMirror mirror = switch (settings.getMirror()) { + case X -> com.github.steveice10.mc.protocol.data.game.level.block.StructureMirror.FRONT_BACK; + case Z -> com.github.steveice10.mc.protocol.data.game.level.block.StructureMirror.LEFT_RIGHT; + default -> com.github.steveice10.mc.protocol.data.game.level.block.StructureMirror.NONE; + }; + + com.github.steveice10.mc.protocol.data.game.level.block.StructureRotation rotation = switch (settings.getRotation()) { + case ROTATE_90 -> com.github.steveice10.mc.protocol.data.game.level.block.StructureRotation.CLOCKWISE_90; + case ROTATE_180 -> com.github.steveice10.mc.protocol.data.game.level.block.StructureRotation.CLOCKWISE_180; + case ROTATE_270 -> com.github.steveice10.mc.protocol.data.game.level.block.StructureRotation.COUNTERCLOCKWISE_90; + default -> com.github.steveice10.mc.protocol.data.game.level.block.StructureRotation.NONE; + }; + + Vector3i offset = settings.getOffset(); + if (session.getStructureBlockCache().getBedrockOffset() != null) { + offset = settings.getOffset().sub(session.getStructureBlockCache().getBedrockOffset()); + } + + ServerboundSetStructureBlockPacket structureBlockPacket = new ServerboundSetStructureBlockPacket( + blockPosition, + action, + mode, + structureName, + offset, + settings.getSize(), + mirror, + rotation, + "", + settings.getIntegrityValue(), + settings.getIntegritySeed(), + settings.isIgnoringEntities(), + false, + boundingBoxVisible + ); + + session.sendDownstreamPacket(structureBlockPacket); + } +} From 576a1b7d7a6360bfffc4923c708446f4a92f7c96 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Wed, 17 Apr 2024 17:53:56 -0400 Subject: [PATCH 051/272] Remove map cache (#4576) --- .../geyser/session/GeyserSession.java | 2 - .../BedrockMapInfoRequestTranslator.java | 50 ------------------- .../java/level/JavaMapItemDataTranslator.java | 17 ++----- 3 files changed, 5 insertions(+), 64 deletions(-) delete mode 100644 core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMapInfoRequestTranslator.java diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index c0749400a..2a7b9b3fc 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -262,8 +262,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { @Setter private ItemMappings itemMappings; - private final Long2ObjectMap storedMaps = new Long2ObjectOpenHashMap<>(); - /** * Required to decode biomes correctly. */ diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMapInfoRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMapInfoRequestTranslator.java deleted file mode 100644 index 3e885b63f..000000000 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMapInfoRequestTranslator.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.geyser.translator.protocol.bedrock; - -import org.cloudburstmc.protocol.bedrock.packet.ClientboundMapItemDataPacket; -import org.cloudburstmc.protocol.bedrock.packet.MapInfoRequestPacket; -import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.translator.protocol.PacketTranslator; -import org.geysermc.geyser.translator.protocol.Translator; - -import java.util.concurrent.TimeUnit; - -@Translator(packet = MapInfoRequestPacket.class) -public class BedrockMapInfoRequestTranslator extends PacketTranslator { - - @Override - public void translate(GeyserSession session, MapInfoRequestPacket packet) { - long mapId = packet.getUniqueMapId(); - - ClientboundMapItemDataPacket mapPacket = session.getStoredMaps().remove(mapId); - if (mapPacket != null) { - // Delay the packet 100ms to prevent the client from ignoring the packet - session.scheduleInEventLoop(() -> session.sendUpstreamPacket(mapPacket), - 100, TimeUnit.MILLISECONDS); - } - } -} diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaMapItemDataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaMapItemDataTranslator.java index 34fbf2d9c..01b0f324f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaMapItemDataTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaMapItemDataTranslator.java @@ -44,7 +44,6 @@ public class JavaMapItemDataTranslator extends PacketTranslator Date: Thu, 18 Apr 2024 00:16:41 -0400 Subject: [PATCH 052/272] Reset metadata and attributes if needed when respawning (#4566) * Reset metadata and attributes if needed when respawning * Minor edits * Reset attributes in JavaLoginTranslator * Fix client bug when updating absorption and health in the same tick --- .../entity/attribute/GeyserAttributeType.java | 6 ++- .../entity/type/player/PlayerEntity.java | 5 ++- .../type/player/SessionPlayerEntity.java | 39 +++++++++++++++++++ .../geyser/session/GeyserSession.java | 2 +- .../protocol/java/JavaLoginTranslator.java | 2 +- .../protocol/java/JavaRespawnTranslator.java | 8 ++++ 6 files changed, 57 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/attribute/GeyserAttributeType.java b/core/src/main/java/org/geysermc/geyser/entity/attribute/GeyserAttributeType.java index 234c1afe9..88d493275 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/attribute/GeyserAttributeType.java +++ b/core/src/main/java/org/geysermc/geyser/entity/attribute/GeyserAttributeType.java @@ -51,7 +51,7 @@ public enum GeyserAttributeType { MAX_HEALTH("minecraft:generic.max_health", null, 0f, 1024f, 20f), // Bedrock Attributes - ABSORPTION(null, "minecraft:absorption", 0f, Float.MAX_VALUE, 0f), + ABSORPTION(null, "minecraft:absorption", 0f, 1024f, 0f), EXHAUSTION(null, "minecraft:player.exhaustion", 0f, 5f, 0f), EXPERIENCE(null, "minecraft:player.experience", 0f, 1f, 0f), EXPERIENCE_LEVEL(null, "minecraft:player.level", 0f, 24791.00f, 0f), @@ -66,6 +66,10 @@ public enum GeyserAttributeType { private final float maximum; private final float defaultValue; + public AttributeData getAttribute() { + return getAttribute(defaultValue); + } + public AttributeData getAttribute(float value) { return getAttribute(value, maximum); } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java index 9e3888138..20819f75e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java @@ -55,6 +55,7 @@ import org.cloudburstmc.protocol.bedrock.packet.SetEntityLinkPacket; import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket; import org.geysermc.geyser.api.entity.type.player.GeyserPlayerEntity; import org.geysermc.geyser.entity.EntityDefinitions; +import org.geysermc.geyser.entity.attribute.GeyserAttributeType; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.LivingEntity; import org.geysermc.geyser.entity.type.living.animal.tameable.ParrotEntity; @@ -283,7 +284,7 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity { attributesPacket.setRuntimeEntityId(geyserId); // Setting to a higher maximum since plugins/datapacks can probably extend the Bedrock soft limit attributesPacket.setAttributes(Collections.singletonList( - new AttributeData("minecraft:absorption", 0.0f, 1024f, entityMetadata.getPrimitiveValue(), 0.0f))); + GeyserAttributeType.ABSORPTION.getAttribute(entityMetadata.getPrimitiveValue()))); session.sendUpstreamPacket(attributesPacket); } @@ -307,7 +308,7 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity { * Sets the parrot occupying the shoulder. Bedrock Edition requires a full entity whereas Java Edition just * spawns it from the NBT data provided */ - private void setParrot(CompoundTag tag, boolean isLeft) { + protected void setParrot(CompoundTag tag, boolean isLeft) { if (tag != null && !tag.isEmpty()) { if ((isLeft && leftParrot != null) || (!isLeft && rightParrot != null)) { // No need to update a parrot's data when it already exists diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java index 751a24871..89aa540d8 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java @@ -30,6 +30,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.attribute.AttributeTyp import com.github.steveice10.mc.protocol.data.game.entity.metadata.GlobalPos; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import lombok.Getter; @@ -255,13 +256,51 @@ public class SessionPlayerEntity extends PlayerEntity { return session.getAuthData().uuid(); } + @Override + public void setAbsorptionHearts(FloatEntityMetadata entityMetadata) { + // The bedrock client can glitch when sending a health and absorption attribute in the same tick + // This can happen when switching servers. Resending the absorption attribute fixes the issue + attributes.put(GeyserAttributeType.ABSORPTION, GeyserAttributeType.ABSORPTION.getAttribute(entityMetadata.getPrimitiveValue())); + super.setAbsorptionHearts(entityMetadata); + } + public void resetMetadata() { // Reset all metadata to their default values // This is used when a player respawns + this.flags.clear(); this.initializeMetadata(); // Reset air this.resetAir(); + + // Explicitly reset all metadata not handled by initializeMetadata + setParrot(null, true); + setParrot(null, false); + + // Absorption is metadata in java edition + attributes.remove(GeyserAttributeType.ABSORPTION); + UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket(); + attributesPacket.setRuntimeEntityId(geyserId); + attributesPacket.setAttributes(Collections.singletonList( + GeyserAttributeType.ABSORPTION.getAttribute(0f))); + session.sendUpstreamPacket(attributesPacket); + + dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, 0); + dirtyMetadata.put(EntityDataTypes.EFFECT_AMBIENCE, (byte) 0); + dirtyMetadata.put(EntityDataTypes.FREEZING_EFFECT_STRENGTH, 0f); + + silent = false; + } + + public void resetAttributes() { + attributes.clear(); + maxHealth = GeyserAttributeType.MAX_HEALTH.getDefaultValue(); + + UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket(); + attributesPacket.setRuntimeEntityId(geyserId); + attributesPacket.setAttributes(Collections.singletonList( + GeyserAttributeType.MOVEMENT_SPEED.getAttribute())); + session.sendUpstreamPacket(attributesPacket); } public void resetAir() { diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 2a7b9b3fc..aff21182e 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -712,7 +712,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { // Default move speed // Bedrock clients move very fast by default until they get an attribute packet correcting the speed attributesPacket.setAttributes(Collections.singletonList( - new AttributeData("minecraft:movement", 0.0f, 1024f, 0.1f, 0.1f))); + GeyserAttributeType.MOVEMENT_SPEED.getAttribute())); upstream.sendPacket(attributesPacket); GameRulesChangedPacket gamerulePacket = new GameRulesChangedPacket(); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java index 23c19e84f..4a15157f9 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java @@ -71,7 +71,7 @@ public class JavaLoginTranslator extends PacketTranslator Date: Thu, 18 Apr 2024 07:29:40 -0700 Subject: [PATCH 053/272] Update release for preview builds (#4575) --- .github/workflows/build.yml | 47 +++++++++++++++----- .github/workflows/preview.yml | 73 +++++++++++++++++++++++++++++++ .github/workflows/pullrequest.yml | 18 ++++++++ 3 files changed, 127 insertions(+), 11 deletions(-) create mode 100644 .github/workflows/preview.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1d70d9948..c7b439182 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,6 +8,7 @@ on: paths-ignore: - '.github/ISSUE_TEMPLATE/*.yml' - '.github/actions/pullrequest.yml' + - '.github/actions/preview.yml' - '.idea/copyright/*.xml' - '.gitignore' - 'CONTRIBUTING.md' @@ -19,6 +20,8 @@ on: jobs: build: runs-on: ubuntu-latest + env: + PROJECT: 'geyser' steps: - name: Checkout repository and submodules # See https://github.com/actions/checkout/commits @@ -103,6 +106,34 @@ jobs: with: arguments: publish + - name: Get Release Metadata + if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} + uses: Kas-tle/base-release-action@b863fa0f89bd15267a96a72efb84aec25f168d4c # https://github.com/Kas-tle/base-release-action/releases/tag/main-11 + with: + appID: ${{ secrets.RELEASE_APP_ID }} + appPrivateKey: ${{ secrets.RELEASE_APP_PK }} + files: | + bungeecord:bootstrap/bungeecord/build/libs/Geyser-BungeeCord.jar + fabric:bootstrap/mod/fabric/build/libs/Geyser-Fabric.jar + neoforge:bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar + spigot:bootstrap/spigot/build/libs/Geyser-Spigot.jar + standalone:bootstrap/standalone/build/libs/Geyser-Standalone.jar + velocity:bootstrap/velocity/build/libs/Geyser-Velocity.jar + viaproxy:bootstrap/viaproxy/build/libs/Geyser-ViaProxy.jar + releaseEnabled: false + saveMetadata: true + - name: Update Generated Metadata + if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} + run: | + cat metadata.json + echo + version=$(cat gradle.properties | grep -o "version=[0-9\\.]*" | cut -d"=" -f2) + cat metadata.json | jq --arg project "${PROJECT}" --arg version "${version}" ' + . + | .changes |= map({"commit", "summary", "message"}) + | .downloads |= map_values({"name", "sha256"}) + | {$project, "repo", $version, "number": .build, "changes", "downloads"} + ' | tee metadata.json - name: Publish to Downloads API if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} shell: bash @@ -114,19 +145,13 @@ jobs: # Save the private key to a file echo "$DOWNLOADS_PRIVATE_KEY" > id_ecdsa chmod 600 id_ecdsa - # Set the project - project=geyser - # Get the version from gradle.properties - version=$(cat gradle.properties | grep -o "version=[0-9\\.]*" | cut -d"=" -f2) # Create the build folder - ssh -o StrictHostKeyChecking=no -i id_ecdsa $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP mkdir -p "~/uploads/$project/$GITHUB_RUN_NUMBER/" + ssh -o StrictHostKeyChecking=no -i id_ecdsa $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP mkdir -p "~/uploads/$PROJECT/$GITHUB_RUN_NUMBER/" # Copy over artifacts - rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" bootstrap/**/build/libs/Geyser-*.jar $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$project/$GITHUB_RUN_NUMBER/ - rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" bootstrap/mod/**/build/libs/Geyser-*.jar $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$project/$GITHUB_RUN_NUMBER/ + rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" bootstrap/**/build/libs/Geyser-*.jar $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$PROJECT/$GITHUB_RUN_NUMBER/ + rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" bootstrap/mod/**/build/libs/Geyser-*.jar $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$PROJECT/$GITHUB_RUN_NUMBER/ # Run the build script - # Push the metadata - echo "{\"project\": \"$project\", \"version\": \"$version\", \"id\": $GITHUB_RUN_NUMBER, \"commit\": \"$GITHUB_SHA\"}" > metadata.json - rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" metadata.json $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$project/$GITHUB_RUN_NUMBER/ + rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" metadata.json $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$PROJECT/$GITHUB_RUN_NUMBER/ - name: Publish to Modrinth (Fabric) uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 @@ -152,4 +177,4 @@ jobs: uses: Tim203/actions-git-discord-webhook@70f38ded3aca51635ec978ab4e1a58cd4cd0c2ff with: webhook_url: ${{ secrets.DISCORD_WEBHOOK }} - status: ${{ job.status }} + status: ${{ job.status }} \ No newline at end of file diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml new file mode 100644 index 000000000..794ade4d4 --- /dev/null +++ b/.github/workflows/preview.yml @@ -0,0 +1,73 @@ +name: Upload Preview + +on: + workflow_dispatch: + inputs: + runId: + required: true + description: 'ID of the action to pull artifacts from' + build: + required: true + description: 'Build number for the release' + version: + required: true + description: 'Version under which to upload to the Downloads API' + +jobs: + upload: + runs-on: ubuntu-latest + env: + PROJECT: 'geyser-preview' + BUILD: ${{ github.event.inputs.build }} + VERSION: ${{ github.event.inputs.version }} + steps: + - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # https://github.com/actions/download-artifact/releases/tag/v4.1.4 + with: + run-id: ${{ github.event.inputs.runId }} + github-token: ${{ secrets.GITHUB_TOKEN }} + merge-multiple: true + - name: Get Preview Metadata + if: success() + uses: Kas-tle/base-release-action@b863fa0f89bd15267a96a72efb84aec25f168d4c # https://github.com/Kas-tle/base-release-action/releases/tag/main-11 + with: + appID: ${{ secrets.RELEASE_APP_ID }} + appPrivateKey: ${{ secrets.RELEASE_APP_PK }} + files: | + bungeecord:Geyser-BungeeCord.jar + fabric:Geyser-Fabric.jar + neoforge:Geyser-NeoForge.jar + spigot:Geyser-Spigot.jar + standalone:Geyser-Standalone.jar + velocity:Geyser-Velocity.jar + viaproxy:Geyser-ViaProxy.jar + releaseEnabled: false + saveMetadata: true + updateReleaseData: false + - name: Update Generated Metadata + if: success() + run: | + cat metadata.json + echo + cat metadata.json | jq --arg project "${PROJECT}" --arg version "${VERSION}" --arg number "${BUILD}" ' + . + | .downloads |= map_values({"name", "sha256"}) + | {$project, "repo", $version, "number": $number | tonumber, "changes": [], "downloads"} + ' | tee metadata.json + - name: Publish to Downloads API + if: success() + shell: bash + env: + DOWNLOADS_USERNAME: ${{ vars.DOWNLOADS_USERNAME }} + DOWNLOADS_PRIVATE_KEY: ${{ secrets.DOWNLOADS_PRIVATE_KEY }} + DOWNLOADS_SERVER_IP: ${{ secrets.DOWNLOADS_SERVER_IP }} + run: | + # Save the private key to a file + echo "$DOWNLOADS_PRIVATE_KEY" > id_ecdsa + chmod 600 id_ecdsa + # Create the build folder + ssh -o StrictHostKeyChecking=no -i id_ecdsa $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP mkdir -p "~/uploads/$PROJECT/$BUILD/" + # Copy over artifacts + rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" Geyser-*.jar $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$PROJECT/$BUILD/ + # Run the build script + # Push the metadata + rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" metadata.json $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$PROJECT/$BUILD/ \ No newline at end of file diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 93be4711e..18223e7dc 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -102,3 +102,21 @@ jobs: name: Geyser ViaProxy path: geyser/bootstrap/viaproxy/build/libs/Geyser-ViaProxy.jar if-no-files-found: error + + - name: Trigger Preview Deployment + if: >- + contains(github.event.pull_request.labels.*.name, 'PR: Needs Testing') + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea + with: + script: | + github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: 'preview.yml', + ref: 'master', + inputs: { + runId: '${{ github.run_id }}', + build: '${{ github.run_number }}', + version: 'pr.${{ github.event.pull_request.number }}' + } + }); \ No newline at end of file From ae96ad2ec4afd81a7c1478ea8f52c10af0350ab0 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Thu, 18 Apr 2024 17:18:05 +0100 Subject: [PATCH 054/272] Change preview builds project --- .github/workflows/preview.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 794ade4d4..a2955a081 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -17,7 +17,7 @@ jobs: upload: runs-on: ubuntu-latest env: - PROJECT: 'geyser-preview' + PROJECT: 'geyserpreview' BUILD: ${{ github.event.inputs.build }} VERSION: ${{ github.event.inputs.version }} steps: @@ -70,4 +70,4 @@ jobs: rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" Geyser-*.jar $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$PROJECT/$BUILD/ # Run the build script # Push the metadata - rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" metadata.json $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$PROJECT/$BUILD/ \ No newline at end of file + rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" metadata.json $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$PROJECT/$BUILD/ From 0cc2921eda30e2fe44951d1886bdb7ec6c3acbdf Mon Sep 17 00:00:00 2001 From: ookiegajwa <91029880+ookiegajwa@users.noreply.github.com> Date: Thu, 18 Apr 2024 20:23:33 -0500 Subject: [PATCH 055/272] Translate scoreboard display name and number format (#4567) The following caveats apply because selectively removing or modifying the score numbers on Bedrock cannot be done without removing all of them: * "blank" and "styled" number formats are ignored for "list" and "sidebar" display slots * The "fixed" number format is appended to the end of the "list" and "sidebar" entry names instead of replacing the score number * The "below_name" slot has no limitations and displays identically to Java --- .../entity/type/player/PlayerEntity.java | 54 +++++++++++++--- .../geysermc/geyser/scoreboard/Objective.java | 34 +++++++++- .../org/geysermc/geyser/scoreboard/Score.java | 62 ++++++++++++++++++- .../geyser/scoreboard/Scoreboard.java | 4 +- .../java/scoreboard/JavaResetScorePacket.java | 4 +- .../JavaSetObjectiveTranslator.java | 16 ++++- .../scoreboard/JavaSetScoreTranslator.java | 18 ++---- 7 files changed, 157 insertions(+), 35 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java index 20819f75e..b957a0243 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java @@ -25,6 +25,11 @@ package org.geysermc.geyser.entity.type.player; +import com.github.steveice10.mc.protocol.codec.NbtComponentSerializer; +import com.github.steveice10.mc.protocol.data.game.chat.numbers.BlankFormat; +import com.github.steveice10.mc.protocol.data.game.chat.numbers.FixedFormat; +import com.github.steveice10.mc.protocol.data.game.chat.numbers.NumberFormat; +import com.github.steveice10.mc.protocol.data.game.chat.numbers.StyledFormat; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; @@ -33,6 +38,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEnt import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition; import com.github.steveice10.mc.protocol.data.game.scoreboard.TeamColor; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.StringTag; import lombok.Getter; import lombok.Setter; import net.kyori.adventure.text.Component; @@ -64,6 +70,7 @@ import org.geysermc.geyser.scoreboard.Score; import org.geysermc.geyser.scoreboard.Team; import org.geysermc.geyser.scoreboard.UpdateType; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.util.ChunkUtils; @@ -415,14 +422,36 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity { public void setBelowNameText(Objective objective) { if (objective != null && objective.getUpdateType() != UpdateType.REMOVE) { - int amount; Score score = objective.getScores().get(username); + String numberString; + NumberFormat numberFormat; + int amount; if (score != null) { - amount = score.getCurrentData().getScore(); + amount = score.getScore(); + numberFormat = score.getNumberFormat(); + if (numberFormat == null) { + numberFormat = objective.getNumberFormat(); + } } else { amount = 0; + numberFormat = objective.getNumberFormat(); } - String displayString = amount + " " + objective.getDisplayName(); + + if (numberFormat instanceof BlankFormat) { + numberString = ""; + } else if (numberFormat instanceof FixedFormat fixedFormat) { + numberString = MessageTranslator.convertMessage(fixedFormat.getValue()); + } else if (numberFormat instanceof StyledFormat styledFormat) { + CompoundTag styledAmount = styledFormat.getStyle().clone(); + styledAmount.put(new StringTag("text", String.valueOf(amount))); + + numberString = MessageTranslator.convertJsonMessage( + NbtComponentSerializer.tagComponentToJson(styledAmount).toString()); + } else { + numberString = String.valueOf(amount); + } + + String displayString = numberString + " " + ChatColor.RESET + objective.getDisplayName(); if (valid) { // Already spawned - we still need to run the rest of this code because the spawn packet will be @@ -431,13 +460,22 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity { packet.setRuntimeEntityId(geyserId); packet.getMetadata().put(EntityDataTypes.SCORE, displayString); session.sendUpstreamPacket(packet); + } else { + // Not spawned yet, store score value in dirtyMetadata to be picked up by #spawnEntity + dirtyMetadata.put(EntityDataTypes.SCORE, displayString); + } + } else { + if (valid) { + SetEntityDataPacket packet = new SetEntityDataPacket(); + packet.setRuntimeEntityId(geyserId); + packet.getMetadata().put(EntityDataTypes.SCORE, ""); + session.sendUpstreamPacket(packet); + } else { + // Not spawned yet, store score value in dirtyMetadata to be picked up by #spawnEntity + dirtyMetadata.put(EntityDataTypes.SCORE, ""); } - } else if (valid) { - SetEntityDataPacket packet = new SetEntityDataPacket(); - packet.setRuntimeEntityId(geyserId); - packet.getMetadata().put(EntityDataTypes.SCORE, ""); - session.sendUpstreamPacket(packet); } + } /** diff --git a/core/src/main/java/org/geysermc/geyser/scoreboard/Objective.java b/core/src/main/java/org/geysermc/geyser/scoreboard/Objective.java index fd9e0fbf3..c00c69660 100644 --- a/core/src/main/java/org/geysermc/geyser/scoreboard/Objective.java +++ b/core/src/main/java/org/geysermc/geyser/scoreboard/Objective.java @@ -25,13 +25,16 @@ package org.geysermc.geyser.scoreboard; +import com.github.steveice10.mc.protocol.data.game.chat.numbers.NumberFormat; import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition; import com.github.steveice10.mc.protocol.data.game.scoreboard.TeamColor; import lombok.Getter; import lombok.Setter; +import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.Nullable; import java.util.Map; +import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; @Getter @@ -47,6 +50,7 @@ public final class Objective { private ScoreboardPosition displaySlot; private String displaySlotName; private String displayName = "unknown"; + private NumberFormat numberFormat; private int type = 0; // 0 = integer, 1 = heart private Map scores = new ConcurrentHashMap<>(); @@ -85,25 +89,29 @@ public final class Objective { }; } - public void registerScore(String id, int score) { + public void registerScore(String id, int score, Component displayName, NumberFormat numberFormat) { if (!scores.containsKey(id)) { long scoreId = scoreboard.getNextId().getAndIncrement(); Score scoreObject = new Score(scoreId, id) .setScore(score) .setTeam(scoreboard.getTeamFor(id)) + .setDisplayName(displayName) + .setNumberFormat(numberFormat) .setUpdateType(UpdateType.ADD); scores.put(id, scoreObject); } } - public void setScore(String id, int score) { + public void setScore(String id, int score, Component displayName, NumberFormat numberFormat) { Score stored = scores.get(id); if (stored != null) { stored.setScore(score) + .setDisplayName(displayName) + .setNumberFormat(numberFormat) .setUpdateType(UpdateType.UPDATE); return; } - registerScore(id, score); + registerScore(id, score, displayName, numberFormat); } public void removeScore(String id) { @@ -128,6 +136,26 @@ public final class Objective { return this; } + public Objective setNumberFormat(NumberFormat numberFormat) { + if (Objects.equals(this.numberFormat, numberFormat)) { + return this; + } + + this.numberFormat = numberFormat; + if (updateType == UpdateType.NOTHING) { + updateType = UpdateType.UPDATE; + } + + // Update the number format for scores that are following this objective's number format + for (Score score : scores.values()) { + if (score.getNumberFormat() == null) { + score.setUpdateType(UpdateType.UPDATE); + } + } + + return this; + } + public Objective setType(int type) { this.type = type; if (updateType == UpdateType.NOTHING) { diff --git a/core/src/main/java/org/geysermc/geyser/scoreboard/Score.java b/core/src/main/java/org/geysermc/geyser/scoreboard/Score.java index 0a6623e97..ec17818c4 100644 --- a/core/src/main/java/org/geysermc/geyser/scoreboard/Score.java +++ b/core/src/main/java/org/geysermc/geyser/scoreboard/Score.java @@ -25,9 +25,16 @@ package org.geysermc.geyser.scoreboard; +import com.github.steveice10.mc.protocol.data.game.chat.numbers.FixedFormat; +import com.github.steveice10.mc.protocol.data.game.chat.numbers.NumberFormat; +import net.kyori.adventure.text.Component; import org.cloudburstmc.protocol.bedrock.data.ScoreInfo; import lombok.Getter; import lombok.experimental.Accessors; +import org.geysermc.geyser.text.ChatColor; +import org.geysermc.geyser.translator.text.MessageTranslator; + +import java.util.Objects; @Getter @Accessors(chain = true) @@ -52,6 +59,10 @@ public final class Score { } public String getDisplayName() { + String displayName = cachedData.displayName; + if (displayName != null) { + return displayName; + } Team team = cachedData.team; if (team != null) { return team.getDisplayName(name); @@ -88,6 +99,35 @@ public final class Score { return this; } + public Score setDisplayName(Component displayName) { + if (currentData.displayName != null && displayName != null) { + String convertedDisplayName = MessageTranslator.convertMessage(displayName); + if (!currentData.displayName.equals(convertedDisplayName)) { + currentData.displayName = convertedDisplayName; + setUpdateType(UpdateType.UPDATE); + } + return this; + } + // simplified from (this.displayName != null && displayName == null) || (this.displayName == null && displayName != null) + if (currentData.displayName != null || displayName != null) { + currentData.displayName = MessageTranslator.convertMessage(displayName); + setUpdateType(UpdateType.UPDATE); + } + return this; + } + + public NumberFormat getNumberFormat() { + return currentData.numberFormat; + } + + public Score setNumberFormat(NumberFormat numberFormat) { + if (!Objects.equals(currentData.numberFormat, numberFormat)) { + currentData.numberFormat = numberFormat; + setUpdateType(UpdateType.UPDATE); + } + return this; + } + public UpdateType getUpdateType() { return currentData.updateType; } @@ -105,7 +145,7 @@ public final class Score { (currentData.team != null && currentData.team.shouldUpdate()); } - public void update(String objectiveName) { + public void update(Objective objective) { if (cachedData == null) { cachedData = new ScoreData(); cachedData.updateType = UpdateType.ADD; @@ -119,13 +159,26 @@ public final class Score { currentData.changed = false; cachedData.team = currentData.team; cachedData.score = currentData.score; + cachedData.displayName = currentData.displayName; + cachedData.numberFormat = currentData.numberFormat; String name = this.name; - if (cachedData.team != null) { + if (cachedData.displayName != null) { + name = cachedData.displayName; + } else if (cachedData.team != null) { cachedData.team.prepareUpdate(); name = cachedData.team.getDisplayName(name); } - cachedInfo = new ScoreInfo(id, objectiveName, cachedData.score, name); + + NumberFormat numberFormat = cachedData.numberFormat; + if (numberFormat == null) { + numberFormat = objective.getNumberFormat(); + } + if (numberFormat instanceof FixedFormat fixedFormat) { + name += " " + ChatColor.RESET + MessageTranslator.convertMessage(fixedFormat.getValue()); + } + + cachedInfo = new ScoreInfo(id, objective.getObjectiveName(), cachedData.score, name); } @Getter @@ -136,6 +189,9 @@ public final class Score { private Team team; private int score; + private String displayName; + private NumberFormat numberFormat; + private ScoreData() { updateType = UpdateType.ADD; } diff --git a/core/src/main/java/org/geysermc/geyser/scoreboard/Scoreboard.java b/core/src/main/java/org/geysermc/geyser/scoreboard/Scoreboard.java index 216370bde..dfd74a79e 100644 --- a/core/src/main/java/org/geysermc/geyser/scoreboard/Scoreboard.java +++ b/core/src/main/java/org/geysermc/geyser/scoreboard/Scoreboard.java @@ -240,7 +240,7 @@ public final class Scoreboard { boolean update = score.shouldUpdate(); if (update) { - score.update(objective.getObjectiveName()); + score.update(objective); } if (score.getUpdateType() != REMOVE && update) { @@ -281,7 +281,7 @@ public final class Scoreboard { } if (score.shouldUpdate()) { - score.update(objective.getObjectiveName()); + score.update(objective); add = true; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaResetScorePacket.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaResetScorePacket.java index 418037760..01b4fddea 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaResetScorePacket.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaResetScorePacket.java @@ -54,7 +54,7 @@ public class JavaResetScorePacket extends PacketTranslator objective.setDisplayName(MessageTranslator.convertMessage(packet.getDisplayName())) - .setType(packet.getType().ordinal()); + case ADD, UPDATE -> { + objective.setDisplayName(MessageTranslator.convertMessage(packet.getDisplayName())) + .setNumberFormat(packet.getNumberFormat()) + .setType(packet.getType().ordinal()); + if (objective == scoreboard.getObjectiveSlots().get(ScoreboardPosition.BELOW_NAME)) { + // Update the score tag of all players + for (PlayerEntity entity : session.getEntityCache().getAllPlayerEntities()) { + if (entity.isValid()) { + entity.setBelowNameText(objective); + } + } + } + } case REMOVE -> { scoreboard.unregisterObjective(packet.getName()); if (objective != null && objective == scoreboard.getObjectiveSlots().get(ScoreboardPosition.BELOW_NAME)) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetScoreTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetScoreTranslator.java index 594e2cbed..6bffee3d3 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetScoreTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetScoreTranslator.java @@ -28,8 +28,6 @@ package org.geysermc.geyser.translator.protocol.java.scoreboard; import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.scoreboard.ClientboundSetScorePacket; import org.checkerframework.checker.nullness.qual.Nullable; -import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; -import org.cloudburstmc.protocol.bedrock.packet.SetEntityDataPacket; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.entity.type.player.PlayerEntity; @@ -54,7 +52,6 @@ public class JavaSetScoreTranslator extends PacketTranslator Date: Fri, 19 Apr 2024 05:41:06 -0400 Subject: [PATCH 056/272] Fix default wolf and cat collar color (#4582) --- .../living/animal/tameable/CatEntity.java | 11 +++++----- .../living/animal/tameable/WolfEntity.java | 22 ++++++++++++++----- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/CatEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/CatEntity.java index 412157b5d..93cb92c7d 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/CatEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/CatEntity.java @@ -45,7 +45,7 @@ import java.util.UUID; public class CatEntity extends TameableEntity { - private byte collarColor; + private byte collarColor = 14; // Red - default public CatEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); @@ -76,10 +76,7 @@ public class CatEntity extends TameableEntity { @Override public void setTameableFlags(ByteEntityMetadata entityMetadata) { super.setTameableFlags(entityMetadata); - // Update collar color if tamed - if (getFlag(EntityFlag.TAMED)) { - dirtyMetadata.put(EntityDataTypes.COLOR, collarColor); - } + updateCollarColor(); } public void setCatVariant(IntEntityMetadata entityMetadata) { @@ -101,6 +98,10 @@ public class CatEntity extends TameableEntity { public void setCollarColor(IntEntityMetadata entityMetadata) { collarColor = (byte) entityMetadata.getPrimitiveValue(); + updateCollarColor(); + } + + private void updateCollarColor() { // Needed or else wild cats are a red color if (getFlag(EntityFlag.TAMED)) { dirtyMetadata.put(EntityDataTypes.COLOR, collarColor); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java index 0f5b36ec3..c75247fdf 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java @@ -32,6 +32,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; +import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; @@ -41,6 +42,7 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import java.util.Collections; import java.util.Set; import java.util.UUID; @@ -54,7 +56,7 @@ public class WolfEntity extends TameableEntity { Items.PORKCHOP, Items.BEEF, Items.RABBIT, Items.COOKED_PORKCHOP, Items.COOKED_BEEF, Items.ROTTEN_FLESH, Items.MUTTON, Items.COOKED_MUTTON, Items.COOKED_RABBIT); - private byte collarColor; + private byte collarColor = 14; // Red - default public WolfEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); @@ -64,19 +66,27 @@ public class WolfEntity extends TameableEntity { public void setTameableFlags(ByteEntityMetadata entityMetadata) { super.setTameableFlags(entityMetadata); // Reset wolf color - byte xd = entityMetadata.getPrimitiveValue(); - boolean angry = (xd & 0x02) == 0x02; - if (angry) { + if (getFlag(EntityFlag.ANGRY)) { dirtyMetadata.put(EntityDataTypes.COLOR, (byte) 0); + } else if (getFlag(EntityFlag.TAMED)) { + updateCollarColor(); + + // This fixes tail angle when taming + UpdateAttributesPacket packet = new UpdateAttributesPacket(); + packet.setRuntimeEntityId(geyserId); + packet.setAttributes(Collections.singletonList(createHealthAttribute())); + session.sendUpstreamPacket(packet); } } public void setCollarColor(IntEntityMetadata entityMetadata) { collarColor = (byte) entityMetadata.getPrimitiveValue(); - if (getFlag(EntityFlag.ANGRY)) { - return; + if (!getFlag(EntityFlag.ANGRY) && getFlag(EntityFlag.TAMED)) { + updateCollarColor(); } + } + private void updateCollarColor() { dirtyMetadata.put(EntityDataTypes.COLOR, collarColor); if (ownerBedrockId == 0) { // If a color is set and there is no owner entity ID, set one. From 94f664ad8d065df32d0ce23cabd1e698ea7faf1e Mon Sep 17 00:00:00 2001 From: chris Date: Fri, 19 Apr 2024 11:50:40 +0200 Subject: [PATCH 057/272] Fix: Properly check whether the `so_reuseport` socket option is available (#4579) * Try to properly check if so_reuseport is available * io_uring "support" * comment out io_uring, for now * Make IO_uring opt-in via `-DGeyser.io_uring=true` flag * dont include io_uring * oops - bungee editing on mobile is hard * oops - spigot * oops - velocity * properly exclude all io_uring on all platforms except standalone --------- Co-authored-by: Kas-tle <26531652+Kas-tle@users.noreply.github.com> --- bootstrap/bungeecord/build.gradle.kts | 1 + bootstrap/spigot/build.gradle.kts | 1 + bootstrap/velocity/build.gradle.kts | 4 +- bootstrap/viaproxy/build.gradle.kts | 1 + .../geyser.modded-conventions.gradle.kts | 2 + core/build.gradle.kts | 7 +--- .../geyser/network/netty/Bootstraps.java | 17 +++++++- .../geyser/network/netty/GeyserServer.java | 40 ++++++++++++++----- gradle/libs.versions.toml | 2 + 9 files changed, 56 insertions(+), 19 deletions(-) diff --git a/bootstrap/bungeecord/build.gradle.kts b/bootstrap/bungeecord/build.gradle.kts index 1b57ffa5a..e93c096a1 100644 --- a/bootstrap/bungeecord/build.gradle.kts +++ b/bootstrap/bungeecord/build.gradle.kts @@ -22,6 +22,7 @@ tasks.withType { dependencies { exclude(dependency("com.google.*:.*")) + exclude(dependency("io.netty.incubator:.*")) exclude(dependency("io.netty:netty-transport-native-epoll:.*")) exclude(dependency("io.netty:netty-transport-native-unix-common:.*")) exclude(dependency("io.netty:netty-handler:.*")) diff --git a/bootstrap/spigot/build.gradle.kts b/bootstrap/spigot/build.gradle.kts index 41da1a0de..1d135c33d 100644 --- a/bootstrap/spigot/build.gradle.kts +++ b/bootstrap/spigot/build.gradle.kts @@ -41,6 +41,7 @@ tasks.withType { // We cannot shade Netty, or else native libraries will not load // Needed because older Spigot builds do not provide the haproxy module + exclude(dependency("io.netty.incubator:.*")) exclude(dependency("io.netty:netty-transport-classes-epoll:.*")) exclude(dependency("io.netty:netty-transport-native-epoll:.*")) exclude(dependency("io.netty:netty-transport-native-unix-common:.*")) diff --git a/bootstrap/velocity/build.gradle.kts b/bootstrap/velocity/build.gradle.kts index 97e9d1f57..da826803c 100644 --- a/bootstrap/velocity/build.gradle.kts +++ b/bootstrap/velocity/build.gradle.kts @@ -12,7 +12,8 @@ platformRelocate("org.yaml") exclude("com.google.*:*") -// Needed because Velocity provides every dependency except netty-resolver-dns +// Needed because Velocity provides every dependency except netty-resolver-dns +exclude("io.netty.incubator:.*") exclude("io.netty:netty-transport-native-epoll:*") exclude("io.netty:netty-transport-native-unix-common:*") exclude("io.netty:netty-transport-native-kqueue:*") @@ -57,6 +58,7 @@ tasks.withType { exclude(dependency("io.netty:netty-transport:.*")) exclude(dependency("io.netty:netty-codec:.*")) exclude(dependency("io.netty:netty-codec-haproxy:.*")) + exclude(dependency("io.netty.incubator:.*")) exclude(dependency("org.slf4j:.*")) exclude(dependency("org.ow2.asm:.*")) // Exclude all Kyori dependencies except the legacy NBT serializer diff --git a/bootstrap/viaproxy/build.gradle.kts b/bootstrap/viaproxy/build.gradle.kts index 01c5b5b34..6eadc790f 100644 --- a/bootstrap/viaproxy/build.gradle.kts +++ b/bootstrap/viaproxy/build.gradle.kts @@ -22,6 +22,7 @@ tasks.withType { dependencies { exclude(dependency("com.google.*:.*")) exclude(dependency("io.netty:.*")) + exclude(dependency("io.netty.incubator:.*")) exclude(dependency("org.slf4j:.*")) exclude(dependency("org.ow2.asm:.*")) } diff --git a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts index e011b7139..3d41dbbb4 100644 --- a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts @@ -26,6 +26,8 @@ provided("io.netty", "netty-transport-native-epoll") provided("io.netty", "netty-transport-native-unix-common") provided("io.netty", "netty-transport-classes-kqueue") provided("io.netty", "netty-transport-native-kqueue") +provided("io.netty.incubator", "netty-incubator-transport-native-io_uring") +provided("io.netty.incubator", "netty-incubator-transport-classes-io_uring") provided("io.netty", "netty-handler") provided("io.netty", "netty-common") provided("io.netty", "netty-buffer") diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 93c9f4f13..b1244d55d 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -47,6 +47,8 @@ dependencies { implementation(libs.netty.transport.native.epoll) { artifact { classifier = "linux-x86_64" } } implementation(libs.netty.transport.native.epoll) { artifact { classifier = "linux-aarch_64" } } implementation(libs.netty.transport.native.kqueue) { artifact { classifier = "osx-x86_64" } } + implementation(libs.netty.transport.native.io.uring) { artifact { classifier = "linux-x86_64" } } + implementation(libs.netty.transport.native.io.uring) { artifact { classifier = "linux-aarch_64" } } // Adventure text serialization api(libs.bundles.adventure) @@ -66,11 +68,6 @@ dependencies { api(libs.events) } -configurations.api { - // This is still experimental - additionally, it could only really benefit standalone - exclude(group = "io.netty.incubator", module = "netty-incubator-transport-native-io_uring") -} - tasks.processResources { // This is solely for backwards compatibility for other programs that used this file before the switch to gradle. // It used to be generated by the maven Git-Commit-Id-Plugin diff --git a/core/src/main/java/org/geysermc/geyser/network/netty/Bootstraps.java b/core/src/main/java/org/geysermc/geyser/network/netty/Bootstraps.java index 9f889a6e7..fbc333106 100644 --- a/core/src/main/java/org/geysermc/geyser/network/netty/Bootstraps.java +++ b/core/src/main/java/org/geysermc/geyser/network/netty/Bootstraps.java @@ -49,6 +49,7 @@ public final class Bootstraps { String kernelVersion; try { kernelVersion = Native.KERNEL_VERSION; + GeyserImpl.getInstance().getLogger().debug("Kernel version: " + kernelVersion); } catch (Throwable e) { GeyserImpl.getInstance().getLogger().debug("Could not determine kernel version! " + e.getMessage()); kernelVersion = null; @@ -67,10 +68,22 @@ public final class Bootstraps { } @SuppressWarnings({"rawtypes, unchecked"}) - public static void setupBootstrap(AbstractBootstrap bootstrap) { + public static boolean setupBootstrap(AbstractBootstrap bootstrap) { + boolean success = true; if (REUSEPORT_AVAILABLE) { - bootstrap.option(UnixChannelOption.SO_REUSEPORT, true); + // Guessing whether so_reuseport is available based on kernel version is cool, but unreliable. + Channel channel = bootstrap.register().channel(); + if (channel.config().setOption(UnixChannelOption.SO_REUSEPORT, true)) { + bootstrap.option(UnixChannelOption.SO_REUSEPORT, true); + } else { + // If this occurs, we guessed wrong and reuseport is not available + GeyserImpl.getInstance().getLogger().debug("so_reuseport is not available despite version being " + Native.KERNEL_VERSION); + success = false; + } + // Now yeet that channel + channel.close(); } + return success; } private static int[] fromString(String input) { diff --git a/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java b/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java index 8ead16623..652901f36 100644 --- a/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java +++ b/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.network.netty; -import com.github.steveice10.packetlib.helper.TransportHelper; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; @@ -39,6 +38,9 @@ import io.netty.channel.kqueue.KQueueEventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.DatagramChannel; import io.netty.channel.socket.nio.NioDatagramChannel; +import io.netty.incubator.channel.uring.IOUring; +import io.netty.incubator.channel.uring.IOUringDatagramChannel; +import io.netty.incubator.channel.uring.IOUringEventLoopGroup; import io.netty.util.concurrent.Future; import lombok.Getter; import net.jodah.expiringmap.ExpirationPolicy; @@ -106,7 +108,7 @@ public final class GeyserServer { @Getter private final ExpiringMap proxiedAddresses; - private final int listenCount; + private int listenCount; private ChannelFuture[] bootstrapFutures; @@ -127,8 +129,11 @@ public final class GeyserServer { this.childGroup = TRANSPORT.eventLoopGroupFactory().apply(threadCount); this.bootstrap = this.createBootstrap(); - // setup SO_REUSEPORT if exists - Bootstraps.setupBootstrap(this.bootstrap); + // setup SO_REUSEPORT if exists - or, if the option does not actually exist, reset listen count + // otherwise, we try to bind multiple times which wont work if so_reuseport is not valid + if (!Bootstraps.setupBootstrap(this.bootstrap)) { + this.listenCount = 1; + } if (this.geyser.getConfig().getBedrock().isEnableProxyProtocol()) { this.proxiedAddresses = ExpiringMap.builder() @@ -415,22 +420,35 @@ public final class GeyserServer { } private static Transport compatibleTransport() { - TransportHelper.TransportMethod transportMethod = TransportHelper.determineTransportMethod(); - if (transportMethod == TransportHelper.TransportMethod.EPOLL) { + if (isClassAvailable("io.netty.incubator.channel.uring.IOUring") + && IOUring.isAvailable() + && Boolean.parseBoolean(System.getProperty("Geyser.io_uring"))) { + return new Transport(IOUringDatagramChannel.class, IOUringEventLoopGroup::new); + } + + if (isClassAvailable("io.netty.channel.epoll.Epoll") && Epoll.isAvailable()) { return new Transport(EpollDatagramChannel.class, EpollEventLoopGroup::new); } - if (transportMethod == TransportHelper.TransportMethod.KQUEUE) { + if (isClassAvailable("io.netty.channel.kqueue.KQueue") && KQueue.isAvailable()) { return new Transport(KQueueDatagramChannel.class, KQueueEventLoopGroup::new); } - // if (transportMethod == TransportHelper.TransportMethod.IO_URING) { - // return new Transport(IOUringDatagramChannel.class, IOUringEventLoopGroup::new); - // } - return new Transport(NioDatagramChannel.class, NioEventLoopGroup::new); } private record Transport(Class datagramChannel, IntFunction eventLoopGroupFactory) { } + + /** + * Used so implementations can opt to remove these dependencies if so desired + */ + private static boolean isClassAvailable(String className) { + try { + Class.forName(className); + return true; + } catch (ClassNotFoundException e) { + return false; + } + } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3111750a8..7feec84e0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,6 +6,7 @@ events = "1.1-SNAPSHOT" jackson = "2.17.0" fastutil = "8.5.2" netty = "4.1.107.Final" +netty-io-uring = "0.0.25.Final-SNAPSHOT" guava = "29.0-jre" gson = "2.3.1" # Provided by Spigot 1.8.8 websocket = "1.5.1" @@ -75,6 +76,7 @@ netty-codec-haproxy = { group = "io.netty", name = "netty-codec-haproxy", versio netty-handler = { group = "io.netty", name = "netty-handler", version.ref = "netty" } netty-transport-native-epoll = { group = "io.netty", name = "netty-transport-native-epoll", version.ref = "netty" } netty-transport-native-kqueue = { group = "io.netty", name = "netty-transport-native-kqueue", version.ref = "netty" } +netty-transport-native-io_uring = { group = "io.netty.incubator", name = "netty-incubator-transport-native-io_uring", version.ref = "netty-io-uring" } log4j-api = { group = "org.apache.logging.log4j", name = "log4j-api", version.ref = "log4j" } log4j-core = { group = "org.apache.logging.log4j", name = "log4j-core", version.ref = "log4j" } From 525a9ccec4f3dfdcbec328c9b382a782540cb7d9 Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Fri, 19 Apr 2024 18:47:00 -0700 Subject: [PATCH 058/272] Fix Preview Workflow (#4583) * Fix preview workflow * Correct path to artifacts * Uncomment repo checks * Don't enforce repo/branch on preview deploy * Correct paths-ignore for build --- .../{pullrequest.yml => build-remote.yml} | 68 +++++++------------ .github/workflows/build.yml | 22 ++++-- .github/workflows/preview.yml | 33 +++++++-- .github/workflows/pull-request.yml | 24 +++++++ core/build.gradle.kts | 5 +- 5 files changed, 92 insertions(+), 60 deletions(-) rename .github/workflows/{pullrequest.yml => build-remote.yml} (65%) create mode 100644 .github/workflows/pull-request.yml diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/build-remote.yml similarity index 65% rename from .github/workflows/pullrequest.yml rename to .github/workflows/build-remote.yml index 18223e7dc..75bcfaff5 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/build-remote.yml @@ -1,13 +1,27 @@ -name: Build Pull Request +name: Build Remote -on: - pull_request: - merge_group: +on: + workflow_call: + inputs: + repository: + required: true + description: 'The repo of the remote' + type: string + ref: + required: true + description: 'The ref of the remote' + type: string + +permissions: {} jobs: build: runs-on: ubuntu-latest steps: + - name: Set Build Number + run: | + echo "BUILD_NUMBER=${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV + - name: Set up JDK 17 # See https://github.com/actions/setup-java/commits uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0 @@ -15,29 +29,12 @@ jobs: java-version: 17 distribution: temurin - - name: Check if the author has forked the API repo - # See https://github.com/Kas-tle/find-forks-action/commits - uses: Kas-tle/find-forks-action@1b5447d1e3c7a8ed79583dd817cc5399686eed3a - id: find_forks - with: - owner: GeyserMC - repo: api - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Use author's API repo if it exists - if: ${{ steps.find_forks.outputs.target_branch_found == 'true' }} - env: - API_FORK_URL: ${{ steps.find_forks.outputs.user_fork_url }} - API_FORK_BRANCH: ${{ github.event.pull_request.head.ref }} - run: | - git clone "${API_FORK_URL}" --single-branch --branch "${API_FORK_BRANCH}" api - cd api - ./gradlew publishToMavenLocal - - name: Checkout repository and submodules # See https://github.com/actions/checkout/commits uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: + repository: ${{ inputs.repository }} + ref: ${{ inputs.ref }} submodules: recursive path: geyser @@ -46,11 +43,12 @@ jobs: uses: gradle/wrapper-validation-action@699bb18358f12c5b78b37bb0111d3a0e2276e0e2 # v2.1.1 - name: Build Geyser - # See https://github.com/gradle/gradle-build-action/commits - uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 from https://github.com/gradle/actions/commits + # See https://github.com/gradle/actions/commits + uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 with: arguments: build build-root-directory: geyser + cache-read-only: true - name: Archive artifacts (Geyser Fabric) # See https://github.com/actions/upload-artifact/commits @@ -101,22 +99,4 @@ jobs: with: name: Geyser ViaProxy path: geyser/bootstrap/viaproxy/build/libs/Geyser-ViaProxy.jar - if-no-files-found: error - - - name: Trigger Preview Deployment - if: >- - contains(github.event.pull_request.labels.*.name, 'PR: Needs Testing') - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea - with: - script: | - github.rest.actions.createWorkflowDispatch({ - owner: context.repo.owner, - repo: context.repo.repo, - workflow_id: 'preview.yml', - ref: 'master', - inputs: { - runId: '${{ github.run_id }}', - build: '${{ github.run_number }}', - version: 'pr.${{ github.event.pull_request.number }}' - } - }); \ No newline at end of file + if-no-files-found: error \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c7b439182..9582df3e8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,8 +7,9 @@ on: - 'gh-readonly-queue/**' paths-ignore: - '.github/ISSUE_TEMPLATE/*.yml' - - '.github/actions/pullrequest.yml' - - '.github/actions/preview.yml' + - '.github/actions/workflows/build-remote.yml' + - '.github/actions/workflows/preview.yml' + - '.github/actions/workflows/pull-request.yml' - '.idea/copyright/*.xml' - '.gitignore' - 'CONTRIBUTING.md' @@ -23,6 +24,13 @@ jobs: env: PROJECT: 'geyser' steps: + - name: Set Build Number + env: + BUILD_JSON: ${{ vars.RELEASEACTION_PREVRELEASE }} + run: | + BUILD_NUMBER=$(echo $BUILD_JSON | jq --arg branch "${GITHUB_REF_NAME}" 'if .[$branch] == null then 1 else .[$branch] | .t | tonumber + 1 end // 1') + echo "BUILD_NUMBER=${BUILD_NUMBER}" >> $GITHUB_ENV + - name: Checkout repository and submodules # See https://github.com/actions/checkout/commits uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 @@ -40,8 +48,8 @@ jobs: distribution: temurin - name: Build - # See https://github.com/gradle/gradle-build-action/commits - uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 from https://github.com/gradle/actions/commits + # See https://github.com/gradle/actions/commits + uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 with: arguments: build gradle-home-cache-cleanup: true @@ -108,7 +116,8 @@ jobs: - name: Get Release Metadata if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} - uses: Kas-tle/base-release-action@b863fa0f89bd15267a96a72efb84aec25f168d4c # https://github.com/Kas-tle/base-release-action/releases/tag/main-11 + # See https://github.com/Kas-tle/base-release-action/releases/tag/main-11 + uses: Kas-tle/base-release-action@b863fa0f89bd15267a96a72efb84aec25f168d4c # main-11 with: appID: ${{ secrets.RELEASE_APP_ID }} appPrivateKey: ${{ secrets.RELEASE_APP_PK }} @@ -134,6 +143,7 @@ jobs: | .downloads |= map_values({"name", "sha256"}) | {$project, "repo", $version, "number": .build, "changes", "downloads"} ' | tee metadata.json + echo - name: Publish to Downloads API if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} shell: bash @@ -177,4 +187,4 @@ jobs: uses: Tim203/actions-git-discord-webhook@70f38ded3aca51635ec978ab4e1a58cd4cd0c2ff with: webhook_url: ${{ secrets.DISCORD_WEBHOOK }} - status: ${{ job.status }} \ No newline at end of file + status: ${{ job.status }} diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index a2955a081..ccac3ba85 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -12,23 +12,44 @@ on: version: required: true description: 'Version under which to upload to the Downloads API' + workflow_call: + inputs: + build: + required: true + description: 'Build number for the release' + type: string + version: + required: true + description: 'Version under which to upload to the Downloads API' + type: string jobs: upload: runs-on: ubuntu-latest env: - PROJECT: 'geyserpreview' - BUILD: ${{ github.event.inputs.build }} - VERSION: ${{ github.event.inputs.version }} + PROJECT: 'geyser-preview' steps: - - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # https://github.com/actions/download-artifact/releases/tag/v4.1.4 + - name: Set Variables + id: setvars + run: | + if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + echo "BUILD=${{ github.event.inputs.build }}" >> $GITHUB_ENV + echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_ENV + echo "RUN=${{ github.event.inputs.runId }}" >> $GITHUB_OUTPUT + else + echo "BUILD=${{ inputs.build }}" >> $GITHUB_ENV + echo "VERSION=${{ inputs.version }}" >> $GITHUB_ENV + echo "RUN=${{ github.run_id }}" >> $GITHUB_OUTPUT + fi + - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 with: - run-id: ${{ github.event.inputs.runId }} + run-id: ${{ steps.setvars.outputs.RUN }} github-token: ${{ secrets.GITHUB_TOKEN }} merge-multiple: true - name: Get Preview Metadata if: success() - uses: Kas-tle/base-release-action@b863fa0f89bd15267a96a72efb84aec25f168d4c # https://github.com/Kas-tle/base-release-action/releases/tag/main-11 + # See https://github.com/Kas-tle/base-release-action/releases/tag/main-11 + uses: Kas-tle/base-release-action@664c39985eb9d0d393ce98e7eb8414d3d98e762a # main-11 with: appID: ${{ secrets.RELEASE_APP_ID }} appPrivateKey: ${{ secrets.RELEASE_APP_PK }} diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml new file mode 100644 index 000000000..bc5e57b6b --- /dev/null +++ b/.github/workflows/pull-request.yml @@ -0,0 +1,24 @@ +name: Process Pull Request + +on: + pull_request_target: + +jobs: + build: + # Forbid access to secrets nor GH Token perms while building the PR + permissions: {} + secrets: {} + uses: ./.github/workflows/build-remote.yml + with: + repository: ${{ github.event.pull_request.head.repo.full_name }} + ref: ${{ github.event.pull_request.head.sha }} + preview: + needs: [build] + if: >- + contains(github.event.pull_request.labels.*.name, 'PR: Needs Testing') + # Allow access to secrets if we are uploading a preview + secrets: inherit + uses: ./.github/workflows/preview.yml + with: + build: ${{ github.run_number }} + version: pr.${{ github.event.pull_request.number }} \ No newline at end of file diff --git a/core/build.gradle.kts b/core/build.gradle.kts index b1244d55d..42d4e13c5 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -98,7 +98,7 @@ configure { } fun Project.buildNumber(): Int = - (System.getenv("GITHUB_RUN_NUMBER") ?: jenkinsBuildNumber())?.let { Integer.parseInt(it) } ?: -1 + (System.getenv("BUILD_NUMBER"))?.let { Integer.parseInt(it) } ?: -1 inner class GitInfo { val branch: String @@ -131,9 +131,6 @@ inner class GitInfo { } } -// todo remove this when we're not using Jenkins anymore -fun jenkinsBuildNumber(): String? = System.getenv("BUILD_NUMBER") - // Manual task to download the bedrock data files from the CloudburstMC/Data repository // Invoke with ./gradlew :core:downloadBedrockData --suffix=1_20_70 // Set suffix to the current Bedrock version From 1bca6421d30966fb4f1b7703df2885da43517d6c Mon Sep 17 00:00:00 2001 From: rtm516 Date: Sat, 20 Apr 2024 03:12:27 +0100 Subject: [PATCH 059/272] Update preview action to use correct project --- .github/workflows/preview.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index ccac3ba85..13712d5ef 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -27,7 +27,7 @@ jobs: upload: runs-on: ubuntu-latest env: - PROJECT: 'geyser-preview' + PROJECT: 'geyserpreview' steps: - name: Set Variables id: setvars From 810c9ced724360b3b52efa3b70eef1682e2bb86b Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Sat, 20 Apr 2024 17:21:39 -0400 Subject: [PATCH 060/272] Fix filled cauldrons only showing as water (#4585) * Fix filled cauldrons only showing as water * Update comment --- .../org/geysermc/geyser/level/block/BlockStateValues.java | 4 ++-- .../translator/level/block/entity/BedrockOnlyBlockEntity.java | 2 +- .../java/level/JavaLevelChunkWithLightTranslator.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java b/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java index e665a22ef..52759c709 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java @@ -260,8 +260,6 @@ public final class BlockStateValues { } /** - * Non-water cauldrons (since Bedrock 1.18.30) must have a block entity packet sent on chunk load to fix rendering issues. - * * @return if this Java block state is a non-empty non-water cauldron */ public static boolean isNonWaterCauldron(int state) { @@ -269,6 +267,8 @@ public final class BlockStateValues { } /** + * Cauldrons (since Bedrock 1.18.30) must have a block entity packet sent on chunk load to fix rendering issues. + *

* When using a bucket on a cauldron sending a ServerboundUseItemPacket can result in the liquid being placed. * * @return if this Java block state is a cauldron diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedrockOnlyBlockEntity.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedrockOnlyBlockEntity.java index 07b075690..051986473 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedrockOnlyBlockEntity.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedrockOnlyBlockEntity.java @@ -63,7 +63,7 @@ public interface BedrockOnlyBlockEntity extends RequiresBlockState { return FlowerPotBlockEntityTranslator.getTag(session, blockState, position); } else if (PistonBlockEntityTranslator.isBlock(blockState)) { return PistonBlockEntityTranslator.getTag(blockState, position); - } else if (BlockStateValues.isNonWaterCauldron(blockState)) { + } else if (BlockStateValues.isCauldron(blockState)) { // As of 1.18.30: this is required to make rendering not look weird on chunk load (lava and snow cauldrons look dim) return NbtMap.builder() .putString("id", "Cauldron") diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java index 8a35bbb5c..a98ead719 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java @@ -200,7 +200,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator> 8) & 0xF), (packet.getZ() << 4) + ((yzx >> 4) & 0xF)), javaId @@ -259,7 +259,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator Date: Sat, 20 Apr 2024 19:07:39 -0700 Subject: [PATCH 061/272] Fallback to GITHUB_RUN_NUMBER if RELEASEACTION_PREVRELEASE is unset (#4587) This is so there is still a build number when built on other repositories --- .github/workflows/build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9582df3e8..1ef0118ff 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,9 +7,9 @@ on: - 'gh-readonly-queue/**' paths-ignore: - '.github/ISSUE_TEMPLATE/*.yml' - - '.github/actions/workflows/build-remote.yml' - - '.github/actions/workflows/preview.yml' - - '.github/actions/workflows/pull-request.yml' + - '.github/workflows/build-remote.yml' + - '.github/workflows/preview.yml' + - '.github/workflows/pull-request.yml' - '.idea/copyright/*.xml' - '.gitignore' - 'CONTRIBUTING.md' @@ -29,7 +29,7 @@ jobs: BUILD_JSON: ${{ vars.RELEASEACTION_PREVRELEASE }} run: | BUILD_NUMBER=$(echo $BUILD_JSON | jq --arg branch "${GITHUB_REF_NAME}" 'if .[$branch] == null then 1 else .[$branch] | .t | tonumber + 1 end // 1') - echo "BUILD_NUMBER=${BUILD_NUMBER}" >> $GITHUB_ENV + echo "BUILD_NUMBER=${BUILD_NUMBER:=$GITHUB_RUN_NUMBER}" >> $GITHUB_ENV - name: Checkout repository and submodules # See https://github.com/actions/checkout/commits From 3fa79529365e4ceae3fb4f95b2acde2f1305a13d Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Tue, 23 Apr 2024 09:16:18 -0700 Subject: [PATCH 062/272] 1.20.80 Support and Protocol Changes (#4561) * Make evil more harder Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Deregister more unused packets Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Add more unused packets Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Pin protocol to 68dc192 * Correction * Update Protocol * More kicking Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * stop reading when there is no item to read (#9) * Bump protocol Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * 1.20.80 Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Remove unused postinitchannel GeyserServerInitializer * Pull protocol jitpack from cloudburst again * Actually builds Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Bump protocol to fix BossEventPacket & EmotePacket Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Add remove before merge comment Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Bump protocol to fix BlockEntityDataPacket and ignore serverbound BossEventPacket Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Bump protocol & add more illegal/ignored packets Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Remove deprecated packet Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Ignore ClientCacheStatusPacket instead of disallow Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Define static serializers Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Less static class nonsense more correct order Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Remove unused import Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Bump protocol Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Move codec processing to CodecProcessor Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Falsify recipe symetry assumption Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Update Protocol for 2 wrong packet IDs & 5 wrong directions * Jitpack protocol from Geyser repo --------- Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> Co-authored-by: chris --- README.md | 2 +- .../geyser/network/CodecProcessor.java | 292 + .../geysermc/geyser/network/GameProtocol.java | 29 +- .../network/GeyserServerInitializer.java | 8 + .../geyser/network/InvalidPacketHandler.java | 58 + .../populator/BlockRegistryPopulator.java | 4 +- .../registry/populator/Conversion662_649.java | 4 + .../registry/populator/Conversion671_662.java | 182 + .../populator/ItemRegistryPopulator.java | 4 +- .../populator/RecipeRegistryPopulator.java | 2 +- .../java/JavaUpdateRecipesTranslator.java | 2 +- .../JavaContainerSetSlotTranslator.java | 3 +- .../bedrock/block_palette.1_20_80.nbt | Bin 0 -> 176786 bytes .../bedrock/creative_items.1_20_80.json | 5812 +++++++++++++++ .../resources/bedrock/entity_identifiers.dat | Bin 7886 -> 7951 bytes .../bedrock/runtime_item_states.1_20_80.json | 6274 +++++++++++++++++ core/src/main/resources/mappings | 2 +- gradle/libs.versions.toml | 15 +- 18 files changed, 12661 insertions(+), 32 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java create mode 100644 core/src/main/java/org/geysermc/geyser/network/InvalidPacketHandler.java create mode 100644 core/src/main/java/org/geysermc/geyser/registry/populator/Conversion671_662.java create mode 100644 core/src/main/resources/bedrock/block_palette.1_20_80.nbt create mode 100644 core/src/main/resources/bedrock/creative_items.1_20_80.json create mode 100644 core/src/main/resources/bedrock/runtime_item_states.1_20_80.json diff --git a/README.md b/README.md index 0aa9d009a..e17c9d2bb 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here! -### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.73 and Minecraft Java 1.20.4 +### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.80 and Minecraft Java 1.20.4 ## Setting Up Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser. diff --git a/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java b/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java new file mode 100644 index 000000000..4ad02a644 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.network; + +import io.netty.buffer.ByteBuf; +import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec; +import org.cloudburstmc.protocol.bedrock.codec.BedrockCodecHelper; +import org.cloudburstmc.protocol.bedrock.codec.BedrockPacketSerializer; +import org.cloudburstmc.protocol.bedrock.codec.v291.serializer.MobArmorEquipmentSerializer_v291; +import org.cloudburstmc.protocol.bedrock.codec.v291.serializer.MobEquipmentSerializer_v291; +import org.cloudburstmc.protocol.bedrock.codec.v291.serializer.PlayerHotbarSerializer_v291; +import org.cloudburstmc.protocol.bedrock.codec.v291.serializer.SetEntityLinkSerializer_v291; +import org.cloudburstmc.protocol.bedrock.codec.v390.serializer.PlayerSkinSerializer_v390; +import org.cloudburstmc.protocol.bedrock.codec.v407.serializer.InventoryContentSerializer_v407; +import org.cloudburstmc.protocol.bedrock.codec.v407.serializer.InventorySlotSerializer_v407; +import org.cloudburstmc.protocol.bedrock.codec.v486.serializer.BossEventSerializer_v486; +import org.cloudburstmc.protocol.bedrock.codec.v557.serializer.SetEntityDataSerializer_v557; +import org.cloudburstmc.protocol.bedrock.codec.v662.serializer.SetEntityMotionSerializer_v662; +import org.cloudburstmc.protocol.bedrock.packet.AnvilDamagePacket; +import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket; +import org.cloudburstmc.protocol.bedrock.packet.BossEventPacket; +import org.cloudburstmc.protocol.bedrock.packet.ClientCacheBlobStatusPacket; +import org.cloudburstmc.protocol.bedrock.packet.ClientCacheStatusPacket; +import org.cloudburstmc.protocol.bedrock.packet.ClientCheatAbilityPacket; +import org.cloudburstmc.protocol.bedrock.packet.ClientToServerHandshakePacket; +import org.cloudburstmc.protocol.bedrock.packet.CodeBuilderSourcePacket; +import org.cloudburstmc.protocol.bedrock.packet.CraftingEventPacket; +import org.cloudburstmc.protocol.bedrock.packet.CreatePhotoPacket; +import org.cloudburstmc.protocol.bedrock.packet.DebugInfoPacket; +import org.cloudburstmc.protocol.bedrock.packet.DisconnectPacket; +import org.cloudburstmc.protocol.bedrock.packet.EditorNetworkPacket; +import org.cloudburstmc.protocol.bedrock.packet.EntityFallPacket; +import org.cloudburstmc.protocol.bedrock.packet.GameTestRequestPacket; +import org.cloudburstmc.protocol.bedrock.packet.InventoryContentPacket; +import org.cloudburstmc.protocol.bedrock.packet.InventorySlotPacket; +import org.cloudburstmc.protocol.bedrock.packet.LabTablePacket; +import org.cloudburstmc.protocol.bedrock.packet.MapCreateLockedCopyPacket; +import org.cloudburstmc.protocol.bedrock.packet.MapInfoRequestPacket; +import org.cloudburstmc.protocol.bedrock.packet.MobArmorEquipmentPacket; +import org.cloudburstmc.protocol.bedrock.packet.MobEquipmentPacket; +import org.cloudburstmc.protocol.bedrock.packet.MultiplayerSettingsPacket; +import org.cloudburstmc.protocol.bedrock.packet.NpcRequestPacket; +import org.cloudburstmc.protocol.bedrock.packet.PhotoInfoRequestPacket; +import org.cloudburstmc.protocol.bedrock.packet.PhotoTransferPacket; +import org.cloudburstmc.protocol.bedrock.packet.PlayerAuthInputPacket; +import org.cloudburstmc.protocol.bedrock.packet.PlayerHotbarPacket; +import org.cloudburstmc.protocol.bedrock.packet.PlayerSkinPacket; +import org.cloudburstmc.protocol.bedrock.packet.PurchaseReceiptPacket; +import org.cloudburstmc.protocol.bedrock.packet.RefreshEntitlementsPacket; +import org.cloudburstmc.protocol.bedrock.packet.ScriptMessagePacket; +import org.cloudburstmc.protocol.bedrock.packet.SetEntityDataPacket; +import org.cloudburstmc.protocol.bedrock.packet.SetEntityLinkPacket; +import org.cloudburstmc.protocol.bedrock.packet.SetEntityMotionPacket; +import org.cloudburstmc.protocol.bedrock.packet.SettingsCommandPacket; +import org.cloudburstmc.protocol.bedrock.packet.SimpleEventPacket; +import org.cloudburstmc.protocol.bedrock.packet.SubChunkRequestPacket; +import org.cloudburstmc.protocol.bedrock.packet.SubClientLoginPacket; +import org.cloudburstmc.protocol.bedrock.packet.TickSyncPacket; +import org.cloudburstmc.protocol.common.util.VarInts; + +/** + * Processes the Bedrock codec to remove or modify unused or unsafe packets and fields. + */ +class CodecProcessor { + + /** + * Generic serializer that throws an exception when trying to serialize or deserialize a packet, leading to client disconnection. + */ + @SuppressWarnings("rawtypes") + private static final BedrockPacketSerializer ILLEGAL_SERIALIZER = new BedrockPacketSerializer<>() { + @Override + public void serialize(ByteBuf buffer, BedrockCodecHelper helper, BedrockPacket packet) { + throw new IllegalArgumentException("Server tried to send unused packet " + packet.getClass().getSimpleName() + "!"); + } + + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, BedrockPacket packet) { + throw new IllegalArgumentException("Client tried to send unused packet " + packet.getClass().getSimpleName() + "!"); + } + }; + + /** + * Generic serializer that does nothing when trying to serialize or deserialize a packet. + */ + @SuppressWarnings("rawtypes") + private static final BedrockPacketSerializer IGNORED_SERIALIZER = new BedrockPacketSerializer<>() { + @Override + public void serialize(ByteBuf buffer, BedrockCodecHelper helper, BedrockPacket packet) { + } + + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, BedrockPacket packet) { + } + }; + + /** + * Serializer that throws an exception when trying to deserialize InventoryContentPacket since server-auth inventory is used. + */ + private static final BedrockPacketSerializer INVENTORY_CONTENT_SERIALIZER = new InventoryContentSerializer_v407() { + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, InventoryContentPacket packet) { + throw new IllegalArgumentException("Client cannot send InventoryContentPacket in server-auth inventory environment!"); + } + }; + + /** + * Serializer that throws an exception when trying to deserialize InventorySlotPacket since server-auth inventory is used. + */ + private static final BedrockPacketSerializer INVENTORY_SLOT_SERIALIZER = new InventorySlotSerializer_v407() { + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, InventorySlotPacket packet) { + throw new IllegalArgumentException("Client cannot send InventorySlotPacket in server-auth inventory environment!"); + } + }; + + /** + * Serializer that does nothing when trying to deserialize BossEventPacket since it is not used from the client. + */ + private static final BedrockPacketSerializer BOSS_EVENT_SERIALIZER = new BossEventSerializer_v486() { + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, BossEventPacket packet) { + } + }; + + /** + * Serializer that does nothing when trying to deserialize MobArmorEquipmentPacket since it is not used from the client. + */ + private static final BedrockPacketSerializer MOB_ARMOR_EQUIPMENT_SERIALIZER = new MobArmorEquipmentSerializer_v291() { + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, MobArmorEquipmentPacket packet) { + } + }; + + /** + * Serializer that does nothing when trying to deserialize PlayerHotbarPacket since it is not used from the client. + */ + private static final BedrockPacketSerializer PLAYER_HOTBAR_SERIALIZER = new PlayerHotbarSerializer_v291() { + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, PlayerHotbarPacket packet) { + } + }; + + /** + * Serializer that does nothing when trying to deserialize PlayerSkinPacket since it is not used from the client. + */ + private static final BedrockPacketSerializer PLAYER_SKIN_SERIALIZER = new PlayerSkinSerializer_v390() { + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, PlayerSkinPacket packet) { + } + }; + + /** + * Serializer that does nothing when trying to deserialize SetEntityDataPacket since it is not used from the client. + */ + private static final BedrockPacketSerializer SET_ENTITY_DATA_SERIALIZER = new SetEntityDataSerializer_v557() { + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, SetEntityDataPacket packet) { + } + }; + + /** + * Serializer that does nothing when trying to deserialize SetEntityMotionPacket since it is not used from the client. + */ + private static final BedrockPacketSerializer SET_ENTITY_MOTION_SERIALIZER = new SetEntityMotionSerializer_v662() { + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, SetEntityMotionPacket packet) { + } + }; + + /** + * Serializer that does nothing when trying to deserialize SetEntityLinkPacket since it is not used from the client. + */ + private static final BedrockPacketSerializer SET_ENTITY_LINK_SERIALIZER = new SetEntityLinkSerializer_v291() { + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, SetEntityLinkPacket packet) { + } + }; + + /** + * Serializer that skips over the item when trying to deserialize MobEquipmentPacket since only the slot info is used. + */ + private static final BedrockPacketSerializer MOB_EQUIPMENT_SERIALIZER = new MobEquipmentSerializer_v291() { + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, MobEquipmentPacket packet) { + packet.setRuntimeEntityId(VarInts.readUnsignedLong(buffer)); + fakeItemRead(buffer); + packet.setInventorySlot(buffer.readUnsignedByte()); + packet.setHotbarSlot(buffer.readUnsignedByte()); + packet.setContainerId(buffer.readByte()); + } + }; + + @SuppressWarnings("unchecked") + static BedrockCodec processCodec(BedrockCodec codec) { + return codec.toBuilder() + // Illegal unused serverbound EDU packets + .updateSerializer(PhotoTransferPacket.class, ILLEGAL_SERIALIZER) + .updateSerializer(LabTablePacket.class, ILLEGAL_SERIALIZER) + .updateSerializer(CodeBuilderSourcePacket.class, ILLEGAL_SERIALIZER) + .updateSerializer(CreatePhotoPacket.class, ILLEGAL_SERIALIZER) + .updateSerializer(NpcRequestPacket.class, ILLEGAL_SERIALIZER) + .updateSerializer(PhotoInfoRequestPacket.class, ILLEGAL_SERIALIZER) + // Illegal unused serverbound packets for featured servers + .updateSerializer(PurchaseReceiptPacket.class, ILLEGAL_SERIALIZER) + // Illegal unused serverbound packets that are deprecated + .updateSerializer(ClientCheatAbilityPacket.class, ILLEGAL_SERIALIZER) + // Illegal unusued serverbound packets that relate to unused features + .updateSerializer(PlayerAuthInputPacket.class, ILLEGAL_SERIALIZER) + .updateSerializer(ClientCacheBlobStatusPacket.class, ILLEGAL_SERIALIZER) + .updateSerializer(SubClientLoginPacket.class, ILLEGAL_SERIALIZER) + .updateSerializer(SubChunkRequestPacket.class, ILLEGAL_SERIALIZER) + .updateSerializer(GameTestRequestPacket.class, ILLEGAL_SERIALIZER) + // Ignored serverbound packets + .updateSerializer(CraftingEventPacket.class, IGNORED_SERIALIZER) // Make illegal when 1.20.40 is removed + .updateSerializer(ClientToServerHandshakePacket.class, IGNORED_SERIALIZER) + .updateSerializer(EntityFallPacket.class, IGNORED_SERIALIZER) + .updateSerializer(MapCreateLockedCopyPacket.class, IGNORED_SERIALIZER) + .updateSerializer(MapInfoRequestPacket.class, IGNORED_SERIALIZER) + .updateSerializer(SettingsCommandPacket.class, IGNORED_SERIALIZER) + .updateSerializer(AnvilDamagePacket.class, IGNORED_SERIALIZER) + .updateSerializer(RefreshEntitlementsPacket.class, IGNORED_SERIALIZER) + // Illegal when serverbound due to Geyser specific setup + .updateSerializer(InventoryContentPacket.class, INVENTORY_CONTENT_SERIALIZER) + .updateSerializer(InventorySlotPacket.class, INVENTORY_SLOT_SERIALIZER) + // Ignored only when serverbound + .updateSerializer(BossEventPacket.class, BOSS_EVENT_SERIALIZER) + .updateSerializer(MobArmorEquipmentPacket.class, MOB_ARMOR_EQUIPMENT_SERIALIZER) + .updateSerializer(PlayerHotbarPacket.class, PLAYER_HOTBAR_SERIALIZER) + .updateSerializer(PlayerSkinPacket.class, PLAYER_SKIN_SERIALIZER) + .updateSerializer(SetEntityDataPacket.class, SET_ENTITY_DATA_SERIALIZER) + .updateSerializer(SetEntityMotionPacket.class, SET_ENTITY_MOTION_SERIALIZER) + .updateSerializer(SetEntityLinkPacket.class, SET_ENTITY_LINK_SERIALIZER) + // Valid serverbound packets where reading of some fields can be skipped + .updateSerializer(MobEquipmentPacket.class, MOB_EQUIPMENT_SERIALIZER) + // // Illegal bidirectional packets + .updateSerializer(DebugInfoPacket.class, ILLEGAL_SERIALIZER) + .updateSerializer(EditorNetworkPacket.class, ILLEGAL_SERIALIZER) + .updateSerializer(ScriptMessagePacket.class, ILLEGAL_SERIALIZER) + // // Ignored bidirectional packets + .updateSerializer(ClientCacheStatusPacket.class, IGNORED_SERIALIZER) + .updateSerializer(DisconnectPacket.class, IGNORED_SERIALIZER) + .updateSerializer(SimpleEventPacket.class, IGNORED_SERIALIZER) + .updateSerializer(TickSyncPacket.class, IGNORED_SERIALIZER) + .updateSerializer(MultiplayerSettingsPacket.class, IGNORED_SERIALIZER) + .build(); + } + + /** + * Fake reading an item from the buffer to improve performance. + * + * @param buffer + */ + private static void fakeItemRead(ByteBuf buffer) { + int id = VarInts.readInt(buffer); // Runtime ID + if (id == 0) { // nothing more to read + return; + } + buffer.skipBytes(2); // count + VarInts.readUnsignedInt(buffer); // damage + boolean hasNetId = buffer.readBoolean(); + if (hasNetId) { + VarInts.readInt(buffer); + } + + VarInts.readInt(buffer); // Block runtime ID + int streamSize = VarInts.readUnsignedInt(buffer); + buffer.skipBytes(streamSize); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java index f43706db0..b5fc4440c 100644 --- a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java +++ b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java @@ -27,17 +27,14 @@ package org.geysermc.geyser.network; import com.github.steveice10.mc.protocol.codec.MinecraftCodec; import com.github.steveice10.mc.protocol.codec.PacketCodec; -import io.netty.buffer.ByteBuf; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec; -import org.cloudburstmc.protocol.bedrock.codec.BedrockCodecHelper; -import org.cloudburstmc.protocol.bedrock.codec.v582.serializer.TrimDataSerializer_v582; import org.cloudburstmc.protocol.bedrock.codec.v622.Bedrock_v622; import org.cloudburstmc.protocol.bedrock.codec.v630.Bedrock_v630; import org.cloudburstmc.protocol.bedrock.codec.v649.Bedrock_v649; import org.cloudburstmc.protocol.bedrock.codec.v662.Bedrock_v662; +import org.cloudburstmc.protocol.bedrock.codec.v671.Bedrock_v671; import org.cloudburstmc.protocol.bedrock.netty.codec.packet.BedrockPacketCodec; -import org.cloudburstmc.protocol.bedrock.packet.TrimDataPacket; import org.geysermc.geyser.session.GeyserSession; import java.util.ArrayList; @@ -48,11 +45,12 @@ import java.util.StringJoiner; * Contains information about the supported protocols in Geyser. */ public final class GameProtocol { + /** * Default Bedrock codec that should act as a fallback. Should represent the latest available * release of the game that Geyser supports. */ - public static final BedrockCodec DEFAULT_BEDROCK_CODEC = processCodec(Bedrock_v662.CODEC); + public static final BedrockCodec DEFAULT_BEDROCK_CODEC = CodecProcessor.processCodec(Bedrock_v671.CODEC); /** * A list of all supported Bedrock versions that can join Geyser @@ -66,18 +64,21 @@ public final class GameProtocol { private static final PacketCodec DEFAULT_JAVA_CODEC = MinecraftCodec.CODEC; static { - SUPPORTED_BEDROCK_CODECS.add(processCodec(Bedrock_v622.CODEC.toBuilder() + SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v622.CODEC.toBuilder() .minecraftVersion("1.20.40/1.20.41") .build())); - SUPPORTED_BEDROCK_CODECS.add(processCodec(Bedrock_v630.CODEC.toBuilder() + SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v630.CODEC.toBuilder() .minecraftVersion("1.20.50/1.20.51") .build())); - SUPPORTED_BEDROCK_CODECS.add(processCodec(Bedrock_v649.CODEC.toBuilder() + SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v649.CODEC.toBuilder() .minecraftVersion("1.20.60/1.20.62") .build())); - SUPPORTED_BEDROCK_CODECS.add(processCodec(DEFAULT_BEDROCK_CODEC.toBuilder() + SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v662.CODEC.toBuilder() .minecraftVersion("1.20.70/1.20.73") .build())); + SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(DEFAULT_BEDROCK_CODEC.toBuilder() + .minecraftVersion("1.20.80") + .build())); } /** @@ -168,16 +169,6 @@ public final class GameProtocol { return joiner.toString(); } - private static BedrockCodec processCodec(BedrockCodec codec) { - return codec.toBuilder() - .updateSerializer(TrimDataPacket.class, new TrimDataSerializer_v582() { - @Override - public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, TrimDataPacket packet) { - } - }) - .build(); - } - private GameProtocol() { } } diff --git a/core/src/main/java/org/geysermc/geyser/network/GeyserServerInitializer.java b/core/src/main/java/org/geysermc/geyser/network/GeyserServerInitializer.java index bb8e87440..662e2f4c7 100644 --- a/core/src/main/java/org/geysermc/geyser/network/GeyserServerInitializer.java +++ b/core/src/main/java/org/geysermc/geyser/network/GeyserServerInitializer.java @@ -25,12 +25,16 @@ package org.geysermc.geyser.network; +import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; import io.netty.channel.DefaultEventLoopGroup; +import io.netty.channel.SimpleChannelInboundHandler; import io.netty.util.concurrent.DefaultThreadFactory; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.BedrockPeer; import org.cloudburstmc.protocol.bedrock.BedrockServerSession; +import org.cloudburstmc.protocol.bedrock.netty.codec.packet.BedrockPacketCodec; import org.cloudburstmc.protocol.bedrock.netty.initializer.BedrockServerInitializer; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.event.bedrock.SessionInitializeEvent; @@ -63,6 +67,10 @@ public class GeyserServerInitializer extends BedrockServerInitializer { bedrockServerSession.setLogging(true); GeyserSession session = new GeyserSession(this.geyser, bedrockServerSession, this.eventLoopGroup.next()); + + Channel channel = bedrockServerSession.getPeer().getChannel(); + channel.pipeline().addAfter(BedrockPacketCodec.NAME, InvalidPacketHandler.NAME, new InvalidPacketHandler(session)); + bedrockServerSession.setPacketHandler(new UpstreamPacketHandler(this.geyser, session)); this.geyser.eventBus().fire(new SessionInitializeEvent(session)); } catch (Throwable e) { diff --git a/core/src/main/java/org/geysermc/geyser/network/InvalidPacketHandler.java b/core/src/main/java/org/geysermc/geyser/network/InvalidPacketHandler.java new file mode 100644 index 000000000..3e836711b --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/network/InvalidPacketHandler.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.network; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import lombok.RequiredArgsConstructor; +import org.geysermc.geyser.session.GeyserSession; + +import java.util.stream.Stream; + +@RequiredArgsConstructor +public class InvalidPacketHandler extends ChannelInboundHandlerAdapter { + public static final String NAME = "rak-error-handler"; + + private final GeyserSession session; + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + Throwable rootCause = Stream.iterate(cause, Throwable::getCause) + .filter(element -> element.getCause() == null) + .findFirst() + .orElse(cause); + + + if (!(rootCause instanceof IllegalArgumentException)) { + super.exceptionCaught(ctx, cause); + return; + } + + // Kick users that try to send illegal packets + session.getGeyser().getLogger().warning(rootCause.getMessage()); + session.disconnect("Invalid packet received!"); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java index c54431fbe..e76edc059 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java @@ -43,6 +43,7 @@ import org.cloudburstmc.protocol.bedrock.codec.v622.Bedrock_v622; import org.cloudburstmc.protocol.bedrock.codec.v630.Bedrock_v630; import org.cloudburstmc.protocol.bedrock.codec.v649.Bedrock_v649; import org.cloudburstmc.protocol.bedrock.codec.v662.Bedrock_v662; +import org.cloudburstmc.protocol.bedrock.codec.v671.Bedrock_v671; import org.cloudburstmc.protocol.bedrock.data.BlockPropertyData; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.geysermc.geyser.GeyserImpl; @@ -122,7 +123,8 @@ public final class BlockRegistryPopulator { .put(ObjectIntPair.of("1_20_50", Bedrock_v630.CODEC.getProtocolVersion()), Conversion649_630::remapBlock) // Only changes in 1.20.60 are hard_stained_glass (an EDU only block) .put(ObjectIntPair.of("1_20_60", Bedrock_v649.CODEC.getProtocolVersion()), Conversion662_649::remapBlock) - .put(ObjectIntPair.of("1_20_70", Bedrock_v662.CODEC.getProtocolVersion()), tag -> tag) + .put(ObjectIntPair.of("1_20_70", Bedrock_v662.CODEC.getProtocolVersion()), Conversion671_662::remapBlock) + .put(ObjectIntPair.of("1_20_80", Bedrock_v671.CODEC.getProtocolVersion()), tag -> tag) .build(); // We can keep this strong as nothing should be garbage collected diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java index cddeae7bf..0fe1610f2 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java @@ -44,6 +44,8 @@ public class Conversion662_649 { static GeyserMappingItem remapItem(@SuppressWarnings("unused") Item item, GeyserMappingItem mapping) { + mapping = Conversion671_662.remapItem(item, mapping); + String identifer = mapping.getBedrockIdentifier(); if (identifer.equals("minecraft:grass_block")) { @@ -93,6 +95,8 @@ public class Conversion662_649 { } static NbtMap remapBlock(NbtMap tag) { + tag = Conversion671_662.remapBlock(tag); + final String name = tag.getString("name"); if (!NEW_BLOCKS.contains(name)) { diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion671_662.java b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion671_662.java new file mode 100644 index 000000000..2c6db7567 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion671_662.java @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.registry.populator; + +import org.cloudburstmc.nbt.NbtMap; +import org.geysermc.geyser.item.type.Item; +import org.geysermc.geyser.registry.type.GeyserMappingItem; + +import java.util.List; +import java.util.stream.Stream; + +public class Conversion671_662 { + private static final List NEW_CORAL_FANS = List.of("minecraft:tube_coral_fan", "minecraft:brain_coral_fan", "minecraft:bubble_coral_fan", "minecraft:fire_coral_fan", "minecraft:horn_coral_fan"); + private static final List NEW_DEAD_CORAL_FANS = List.of("minecraft:dead_tube_coral_fan", "minecraft:dead_brain_coral_fan", "minecraft:dead_bubble_coral_fan", "minecraft:dead_fire_coral_fan", "minecraft:dead_horn_coral_fan"); + private static final List NEW_FLOWERS = List.of("minecraft:poppy", "minecraft:blue_orchid", "minecraft:allium", "minecraft:azure_bluet", "minecraft:red_tulip", "minecraft:orange_tulip", "minecraft:white_tulip", "minecraft:pink_tulip", "minecraft:oxeye_daisy", "minecraft:cornflower", "minecraft:lily_of_the_valley"); + private static final List NEW_SAPLINGS = List.of("minecraft:oak_sapling", "minecraft:spruce_sapling", "minecraft:birch_sapling", "minecraft:jungle_sapling", "minecraft:acacia_sapling", "minecraft:dark_oak_sapling", "minecraft:bamboo_sapling"); + private static final List NEW_BLOCKS = Stream.of(NEW_CORAL_FANS, NEW_DEAD_CORAL_FANS, NEW_FLOWERS, NEW_SAPLINGS).flatMap(List::stream).toList(); + + static GeyserMappingItem remapItem(@SuppressWarnings("unused") Item item, GeyserMappingItem mapping) { + String identifer = mapping.getBedrockIdentifier(); + + if (!NEW_BLOCKS.contains(identifer)) { + return mapping; + } + + if (NEW_FLOWERS.contains(identifer)) { + switch (identifer) { + case "minecraft:poppy" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(0); } + case "minecraft:blue_orchid" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(1); } + case "minecraft:allium" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(2); } + case "minecraft:azure_bluet" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(3); } + case "minecraft:red_tulip" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(4); } + case "minecraft:orange_tulip" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(5); } + case "minecraft:white_tulip" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(6); } + case "minecraft:pink_tulip" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(7); } + case "minecraft:oxeye_daisy" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(8); } + case "minecraft:cornflower" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(9); } + case "minecraft:lily_of_the_valley" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(10); } + } + } + + if (NEW_SAPLINGS.contains(identifer)) { + switch (identifer) { + case "minecraft:oak_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(0); } + case "minecraft:spruce_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(1); } + case "minecraft:birch_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(2); } + case "minecraft:jungle_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(3); } + case "minecraft:acacia_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(4); } + case "minecraft:dark_oak_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(5); } + } + } + + if (NEW_CORAL_FANS.contains(identifer)) { + switch (identifer) { + case "minecraft:tube_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan").withBedrockData(0); } + case "minecraft:brain_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan").withBedrockData(1); } + case "minecraft:bubble_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan").withBedrockData(2); } + case "minecraft:fire_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan").withBedrockData(3); } + case "minecraft:horn_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan").withBedrockData(4); } + } + } + + if (NEW_DEAD_CORAL_FANS.contains(identifer)) { + switch (identifer) { + case "minecraft:dead_tube_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan_dead").withBedrockData(0); } + case "minecraft:dead_brain_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan_dead").withBedrockData(1); } + case "minecraft:dead_bubble_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan_dead").withBedrockData(2); } + case "minecraft:dead_fire_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan_dead").withBedrockData(3); } + case "minecraft:dead_horn_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan_dead").withBedrockData(4); } + } + } + + return mapping; + } + + static NbtMap remapBlock(NbtMap tag) { + final String name = tag.getString("name"); + + if (!NEW_BLOCKS.contains(name)) { + return tag; + } + + if (name.equals("minecraft:bamboo_sapling")) { + NbtMap states = tag.getCompound("states") + .toBuilder() + .putString("sapling_type", "oak") + .build(); + + return tag.toBuilder().putCompound("states", states).build(); + } + + String replacement; + + if (NEW_SAPLINGS.contains(name)) { + replacement = "minecraft:sapling"; + String saplingType = name.replaceAll("minecraft:|_sapling", "");; + + NbtMap states = tag.getCompound("states") + .toBuilder() + .putString("sapling_type", saplingType) + .build(); + + return tag.toBuilder().putString("name", replacement).putCompound("states", states).build(); + } + + if (NEW_FLOWERS.contains(name)) { + replacement = "minecraft:red_flower"; + String flowerType; + + switch (name) { + case "minecraft:poppy" -> flowerType = "poppy"; + case "minecraft:blue_orchid" -> flowerType = "orchid"; + case "minecraft:allium" -> flowerType = "allium"; + case "minecraft:azure_bluet" -> flowerType = "houstonia"; + case "minecraft:red_tulip" -> flowerType = "tulip_red"; + case "minecraft:orange_tulip" -> flowerType = "tulip_orange"; + case "minecraft:white_tulip" -> flowerType = "tulip_white"; + case "minecraft:pink_tulip" -> flowerType = "tulip_pink"; + case "minecraft:oxeye_daisy" -> flowerType = "oxeye"; + case "minecraft:cornflower" -> flowerType = "cornflower"; + case "minecraft:lily_of_the_valley" -> flowerType = "lily_of_the_valley"; + default -> throw new IllegalStateException("Unexpected value: " + name); + } + + NbtMap states = tag.getCompound("states") + .toBuilder() + .putString("flower_type", flowerType) + .build(); + + return tag.toBuilder().putString("name", replacement).putCompound("states", states).build(); + } + + boolean isLiveCoralFan = NEW_CORAL_FANS.contains(name); + boolean isDeadCoralFan = NEW_DEAD_CORAL_FANS.contains(name); + + if (isLiveCoralFan || isDeadCoralFan) { + replacement = isLiveCoralFan ? "minecraft:coral_fan" : "minecraft:coral_fan_dead"; + String coralColor; + + switch (name) { + case "minecraft:tube_coral_fan", "minecraft:dead_tube_coral_fan" -> coralColor = "blue"; + case "minecraft:brain_coral_fan", "minecraft:dead_brain_coral_fan" -> coralColor = "pink"; + case "minecraft:bubble_coral_fan", "minecraft:dead_bubble_coral_fan" -> coralColor = "purple"; + case "minecraft:fire_coral_fan", "minecraft:dead_fire_coral_fan" -> coralColor = "yellow"; + case "minecraft:horn_coral_fan", "minecraft:dead_horn_coral_fan" -> coralColor = "red"; + default -> throw new IllegalStateException("Unexpected value: " + name); + } + + NbtMap states = tag.getCompound("states") + .toBuilder() + .putString("coral_color", coralColor) + .build(); + + return tag.toBuilder().putString("name", replacement).putCompound("states", states).build(); + } + + return tag; + } +} \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java index 708f92dc5..5b64da7a1 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java @@ -42,6 +42,7 @@ import org.cloudburstmc.protocol.bedrock.codec.v622.Bedrock_v622; import org.cloudburstmc.protocol.bedrock.codec.v630.Bedrock_v630; import org.cloudburstmc.protocol.bedrock.codec.v649.Bedrock_v649; import org.cloudburstmc.protocol.bedrock.codec.v662.Bedrock_v662; +import org.cloudburstmc.protocol.bedrock.codec.v671.Bedrock_v671; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; @@ -93,7 +94,8 @@ public class ItemRegistryPopulator { paletteVersions.add(new PaletteVersion("1_20_40", Bedrock_v622.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion630_622::remapItem)); paletteVersions.add(new PaletteVersion("1_20_50", Bedrock_v630.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion649_630::remapItem)); paletteVersions.add(new PaletteVersion("1_20_60", Bedrock_v649.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion662_649::remapItem)); - paletteVersions.add(new PaletteVersion("1_20_70", Bedrock_v662.CODEC.getProtocolVersion())); + paletteVersions.add(new PaletteVersion("1_20_70", Bedrock_v662.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion671_662::remapItem)); + paletteVersions.add(new PaletteVersion("1_20_80", Bedrock_v671.CODEC.getProtocolVersion())); GeyserBootstrap bootstrap = GeyserImpl.getInstance().getBootstrap(); diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java index f8929c900..5e4d5fc7a 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java @@ -173,7 +173,7 @@ public class RecipeRegistryPopulator { /* Convert end */ return ShapedRecipeData.shaped(uuid.toString(), shape.get(0).length(), shape.size(), - inputs.stream().map(ItemDescriptorWithCount::fromItem).toList(), Collections.singletonList(output), uuid, "crafting_table", 0, netId); + inputs.stream().map(ItemDescriptorWithCount::fromItem).toList(), Collections.singletonList(output), uuid, "crafting_table", 0, netId, false); } List inputs = new ObjectArrayList<>(); for (JsonNode entry : node.get("inputs")) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java index 7beb37af9..94c69b780 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java @@ -162,7 +162,7 @@ public class JavaUpdateRecipesTranslator extends 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 literal 0 HcmV?d00001 diff --git a/core/src/main/resources/bedrock/creative_items.1_20_80.json b/core/src/main/resources/bedrock/creative_items.1_20_80.json new file mode 100644 index 000000000..02feea34b --- /dev/null +++ b/core/src/main/resources/bedrock/creative_items.1_20_80.json @@ -0,0 +1,5812 @@ +{ + "items": [ + { + "id": "minecraft:oak_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQFAAAACAQAbmFtZRQAbWluZWNyYWZ0Om9ha19wbGFua3MECQBuYW1lX2hhc2ilMDLR92rQ4wMKAG5ldHdvcmtfaWS2GotyCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:spruce_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTiAwAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9wbGFua3MECQBuYW1lX2hhc2iumBkmFGFE8gMKAG5ldHdvcmtfaWSo8TFgCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:birch_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTjAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX3BsYW5rcwQJAG5hbWVfaGFzaLrrAKJqV2WFAwoAbmV0d29ya19pZL+e3ZAKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:jungle_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTkAwAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9wbGFua3MECQBuYW1lX2hhc2iBM3k4T3FAugMKAG5ldHdvcmtfaWSXUmBCCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:acacia_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTlAwAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9wbGFua3MECQBuYW1lX2hhc2g60edJxO5/aAMKAG5ldHdvcmtfaWTUXozECgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:dark_oak_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTmAwAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX3BsYW5rcwQJAG5hbWVfaGFzaAr64wkQ9cA7AwoAbmV0d29ya19pZFbMeR0KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:mangrove_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTlAgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX3BsYW5rcwQJAG5hbWVfaGFzaPvLtcEA0F8xAwoAbmV0d29ya19pZEvnlCYKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cherry_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAwAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9wbGFua3MECQBuYW1lX2hhc2hNIvVh/lVW7gMKAG5ldHdvcmtfaWQTXpRoCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:bamboo_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT9AgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19wbGFua3MECQBuYW1lX2hhc2gYnjNz7SCCjgMKAG5ldHdvcmtfaWTi8ySSCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:bamboo_mosaic", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT8AgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19tb3NhaWMECQBuYW1lX2hhc2izSEgiMKOp/AMKAG5ldHdvcmtfaWQZ/p8xCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:crimson_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTxAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fcGxhbmtzBAkAbmFtZV9oYXNoJc5IKqNXJnwDCgBuZXR3b3JrX2lkwtJDdQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:warped_planks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTyAQAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9wbGFua3MECQBuYW1lX2hhc2g3yGXEWhe6LgMKAG5ldHdvcmtfaWStTABvCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWSE4JosCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCwBjb2JibGVzdG9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWTUvV6XCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlEQBtb3NzeV9jb2JibGVzdG9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWT4opb2CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlBwBncmFuaXRlCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQAMQTVCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlBwBkaW9yaXRlCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQIbDOcCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCABhbmRlc2l0ZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWSZKhusCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCQBzYW5kc3RvbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWSp4zgCCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlDQByZWRfc2FuZHN0b25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRbqVHTCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCwBzdG9uZV9icmljawgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRr0ZT/CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlEQBtb3NzeV9zdG9uZV9icmljawgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRnLis3CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlBQBicmljawgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQNLzfSCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlDABuZXRoZXJfYnJpY2sIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQ5h0xwCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlEAByZWRfbmV0aGVyX2JyaWNrCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWS9J0B2CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCQBlbmRfYnJpY2sIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cobblestone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRPbkJeCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCgBwcmlzbWFyaW5lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:blackstone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQUAgAACAQAbmFtZRkAbWluZWNyYWZ0OmJsYWNrc3RvbmVfd2FsbAQJAG5hbWVfaGFzaMP8XppUSU1RAwoAbmV0d29ya19pZMbeBBsKBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:polished_blackstone_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQoAgAACAQAbmFtZSIAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfd2FsbAQJAG5hbWVfaGFzaP6SwV08YwzAAwoAbmV0d29ya19pZAJLsz8KBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:polished_blackstone_brick_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQVAgAACAQAbmFtZSgAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tfd2FsbAQJAG5hbWVfaGFzaBBIDZbHxiEzAwoAbmV0d29ya19pZEbLV8cKBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cobbled_deepslate_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR9AgAACAQAbmFtZSAAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlX3dhbGwECQBuYW1lX2hhc2iECY5oKxeT+gMKAG5ldHdvcmtfaWRCnPrFCgYAc3RhdGVzCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:deepslate_tile_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAgAACAQAbmFtZR0AbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlX3dhbGwECQBuYW1lX2hhc2jz7N+PeuEXgQMKAG5ldHdvcmtfaWTqw4s4CgYAc3RhdGVzCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:polished_deepslate_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSBAgAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZV93YWxsBAkAbmFtZV9oYXNoHxjTdj9pevMDCgBuZXR3b3JrX2lkIvBYYwoGAHN0YXRlcwgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:deepslate_brick_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSJAgAACAQAbmFtZR4AbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja193YWxsBAkAbmFtZV9oYXNoEs3EQrjroyEDCgBuZXR3b3JrX2lkwlrCGwoGAHN0YXRlcwgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:mud_brick_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTgAgAACAQAbmFtZRgAbWluZWNyYWZ0Om11ZF9icmlja193YWxsBAkAbmFtZV9oYXNov9b98ATpUSwDCgBuZXR3b3JrX2lkH/1WZQoGAHN0YXRlcwgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:oak_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRVAAAACAQAbmFtZRMAbWluZWNyYWZ0Om9ha19mZW5jZQQJAG5hbWVfaGFzaGEmid7AaCWRAwoAbmV0d29ya19pZDvPEXcKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:spruce_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRCAwAACAQAbmFtZRYAbWluZWNyYWZ0OnNwcnVjZV9mZW5jZQQJAG5hbWVfaGFzaPQCm+aX1ZQeAwoAbmV0d29ya19pZD1QUEoKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:birch_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ/AwAACAQAbmFtZRUAbWluZWNyYWZ0OmJpcmNoX2ZlbmNlBAkAbmFtZV9oYXNo6CJ2ATpANfgDCgBuZXR3b3JrX2lkmCUV2QoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:jungle_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRBAwAACAQAbmFtZRYAbWluZWNyYWZ0Omp1bmdsZV9mZW5jZQQJAG5hbWVfaGFzaOX4cD9uAmsdAwoAbmV0d29ya19pZHz1VxkKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:acacia_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ+AwAACAQAbmFtZRYAbWluZWNyYWZ0OmFjYWNpYV9mZW5jZQQJAG5hbWVfaGFzaGjn+RlKVDH6AwoAbmV0d29ya19pZNVGubwKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:dark_oak_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRAAwAACAQAbmFtZRgAbWluZWNyYWZ0OmRhcmtfb2FrX2ZlbmNlBAkAbmFtZV9oYXNoGPj0gCgM0c0DCgBuZXR3b3JrX2lk2w+gEwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:mangrove_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTqAgAACAQAbmFtZRgAbWluZWNyYWZ0Om1hbmdyb3ZlX2ZlbmNlBAkAbmFtZV9oYXNowwAd7tPu9bsDCgBuZXR3b3JrX2lkKEcd0goGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cherry_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQTAwAACAQAbmFtZRYAbWluZWNyYWZ0OmNoZXJyeV9mZW5jZQQJAG5hbWVfaGFzaFmtUfHfTxcxAwoAbmV0d29ya19pZPCBxAIKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:bamboo_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQCAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJhbWJvb19mZW5jZQQJAG5hbWVfaGFzaCKRbxfXsfkiAwoAbmV0d29ya19pZJNXKFcKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:nether_brick_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRxAAAACAQAbmFtZRwAbWluZWNyYWZ0Om5ldGhlcl9icmlja19mZW5jZQQJAG5hbWVfaGFzaA6030ngawxcAwoAbmV0d29ya19pZLnjLF4KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:crimson_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT/AQAACAQAbmFtZRcAbWluZWNyYWZ0OmNyaW1zb25fZmVuY2UECQBuYW1lX2hhc2jhUhKv1HGj9AMKAG5ldHdvcmtfaWR3OH3OCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:warped_fence", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQAAgAACAQAbmFtZRYAbWluZWNyYWZ0OndhcnBlZF9mZW5jZQQJAG5hbWVfaGFzaJfb3/YuKmOWAwoAbmV0d29ya19pZCpaGC8KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRrAAAACAQAbmFtZRQAbWluZWNyYWZ0OmZlbmNlX2dhdGUECQBuYW1lX2hhc2hTxpjEDmRzAwMKAG5ldHdvcmtfaWR+T9kTCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:spruce_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS3AAAACAQAbmFtZRsAbWluZWNyYWZ0OnNwcnVjZV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoanTVB84HRbkDCgBuZXR3b3JrX2lkEnw5egoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:birch_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS4AAAACAQAbmFtZRoAbWluZWNyYWZ0OmJpcmNoX2ZlbmNlX2dhdGUECQBuYW1lX2hhc2jmfPklI8azSwMKAG5ldHdvcmtfaWQL77/BCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:jungle_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS5AAAACAQAbmFtZRsAbWluZWNyYWZ0Omp1bmdsZV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNobYVQkfBomIcDCgBuZXR3b3JrX2lkA1zgtgoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:acacia_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS7AAAACAQAbmFtZRsAbWluZWNyYWZ0OmFjYWNpYV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoZnrLUx/XSekDCgBuZXR3b3JrX2lkHg/kTgoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:dark_oak_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS6AAAACAQAbmFtZR0AbWluZWNyYWZ0OmRhcmtfb2FrX2ZlbmNlX2dhdGUECQBuYW1lX2hhc2j2PTvdJJHcVQMKAG5ldHdvcmtfaWTwjOCeCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:mangrove_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTrAgAACAQAbmFtZR0AbWluZWNyYWZ0Om1hbmdyb3ZlX2ZlbmNlX2dhdGUECQBuYW1lX2hhc2i/kOhBKiI/dAMKAG5ldHdvcmtfaWSfweCSCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cherry_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQUAwAACAQAbmFtZRsAbWluZWNyYWZ0OmNoZXJyeV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoKWLgCk0z+PsDCgBuZXR3b3JrX2lk/9bTZQoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:bamboo_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAwAACAQAbmFtZRsAbWluZWNyYWZ0OmJhbWJvb19mZW5jZV9nYXRlBAkAbmFtZV9oYXNopH1JrUgwdIADCgBuZXR3b3JrX2lkzIpPywoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:crimson_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQBAgAACAQAbmFtZRwAbWluZWNyYWZ0OmNyaW1zb25fZmVuY2VfZ2F0ZQQJAG5hbWVfaGFzaHE3Gfd0Z2d2AwoAbmV0d29ya19pZDQzVbEKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQsAaW5fd2FsbF9iaXQAAQgAb3Blbl9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:warped_fence_gate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQCAgAACAQAbmFtZRsAbWluZWNyYWZ0OndhcnBlZF9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoy0oIBjDIG4kDCgBuZXR3b3JrX2lkkf+/3QoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:normal_stone_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAQAACAQAbmFtZR0AbWluZWNyYWZ0Om5vcm1hbF9zdG9uZV9zdGFpcnMECQBuYW1lX2hhc2hAEktZZOkGIwMKAG5ldHdvcmtfaWQeH1ALCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stone_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRDAAAACAQAbmFtZRYAbWluZWNyYWZ0OnN0b25lX3N0YWlycwQJAG5hbWVfaGFzaNRjqVC5GRVDAwoAbmV0d29ya19pZDcCv+MKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:mossy_cobblestone_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSyAQAACAQAbmFtZSIAbWluZWNyYWZ0Om1vc3N5X2NvYmJsZXN0b25lX3N0YWlycwQJAG5hbWVfaGFzaMVSTq5z9n1RAwoAbmV0d29ya19pZFIfrhkKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:oak_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ1AAAACAQAbmFtZRQAbWluZWNyYWZ0Om9ha19zdGFpcnMECQBuYW1lX2hhc2jk/HFzdXy0FQMKAG5ldHdvcmtfaWQJjyzBCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:spruce_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSGAAAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9zdGFpcnMECQBuYW1lX2hhc2iznygw7uBPBQMKAG5ldHdvcmtfaWTv+is3CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:birch_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSHAAAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX3N0YWlycwQJAG5hbWVfaGFzaPfhbL619a3GAwoAbmV0d29ya19pZFyPlHAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:jungle_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSIAAAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9zdGFpcnMECQBuYW1lX2hhc2jodJsHUbOVxQMKAG5ldHdvcmtfaWR0z5d4CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:acacia_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSjAAAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9zdGFpcnMECQBuYW1lX2hhc2h3x1NmD43IqQMKAG5ldHdvcmtfaWS7Jwz6CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:dark_oak_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSkAAAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX3N0YWlycwQJAG5hbWVfaGFzaMfwkbYPbNmAAwoAbmV0d29ya19pZCmBYKAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:mangrove_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTnAgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX3N0YWlycwQJAG5hbWVfaGFzaNpUDY+uGMpyAwoAbmV0d29ya19pZChzUAsKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cherry_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQcAwAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9zdGFpcnMECQBuYW1lX2hhc2jMtr0v9JY4zwMKAG5ldHdvcmtfaWRQwq31CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:bamboo_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT/AgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19zdGFpcnMECQBuYW1lX2hhc2jFOzWL8PalKwMKAG5ldHdvcmtfaWTVPh42CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:bamboo_mosaic_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQKAwAACAQAbmFtZR4AbWluZWNyYWZ0OmJhbWJvb19tb3NhaWNfc3RhaXJzBAkAbmFtZV9oYXNoNLPiveSHPaoDCgBuZXR3b3JrX2lk44PHjgoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stone_brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRtAAAACAQAbmFtZRwAbWluZWNyYWZ0OnN0b25lX2JyaWNrX3N0YWlycwQJAG5hbWVfaGFzaN6tQViRo5cwAwoAbmV0d29ya19pZDMyMgIKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:mossy_stone_brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSuAQAACAQAbmFtZSIAbWluZWNyYWZ0Om1vc3N5X3N0b25lX2JyaWNrX3N0YWlycwQJAG5hbWVfaGFzaIB/Zv5YBPuYAwoAbmV0d29ya19pZANTOsMKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:sandstone_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSAAAAACAQAbmFtZRoAbWluZWNyYWZ0OnNhbmRzdG9uZV9zdGFpcnMECQBuYW1lX2hhc2hOyA0BoYUOPQMKAG5ldHdvcmtfaWSV/834CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:smooth_sandstone_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSwAQAACAQAbmFtZSEAbWluZWNyYWZ0OnNtb290aF9zYW5kc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNoB+CuCd8Ruz8DCgBuZXR3b3JrX2lksR+m8QoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:red_sandstone_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS0AAAACAQAbmFtZR4AbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNoPs0LpHPL24YDCgBuZXR3b3JrX2lkLYVt3woGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:smooth_red_sandstone_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAQAACAQAbmFtZSUAbWluZWNyYWZ0OnNtb290aF9yZWRfc2FuZHN0b25lX3N0YWlycwQJAG5hbWVfaGFzaBvjtQv5pf+MAwoAbmV0d29ya19pZMHNND8KBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:granite_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAQAACAQAbmFtZRgAbWluZWNyYWZ0OmdyYW5pdGVfc3RhaXJzBAkAbmFtZV9oYXNoGzpvtoqKQjgDCgBuZXR3b3JrX2lkPkcB1goGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:polished_granite_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSrAQAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2dyYW5pdGVfc3RhaXJzBAkAbmFtZV9oYXNo3PvbSfEQklIDCgBuZXR3b3JrX2lkMmEm3AoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:diorite_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSpAQAACAQAbmFtZRgAbWluZWNyYWZ0OmRpb3JpdGVfc3RhaXJzBAkAbmFtZV9oYXNoi73T8VQuZmcDCgBuZXR3b3JrX2lk6i6nBQoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:polished_diorite_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSsAQAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2Rpb3JpdGVfc3RhaXJzBAkAbmFtZV9oYXNoFKRJd5Wk5L0DCgBuZXR3b3JrX2lkbt2ioAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:andesite_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSqAQAACAQAbmFtZRkAbWluZWNyYWZ0OmFuZGVzaXRlX3N0YWlycwQJAG5hbWVfaGFzaO5w2FKBw76EAwoAbmV0d29ya19pZKhXEgUKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:polished_andesite_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWStAQAACAQAbmFtZSIAbWluZWNyYWZ0OnBvbGlzaGVkX2FuZGVzaXRlX3N0YWlycwQJAG5hbWVfaGFzaNcZZ/zmLInIAwoAbmV0d29ya19pZJTHrlEKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRsAAAACAQAbmFtZRYAbWluZWNyYWZ0OmJyaWNrX3N0YWlycwQJAG5hbWVfaGFzaMyt+cRDk5O2AwoAbmV0d29ya19pZNeMh58KBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:nether_brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRyAAAACAQAbmFtZR0AbWluZWNyYWZ0Om5ldGhlcl9icmlja19zdGFpcnMECQBuYW1lX2hhc2jRqIoOXgifBAMKAG5ldHdvcmtfaWQDiw5yCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:red_nether_brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS3AQAACAQAbmFtZSEAbWluZWNyYWZ0OnJlZF9uZXRoZXJfYnJpY2tfc3RhaXJzBAkAbmFtZV9oYXNogQvosSbcj7kDCgBuZXR3b3JrX2lkx2IMtAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:end_brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSxAQAACAQAbmFtZRoAbWluZWNyYWZ0OmVuZF9icmlja19zdGFpcnMECQBuYW1lX2hhc2hmlAk+QhsUsQMKAG5ldHdvcmtfaWTN7KFaCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:quartz_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWScAAAACAQAbmFtZRcAbWluZWNyYWZ0OnF1YXJ0el9zdGFpcnMECQBuYW1lX2hhc2hmvpvOqGi6egMKAG5ldHdvcmtfaWRmUTh7CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:smooth_quartz_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS4AQAACAQAbmFtZR4AbWluZWNyYWZ0OnNtb290aF9xdWFydHpfc3RhaXJzBAkAbmFtZV9oYXNoNZZ9rX0qZOsDCgBuZXR3b3JrX2lkzsgQyQoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:purpur_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTLAAAACAQAbmFtZRcAbWluZWNyYWZ0OnB1cnB1cl9zdGFpcnMECQBuYW1lX2hhc2ifwDxeezXD7gMKAG5ldHdvcmtfaWTT+rxiCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:prismarine_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQBAQAACAQAbmFtZRsAbWluZWNyYWZ0OnByaXNtYXJpbmVfc3RhaXJzBAkAbmFtZV9oYXNooTHSZ+IrYtcDCgBuZXR3b3JrX2lkxTJfeAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:dark_prismarine_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQCAQAACAQAbmFtZSAAbWluZWNyYWZ0OmRhcmtfcHJpc21hcmluZV9zdGFpcnMECQBuYW1lX2hhc2hIciLmam4o4AMKAG5ldHdvcmtfaWTVu7TCCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:prismarine_bricks_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAQAACAQAbmFtZSIAbWluZWNyYWZ0OnByaXNtYXJpbmVfYnJpY2tzX3N0YWlycwQJAG5hbWVfaGFzaNIjq1oBlZMMAwoAbmV0d29ya19pZGEFwLYKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:crimson_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT9AQAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fc3RhaXJzBAkAbmFtZV9oYXNoZJqIzCBpCq4DCgBuZXR3b3JrX2lktXE00AoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:warped_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT+AQAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9zdGFpcnMECQBuYW1lX2hhc2hOkY27jLD4RQMKAG5ldHdvcmtfaWQ+E5VrCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:blackstone_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQTAgAACAQAbmFtZRsAbWluZWNyYWZ0OmJsYWNrc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNokdoUb76p9McDCgBuZXR3b3JrX2lk5fWI5goGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:polished_blackstone_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQjAgAACAQAbmFtZSQAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNolCFtFIE8MmADCgBuZXR3b3JrX2lkGTf7sgoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:polished_blackstone_brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQSAgAACAQAbmFtZSoAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tfc3RhaXJzBAkAbmFtZV9oYXNonks6UlfpOmkDCgBuZXR3b3JrX2lkgYeOdAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cut_copper_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAgAACAQAbmFtZRsAbWluZWNyYWZ0OmN1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNoHfoAXYq5G3MDCgBuZXR3b3JrX2lkeetf7woGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:exposed_cut_copper_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAgAACAQAbmFtZSMAbWluZWNyYWZ0OmV4cG9zZWRfY3V0X2NvcHBlcl9zdGFpcnMECQBuYW1lX2hhc2howneQGtZ9cgMKAG5ldHdvcmtfaWSg73zdCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:weathered_cut_copper_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAgAACAQAbmFtZSUAbWluZWNyYWZ0OndlYXRoZXJlZF9jdXRfY29wcGVyX3N0YWlycwQJAG5hbWVfaGFzaP+R5loXxrVgAwoAbmV0d29ya19pZOnbRf4KBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:oxidized_cut_copper_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRkAgAACAQAbmFtZSQAbWluZWNyYWZ0Om94aWRpemVkX2N1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNo6Jeoq5rsPxsDCgBuZXR3b3JrX2lkmRjDnQoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:waxed_cut_copper_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRlAgAACAQAbmFtZSEAbWluZWNyYWZ0OndheGVkX2N1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNoh07CQj0/SR8DCgBuZXR3b3JrX2lkmYqoqAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:waxed_exposed_cut_copper_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRmAgAACAQAbmFtZSkAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY3V0X2NvcHBlcl9zdGFpcnMECQBuYW1lX2hhc2guVct1ilmxTwMKAG5ldHdvcmtfaWQgCPROCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:waxed_weathered_cut_copper_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRnAgAACAQAbmFtZSsAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jdXRfY29wcGVyX3N0YWlycwQJAG5hbWVfaGFzaPXC8Sz/phCpAwoAbmV0d29ya19pZHlwHVsKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:waxed_oxidized_cut_copper_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS/AgAACAQAbmFtZSoAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2N1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNoaqGdkuhxVZUDCgBuZXR3b3JrX2lkYQXzzgoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cobbled_deepslate_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR8AgAACAQAbmFtZSIAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlX3N0YWlycwQJAG5hbWVfaGFzaPIfa+TpyJcIAwoAbmV0d29ya19pZJUvOYIKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:deepslate_tile_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAgAACAQAbmFtZR8AbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlX3N0YWlycwQJAG5hbWVfaGFzaGFRFzB72mN2AwoAbmV0d29ya19pZJEOgIsKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:polished_deepslate_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSAAgAACAQAbmFtZSMAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZV9zdGFpcnMECQBuYW1lX2hhc2iNCYxVik9sGAMKAG5ldHdvcmtfaWSRVPnYCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:deepslate_brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSIAgAACAQAbmFtZSAAbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja19zdGFpcnMECQBuYW1lX2hhc2hIasOahEf83wMKAG5ldHdvcmtfaWQ1qEDCCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:mud_brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTfAgAACAQAbmFtZRoAbWluZWNyYWZ0Om11ZF9icmlja19zdGFpcnMECQBuYW1lX2hhc2gt3qxK1NWajAMKAG5ldHdvcmtfaWSm9N3MCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:wooden_door" + }, + { + "id": "minecraft:spruce_door" + }, + { + "id": "minecraft:birch_door" + }, + { + "id": "minecraft:jungle_door" + }, + { + "id": "minecraft:acacia_door" + }, + { + "id": "minecraft:dark_oak_door" + }, + { + "id": "minecraft:mangrove_door" + }, + { + "id": "minecraft:cherry_door" + }, + { + "id": "minecraft:bamboo_door" + }, + { + "id": "minecraft:iron_door" + }, + { + "id": "minecraft:crimson_door" + }, + { + "id": "minecraft:warped_door" + }, + { + "id": "minecraft:trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRgAAAACAQAbmFtZRIAbWluZWNyYWZ0OnRyYXBkb29yBAkAbmFtZV9oYXNotYiAJGtN0xADCgBuZXR3b3JrX2lkyTAWkAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:spruce_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSUAQAACAQAbmFtZRkAbWluZWNyYWZ0OnNwcnVjZV90cmFwZG9vcgQJAG5hbWVfaGFzaOwlfbgBkUW4AwoAbmV0d29ya19pZPHy1K0KBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:birch_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAQAACAQAbmFtZRgAbWluZWNyYWZ0OmJpcmNoX3RyYXBkb29yBAkAbmFtZV9oYXNoSLtLweOLJ7wDCgBuZXR3b3JrX2lkeJWDfgoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:jungle_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSTAQAACAQAbmFtZRkAbWluZWNyYWZ0Omp1bmdsZV90cmFwZG9vcgQJAG5hbWVfaGFzaDP/TnM9wyCIAwoAbmV0d29ya19pZEy2fJoKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:acacia_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSQAQAACAQAbmFtZRkAbWluZWNyYWZ0OmFjYWNpYV90cmFwZG9vcgQJAG5hbWVfaGFzaMj8xi3vmEKOAwoAbmV0d29ya19pZOHj8E8KBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:dark_oak_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSSAQAACAQAbmFtZRsAbWluZWNyYWZ0OmRhcmtfb2FrX3RyYXBkb29yBAkAbmFtZV9oYXNomB2GGJQ2aOMDCgBuZXR3b3JrX2lko5ZHTwoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:mangrove_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTvAgAACAQAbmFtZRsAbWluZWNyYWZ0Om1hbmdyb3ZlX3RyYXBkb29yBAkAbmFtZV9oYXNooV3kQsQUUmkDCgBuZXR3b3JrX2lkkF/mxAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cherry_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQeAwAACAQAbmFtZRkAbWluZWNyYWZ0OmNoZXJyeV90cmFwZG9vcgQJAG5hbWVfaGFzaH/PefpfdHgtAwoAbmV0d29ya19pZOA7eNgKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:bamboo_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQHAwAACAQAbmFtZRkAbWluZWNyYWZ0OmJhbWJvb190cmFwZG9vcgQJAG5hbWVfaGFzaJrEOpsTwtKCAwoAbmV0d29ya19pZLvbPz8KBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:iron_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSnAAAACAQAbmFtZRcAbWluZWNyYWZ0Omlyb25fdHJhcGRvb3IECQBuYW1lX2hhc2gwA+IumsEiGQMKAG5ldHdvcmtfaWTvSVl/CgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAEPAHVwc2lkZV9kb3duX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:crimson_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT1AQAACAQAbmFtZRoAbWluZWNyYWZ0OmNyaW1zb25fdHJhcGRvb3IECQBuYW1lX2hhc2jHXufTnwUkYgMKAG5ldHdvcmtfaWQLjMYVCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAEPAHVwc2lkZV9kb3duX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:warped_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT2AQAACAQAbmFtZRkAbWluZWNyYWZ0OndhcnBlZF90cmFwZG9vcgQJAG5hbWVfaGFzaA20wG/+vkd6AwoAbmV0d29ya19pZHKR/hYKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:iron_bars", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRlAAAACAQAbmFtZRMAbWluZWNyYWZ0Omlyb25fYmFycwQJAG5hbWVfaGFzaPuefWSNAe56AwoAbmV0d29ya19pZN2LB5IKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQUAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmdsYXNzBAkAbmFtZV9oYXNowGJByfWff6gDCgBuZXR3b3JrX2lk0hdLNwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:white_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTxAAAACAQAbmFtZR0AbWluZWNyYWZ0OndoaXRlX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2iHubqoMbu9fAMKAG5ldHdvcmtfaWRndBrUCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:light_gray_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSnAwAACAQAbmFtZSIAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaKKa+LrRsHQhAwoAbmV0d29ya19pZEv2giYKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:gray_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSmAwAACAQAbmFtZRwAbWluZWNyYWZ0OmdyYXlfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaIETy7Y/HZREAwoAbmV0d29ya19pZDomVrUKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:black_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSuAwAACAQAbmFtZR0AbWluZWNyYWZ0OmJsYWNrX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2iV6BCwpfDMmwMKAG5ldHdvcmtfaWSV7doJCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:brown_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSrAwAACAQAbmFtZR0AbWluZWNyYWZ0OmJyb3duX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2igsEiq5np8JgMKAG5ldHdvcmtfaWRMzE/lCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:red_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWStAwAACAQAbmFtZRsAbWluZWNyYWZ0OnJlZF9zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNoCa2J12/lQoIDCgBuZXR3b3JrX2lk283lWAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:orange_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSgAwAACAQAbmFtZR4AbWluZWNyYWZ0Om9yYW5nZV9zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNozgjAuvzhxGsDCgBuZXR3b3JrX2lkW5CkhQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:yellow_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSjAwAACAQAbmFtZR4AbWluZWNyYWZ0OnllbGxvd19zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNo7EbHMd5WVugDCgBuZXR3b3JrX2lkkdDyXQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:lime_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSkAwAACAQAbmFtZRwAbWluZWNyYWZ0OmxpbWVfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaBtZA1nZtwcFAwoAbmV0d29ya19pZDxX85UKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:green_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSsAwAACAQAbmFtZR0AbWluZWNyYWZ0OmdyZWVuX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2h91ptDgbehWwMKAG5ldHdvcmtfaWTlDhnECgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cyan_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAwAACAQAbmFtZRwAbWluZWNyYWZ0OmN5YW5fc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaBkIYQ8nQLqbAwoAbmV0d29ya19pZOL1lHsKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:light_blue_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSiAwAACAQAbmFtZSIAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaLt05n1G0fiSAwoAbmV0d29ya19pZNbwulIKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:blue_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSqAwAACAQAbmFtZRwAbWluZWNyYWZ0OmJsdWVfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaPhLocSfzduRAwoAbmV0d29ya19pZENsjFwKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:purple_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSpAwAACAQAbmFtZR4AbWluZWNyYWZ0OnB1cnBsZV9zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNoJk0DhRO0szUDCgBuZXR3b3JrX2lkD98ZxgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:magenta_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAwAACAQAbmFtZR8AbWluZWNyYWZ0Om1hZ2VudGFfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaFEDeFiJj3zSAwoAbmV0d29ya19pZG+iFRoKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:pink_stained_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAwAACAQAbmFtZRwAbWluZWNyYWZ0OnBpbmtfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaDijTX87ywxhAwoAbmV0d29ya19pZKdEricKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:tinted_glass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRNAgAACAQAbmFtZRYAbWluZWNyYWZ0OnRpbnRlZF9nbGFzcwQJAG5hbWVfaGFzaAFZWSamk6KdAwoAbmV0d29ya19pZGSvWX8KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRmAAAACAQAbmFtZRQAbWluZWNyYWZ0OmdsYXNzX3BhbmUECQBuYW1lX2hhc2gRSBHwNMQ4gQMKAG5ldHdvcmtfaWRGwixuCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:white_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSgAAAACAQAbmFtZSIAbWluZWNyYWZ0OndoaXRlX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaHgxQmgJVtRrAwoAbmV0d29ya19pZBEr/DYKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:light_gray_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSJAwAACAQAbmFtZScAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNon0aQw9lNkSEDCgBuZXR3b3JrX2lk9dp5VgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:gray_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSIAwAACAQAbmFtZSEAbWluZWNyYWZ0OmdyYXlfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNors74IIw+2MMDCgBuZXR3b3JrX2lkmrGO5woGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:black_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSQAwAACAQAbmFtZSIAbWluZWNyYWZ0OmJsYWNrX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaOK/5ZRRd+M1AwoAbmV0d29ya19pZDv++oQKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:brown_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSNAwAACAQAbmFtZSIAbWluZWNyYWZ0OmJyb3duX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaLHeGJyRFTIWAwoAbmV0d29ya19pZMz9L0wKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:red_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSPAwAACAQAbmFtZSAAbWluZWNyYWZ0OnJlZF9zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2gGr4x6JheAywMKAG5ldHdvcmtfaWQBjCTmCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:orange_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSCAwAACAQAbmFtZSMAbWluZWNyYWZ0Om9yYW5nZV9zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2hbHxPD2gEbEAMKAG5ldHdvcmtfaWSt/7a5CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:yellow_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAwAACAQAbmFtZSMAbWluZWNyYWZ0OnllbGxvd19zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2g9tl4aOCyZBwMKAG5ldHdvcmtfaWTXRAS7CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:lime_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSGAwAACAQAbmFtZSEAbWluZWNyYWZ0OmxpbWVfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNo3CtUyLwoGegDCgBuZXR3b3JrX2lkYJDnggoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:green_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSOAwAACAQAbmFtZSIAbWluZWNyYWZ0OmdyZWVuX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaJo6YP7IMy9SAwoAbmV0d29ya19pZHOnixoKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cyan_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSKAwAACAQAbmFtZSEAbWluZWNyYWZ0OmN5YW5fc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNoti97c6QrbLQDCgBuZXR3b3JrX2lkUqFUeQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:light_blue_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAwAACAQAbmFtZScAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNovDg/gQle104DCgBuZXR3b3JrX2lkFuy4MQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:blue_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSMAwAACAQAbmFtZSEAbWluZWNyYWZ0OmJsdWVfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNoGc57tiexbQMDCgBuZXR3b3JrX2lk1eBLUAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:purple_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAwAACAQAbmFtZSMAbWluZWNyYWZ0OnB1cnBsZV9zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2hDJHYdd0FdfQMKAG5ldHdvcmtfaWSNsdK5CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:magenta_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAwAACAQAbmFtZSQAbWluZWNyYWZ0Om1hZ2VudGFfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNo3pcOw5bs5XoDCgBuZXR3b3JrX2lkVbOR7AoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:pink_stained_glass_pane", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSHAwAACAQAbmFtZSEAbWluZWNyYWZ0OnBpbmtfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNoWRhSACMWgswDCgBuZXR3b3JrX2lkIR92xwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:ladder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRBAAAACAQAbmFtZRAAbWluZWNyYWZ0OmxhZGRlcgQJAG5hbWVfaGFzaKBhqheJVOz+AwoAbmV0d29ya19pZCgvzlsKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:scaffolding", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSkAQAACAQAbmFtZRUAbWluZWNyYWZ0OnNjYWZmb2xkaW5nBAkAbmFtZV9oYXNoYrkevrqcljwDCgBuZXR3b3JrX2lkD13mlAoGAHN0YXRlcwMJAHN0YWJpbGl0eQAAAAABDwBzdGFiaWxpdHlfY2hlY2sAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stone_block_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWTkNl0JCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQwAc21vb3RoX3N0b25lAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stone_block_slab4", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkQJoxlgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNAUAc3RvbmUAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stone_block_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWRHh04KCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQsAY29iYmxlc3RvbmUAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stone_block_slab2", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkVRZB+woGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhEAbW9zc3lfY29iYmxlc3RvbmUAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:oak_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSeAAAACAQAbmFtZRIAbWluZWNyYWZ0Om9ha19zbGFiBAkAbmFtZV9oYXNoJp1Cp1M4jlwDCgBuZXR3b3JrX2lkZH6+owoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:spruce_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQjBAAACAQAbmFtZRUAbWluZWNyYWZ0OnNwcnVjZV9zbGFiBAkAbmFtZV9oYXNodQi70jB238cDCgBuZXR3b3JrX2lkrriOYQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:birch_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQkBAAACAQAbmFtZRQAbWluZWNyYWZ0OmJpcmNoX3NsYWIECQBuYW1lX2hhc2gZPpfMxoOsTAMKAG5ldHdvcmtfaWThR9jyCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:jungle_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQlBAAACAQAbmFtZRUAbWluZWNyYWZ0Omp1bmdsZV9zbGFiBAkAbmFtZV9oYXNo6gLs79NXak4DCgBuZXR3b3JrX2lk5ZiKgwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:acacia_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQmBAAACAQAbmFtZRUAbWluZWNyYWZ0OmFjYWNpYV9zbGFiBAkAbmFtZV9oYXNomSdFmDnv4OUDCgBuZXR3b3JrX2lkHttaXAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:dark_oak_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQnBAAACAQAbmFtZRcAbWluZWNyYWZ0OmRhcmtfb2FrX3NsYWIECQBuYW1lX2hhc2hJjTohRFyhIQMKAG5ldHdvcmtfaWRMzDTyCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:mangrove_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWToAgAACAQAbmFtZRcAbWluZWNyYWZ0Om1hbmdyb3ZlX3NsYWIECQBuYW1lX2hhc2jYCcmhJPeNMwMKAG5ldHdvcmtfaWQx6U1yCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cherry_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQaAwAACAQAbmFtZRUAbWluZWNyYWZ0OmNoZXJyeV9zbGFiBAkAbmFtZV9oYXNoTt0MmVn/mqoDCgBuZXR3b3JrX2lk2VVsZQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:bamboo_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQAAwAACAQAbmFtZRUAbWluZWNyYWZ0OmJhbWJvb19zbGFiBAkAbmFtZV9oYXNoo1xuFqINeLYDCgBuZXR3b3JrX2lkVC+0twoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:bamboo_mosaic_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQLAwAACAQAbmFtZRwAbWluZWNyYWZ0OmJhbWJvb19tb3NhaWNfc2xhYgQJAG5hbWVfaGFzaNbVRBZ/ChI3AwoAbmV0d29ya19pZOLZHFMKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stone_block_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWQSiInOCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQsAc3RvbmVfYnJpY2sAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stone_block_slab4", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkoF89tgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNBEAbW9zc3lfc3RvbmVfYnJpY2sAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stone_block_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWSkoAE4CgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQkAc2FuZHN0b25lAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stone_block_slab4", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkWfF7pgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNA0AY3V0X3NhbmRzdG9uZQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stone_block_slab2", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkbKRChAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAc21vb3RoX3NhbmRzdG9uZQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stone_block_slab2", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkBlrvqAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMg0AcmVkX3NhbmRzdG9uZQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stone_block_slab4", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkRWFXuwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNBEAY3V0X3JlZF9zYW5kc3RvbmUAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stone_block_slab3", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkom8neQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxQAc21vb3RoX3JlZF9zYW5kc3RvbmUAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stone_block_slab3", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkd1ZaWgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMwcAZ3Jhbml0ZQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stone_block_slab3", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkISH4iwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxAAcG9saXNoZWRfZ3Jhbml0ZQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stone_block_slab3", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkqxEDMwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMwcAZGlvcml0ZQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stone_block_slab3", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkSYs86QoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxAAcG9saXNoZWRfZGlvcml0ZQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stone_block_slab3", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkq6BU6goGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMwgAYW5kZXNpdGUAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stone_block_slab3", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkTSXY8AoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxEAcG9saXNoZWRfYW5kZXNpdGUAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stone_block_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWQiYHKTCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQUAYnJpY2sAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stone_block_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWTk/0LfCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQwAbmV0aGVyX2JyaWNrAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stone_block_slab2", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lk/hXQ7AoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAcmVkX25ldGhlcl9icmljawADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stone_block_slab3", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkYJNxrwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMw8AZW5kX3N0b25lX2JyaWNrAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stone_block_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWRlj0/sCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQYAcXVhcnR6AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stone_block_slab4", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkMae+2goGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNA0Ac21vb3RoX3F1YXJ0egADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stone_block_slab2", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lk+kMHGAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMgYAcHVycHVyAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stone_block_slab2", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkKOSOMAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAcHJpc21hcmluZV9yb3VnaAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stone_block_slab2", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lk8igLCQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMg8AcHJpc21hcmluZV9kYXJrAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stone_block_slab2", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkSFbyEwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAcHJpc21hcmluZV9icmljawADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:crimson_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQHAgAACAQAbmFtZRYAbWluZWNyYWZ0OmNyaW1zb25fc2xhYgQJAG5hbWVfaGFzaKZ+EfP0ZYOZAwoAbmV0d29ya19pZAxRUWAKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:warped_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQIAgAACAQAbmFtZRUAbWluZWNyYWZ0OndhcnBlZF9zbGFiBAkAbmFtZV9oYXNo/AT0e/Z9W7UDCgBuZXR3b3JrX2lk1yq11AoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:blackstone_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQZAgAACAQAbmFtZRkAbWluZWNyYWZ0OmJsYWNrc3RvbmVfc2xhYgQJAG5hbWVfaGFzaF/DD4ZUlNgtAwoAbmV0d29ya19pZGy1DjwKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:polished_blackstone_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQkAgAACAQAbmFtZSIAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfc2xhYgQJAG5hbWVfaGFzaDYnuUs86EWfAwoAbmV0d29ya19pZJj2bXIKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:polished_blackstone_brick_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQbAgAACAQAbmFtZSgAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tfc2xhYgQJAG5hbWVfaGFzaKySLqvHc4xXAwoAbmV0d29ya19pZOyWX94KBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cut_copper_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRoAgAACAQAbmFtZRkAbWluZWNyYWZ0OmN1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaDsNpb2qs4iBAwoAbmV0d29ya19pZOTm2nsKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:exposed_cut_copper_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRpAgAACAQAbmFtZSEAbWluZWNyYWZ0OmV4cG9zZWRfY3V0X2NvcHBlcl9zbGFiBAkAbmFtZV9oYXNoahQ5OwIQb7kDCgBuZXR3b3JrX2lkrUlZLwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:weathered_cut_copper_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRqAgAACAQAbmFtZSMAbWluZWNyYWZ0OndlYXRoZXJlZF9jdXRfY29wcGVyX3NsYWIECQBuYW1lX2hhc2hBIuGIOVVXogMKAG5ldHdvcmtfaWQgnaDiCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:oxidized_cut_copper_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRrAgAACAQAbmFtZSIAbWluZWNyYWZ0Om94aWRpemVkX2N1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaOptj9ycfpaDAwoAbmV0d29ya19pZMzFSRgKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:waxed_cut_copper_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRsAgAACAQAbmFtZR8AbWluZWNyYWZ0OndheGVkX2N1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaAlx6DZOCTHzAwoAbmV0d29ya19pZFRBvDAKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:waxed_exposed_cut_copper_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRtAgAACAQAbmFtZScAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY3V0X2NvcHBlcl9zbGFiBAkAbmFtZV9oYXNo3KqS5OnhtRIDCgBuZXR3b3JrX2lkHTGcTgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:waxed_weathered_cut_copper_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRuAgAACAQAbmFtZSkAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jdXRfY29wcGVyX3NsYWIECQBuYW1lX2hhc2gzZ1oX0HCFtwMKAG5ldHdvcmtfaWSgJR+XCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:waxed_oxidized_cut_copper_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTAAgAACAQAbmFtZSgAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2N1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaMjjTnLu1KcqAwoAbmV0d29ya19pZIxsnFYKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cobbled_deepslate_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR7AgAACAQAbmFtZSAAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlX3NsYWIECQBuYW1lX2hhc2gwJIVWK1TM2QMKAG5ldHdvcmtfaWTYAoX5CgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:polished_deepslate_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR/AgAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZV9zbGFiBAkAbmFtZV9oYXNoC/Adiz8k6RYDCgBuZXR3b3JrX2lkuFYMAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:deepslate_tile_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAgAACAQAbmFtZR0AbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlX3NsYWIECQBuYW1lX2hhc2hPydV6emzIXAMKAG5ldHdvcmtfaWQwlbFCCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:deepslate_brick_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSHAgAACAQAbmFtZR4AbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja19zbGFiBAkAbmFtZV9oYXNoSv62V7iw10UDCgBuZXR3b3JrX2lkWMoragoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:mud_brick_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTdAgAACAQAbmFtZRgAbWluZWNyYWZ0Om11ZF9icmlja19zbGFiBAkAbmFtZV9oYXNoq/tGBQWkv08DCgBuZXR3b3JrX2lkl4nnMwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:brick_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQtAAAACAQAbmFtZRUAbWluZWNyYWZ0OmJyaWNrX2Jsb2NrBAkAbmFtZV9oYXNo5Qc2E005S3oDCgBuZXR3b3JrX2lkqeGWRgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:chiseled_nether_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQtAgAACAQAbmFtZSAAbWluZWNyYWZ0OmNoaXNlbGVkX25ldGhlcl9icmlja3MECQBuYW1lX2hhc2g31SBPTcUK1QMKAG5ldHdvcmtfaWS8TJ+TCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cracked_nether_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQuAgAACAQAbmFtZR8AbWluZWNyYWZ0OmNyYWNrZWRfbmV0aGVyX2JyaWNrcwQJAG5hbWVfaGFzaAdC6eKzXT5tAwoAbmV0d29ya19pZIUSejwKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:quartz_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQvAgAACAQAbmFtZRcAbWluZWNyYWZ0OnF1YXJ0el9icmlja3MECQBuYW1lX2hhc2jSZO590dd8sAMKAG5ldHdvcmtfaWSc5xCLCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stonebrick", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAAAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWQ5kni1CgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQcAZGVmYXVsdAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stonebrick", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAAAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWTDw813CgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQUAbW9zc3kAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stonebrick", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAAAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWSTvQGECgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQcAY3JhY2tlZAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stonebrick", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAAAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWQIM0OwCgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQgAY2hpc2VsZWQAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:end_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTOAAAACAQAbmFtZRQAbWluZWNyYWZ0OmVuZF9icmlja3MECQBuYW1lX2hhc2hIUFfxNLZaFgMKAG5ldHdvcmtfaWQ/vDihCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:prismarine", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAAAACAQAbmFtZRQAbWluZWNyYWZ0OnByaXNtYXJpbmUECQBuYW1lX2hhc2jcnQCHi9CspQMKAG5ldHdvcmtfaWSH021WCgYAc3RhdGVzCBUAcHJpc21hcmluZV9ibG9ja190eXBlBgBicmlja3MAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:polished_blackstone_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQRAgAACAQAbmFtZSQAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tzBAkAbmFtZV9oYXNoIHgsgIdzKXcDCgBuZXR3b3JrX2lkUw9b3woGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cracked_polished_blackstone_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQXAgAACAQAbmFtZSwAbWluZWNyYWZ0OmNyYWNrZWRfcG9saXNoZWRfYmxhY2tzdG9uZV9icmlja3MECQBuYW1lX2hhc2jQIO1GQDk80AMKAG5ldHdvcmtfaWQ3UlRYCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:gilded_blackstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAgAACAQAbmFtZRsAbWluZWNyYWZ0OmdpbGRlZF9ibGFja3N0b25lBAkAbmFtZV9oYXNoNoWt1ocG0HEDCgBuZXR3b3JrX2lktL8gUwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:chiseled_polished_blackstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQWAgAACAQAbmFtZSYAbWluZWNyYWZ0OmNoaXNlbGVkX3BvbGlzaGVkX2JsYWNrc3RvbmUECQBuYW1lX2hhc2gzFa+kEjCJgAMKAG5ldHdvcmtfaWR2NJX2CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:deepslate_tiles", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSCAgAACAQAbmFtZRkAbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlcwQJAG5hbWVfaGFzaGcLLx3NXAFvAwoAbmV0d29ya19pZI/G/xYKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cracked_deepslate_tiles", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSYAgAACAQAbmFtZSEAbWluZWNyYWZ0OmNyYWNrZWRfZGVlcHNsYXRlX3RpbGVzBAkAbmFtZV9oYXNo9zWgkFuMM1QDCgBuZXR3b3JrX2lkGwY6OgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:deepslate_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSGAgAACAQAbmFtZRoAbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja3MECQBuYW1lX2hhc2gucvFmPdZxigMKAG5ldHdvcmtfaWSH4HDPCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cracked_deepslate_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSZAgAACAQAbmFtZSIAbWluZWNyYWZ0OmNyYWNrZWRfZGVlcHNsYXRlX2JyaWNrcwQJAG5hbWVfaGFzaN40aqhh9WqHAwoAbmV0d29ya19pZO9GPBQKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:chiseled_deepslate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSKAgAACAQAbmFtZRwAbWluZWNyYWZ0OmNoaXNlbGVkX2RlZXBzbGF0ZQQJAG5hbWVfaGFzaEU7/uRG8HSBAwoAbmV0d29ya19pZEqmI0EKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cobblestone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQEAAAACAQAbmFtZRUAbWluZWNyYWZ0OmNvYmJsZXN0b25lBAkAbmFtZV9oYXNoPoK7mGlSUz4DCgBuZXR3b3JrX2lkLm7RZwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:mossy_cobblestone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQwAAAACAQAbmFtZRsAbWluZWNyYWZ0Om1vc3N5X2NvYmJsZXN0b25lBAkAbmFtZV9oYXNoGJ67FCbkChMDCgBuZXR3b3JrX2lk/pYs1AoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cobbled_deepslate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR6AgAACAQAbmFtZRsAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlBAkAbmFtZV9oYXNoLUz9Y/ywmLwDCgBuZXR3b3JrX2lkNwzZ+AoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:smooth_stone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AQAACAQAbmFtZRYAbWluZWNyYWZ0OnNtb290aF9zdG9uZQQJAG5hbWVfaGFzaMwf87/JaTNvAwoAbmV0d29ya19pZLkZICEKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:sandstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZB2wApMKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGUHAGRlZmF1bHQAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:sandstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZB7E+eQKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGULAGhlaXJvZ2x5cGhzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:sandstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZFQnDaEKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGUDAGN1dAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:sandstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZPO4A3IKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGUGAHNtb290aAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:red_sandstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWRhNYiFCgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlBwBkZWZhdWx0AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:red_sandstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWTqXJr1CgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlCwBoZWlyb2dseXBocwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:red_sandstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWTQRGkFCgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlAwBjdXQAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:red_sandstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWTvAHWDCgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlBgBzbW9vdGgAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:coal_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWStAAAACAQAbmFtZRQAbWluZWNyYWZ0OmNvYWxfYmxvY2sECQBuYW1lX2hhc2jH8QQP3t5PiAMKAG5ldHdvcmtfaWRo+sR+CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:dried_kelp_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSKAQAACAQAbmFtZRoAbWluZWNyYWZ0OmRyaWVkX2tlbHBfYmxvY2sECQBuYW1lX2hhc2iRoucexkrl8wMKAG5ldHdvcmtfaWQQCCrvCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:gold_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQpAAAACAQAbmFtZRQAbWluZWNyYWZ0OmdvbGRfYmxvY2sECQBuYW1lX2hhc2iYLshvjtXzFwMKAG5ldHdvcmtfaWTDJGBcCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:iron_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQqAAAACAQAbmFtZRQAbWluZWNyYWZ0Omlyb25fYmxvY2sECQBuYW1lX2hhc2jYINmJQbvV/gMKAG5ldHdvcmtfaWRf7AbICgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:copper_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRTAgAACAQAbmFtZRYAbWluZWNyYWZ0OmNvcHBlcl9ibG9jawQJAG5hbWVfaGFzaDVxnehsGaZ1AwoAbmV0d29ya19pZIiUodwKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:exposed_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRUAgAACAQAbmFtZRgAbWluZWNyYWZ0OmV4cG9zZWRfY29wcGVyBAkAbmFtZV9oYXNoQH3Fukmu3CEDCgBuZXR3b3JrX2lk72jFIwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:weathered_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRVAgAACAQAbmFtZRoAbWluZWNyYWZ0OndlYXRoZXJlZF9jb3BwZXIECQBuYW1lX2hhc2hJCQXbvobv+gMKAG5ldHdvcmtfaWQwM0lJCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:oxidized_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRWAgAACAQAbmFtZRkAbWluZWNyYWZ0Om94aWRpemVkX2NvcHBlcgQJAG5hbWVfaGFzaMDtJqR0G5Y7AwoAbmV0d29ya19pZGjN8bUKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:waxed_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRXAgAACAQAbmFtZRYAbWluZWNyYWZ0OndheGVkX2NvcHBlcgQJAG5hbWVfaGFzaPF+FG6Eh5fsAwoAbmV0d29ya19pZIjtz/0KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:waxed_exposed_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRYAgAACAQAbmFtZR4AbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY29wcGVyBAkAbmFtZV9oYXNoig8IOc+SCikDCgBuZXR3b3JrX2lklz8yWQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:waxed_weathered_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRZAgAACAQAbmFtZSAAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jb3BwZXIECQBuYW1lX2hhc2gjtPq8MOdvKgMKAG5ldHdvcmtfaWSQ9Ln9CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:waxed_oxidized_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS9AgAACAQAbmFtZR8AbWluZWNyYWZ0OndheGVkX294aWRpemVkX2NvcHBlcgQJAG5hbWVfaGFzaMaORhsO+LzjAwoAbmV0d29ya19pZJhGfLEKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cut_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRaAgAACAQAbmFtZRQAbWluZWNyYWZ0OmN1dF9jb3BwZXIECQBuYW1lX2hhc2hAfN3NGax3eAMKAG5ldHdvcmtfaWTnFBtYCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:exposed_cut_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRbAgAACAQAbmFtZRwAbWluZWNyYWZ0OmV4cG9zZWRfY3V0X2NvcHBlcgQJAG5hbWVfaGFzaA85G3yv/w6pAwoAbmV0d29ya19pZMQhr0QKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:weathered_cut_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRcAgAACAQAbmFtZR4AbWluZWNyYWZ0OndlYXRoZXJlZF9jdXRfY29wcGVyBAkAbmFtZV9oYXNoVgRV0fBaz88DCgBuZXR3b3JrX2lk/0cYugoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:oxidized_cut_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRdAgAACAQAbmFtZR0AbWluZWNyYWZ0Om94aWRpemVkX2N1dF9jb3BwZXIECQBuYW1lX2hhc2iP8WmFWOkriwMKAG5ldHdvcmtfaWQPdce7CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:waxed_cut_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWReAgAACAQAbmFtZRoAbWluZWNyYWZ0OndheGVkX2N1dF9jb3BwZXIECQBuYW1lX2hhc2jumiwOZIqv2AMKAG5ldHdvcmtfaWQvuxx9CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:waxed_exposed_cut_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRfAgAACAQAbmFtZSIAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY3V0X2NvcHBlcgQJAG5hbWVfaGFzaPE/OfK6IoVMAwoAbmV0d29ya19pZHy5HkcKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:waxed_weathered_cut_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRgAgAACAQAbmFtZSQAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jdXRfY29wcGVyBAkAbmFtZV9oYXNoCA1xDp11bnwDCgBuZXR3b3JrX2lkDyEDVQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:waxed_oxidized_cut_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWS+AgAACAQAbmFtZSMAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2N1dF9jb3BwZXIECQBuYW1lX2hhc2i1pZAsZYHLDAMKAG5ldHdvcmtfaWQ/wSkCCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:emerald_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAAAACAQAbmFtZRcAbWluZWNyYWZ0OmVtZXJhbGRfYmxvY2sECQBuYW1lX2hhc2hK6QunqJznNAMKAG5ldHdvcmtfaWRk5+otCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:diamond_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ5AAAACAQAbmFtZRcAbWluZWNyYWZ0OmRpYW1vbmRfYmxvY2sECQBuYW1lX2hhc2iGKrxuvkytFQMKAG5ldHdvcmtfaWQQeQZXCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:lapis_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQWAAAACAQAbmFtZRUAbWluZWNyYWZ0OmxhcGlzX2Jsb2NrBAkAbmFtZV9oYXNoDZ44xdb2zVoDCgBuZXR3b3JrX2lktVy0BAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:raw_iron_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTCAgAACAQAbmFtZRgAbWluZWNyYWZ0OnJhd19pcm9uX2Jsb2NrBAkAbmFtZV9oYXNo9XyzNIQXxvwDCgBuZXR3b3JrX2lknms1QAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:raw_copper_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTDAgAACAQAbmFtZRoAbWluZWNyYWZ0OnJhd19jb3BwZXJfYmxvY2sECQBuYW1lX2hhc2hw1KG0TNUGgwMKAG5ldHdvcmtfaWS1vGo/CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:raw_gold_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTEAgAACAQAbmFtZRgAbWluZWNyYWZ0OnJhd19nb2xkX2Jsb2NrBAkAbmFtZV9oYXNo6YuwuLwfOBwDCgBuZXR3b3JrX2lkLiQ5gQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:quartz_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAAAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZEupC1AKBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQcAZGVmYXVsdAgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:quartz_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAAAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZM97+l0KBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQUAbGluZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:quartz_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAAAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZCbTfssKBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQgAY2hpc2VsZWQICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:quartz_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAAAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZJss8V0KBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQYAc21vb3RoCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:prismarine", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAAAACAQAbmFtZRQAbWluZWNyYWZ0OnByaXNtYXJpbmUECQBuYW1lX2hhc2jcnQCHi9CspQMKAG5ldHdvcmtfaWRFIsoGCgYAc3RhdGVzCBUAcHJpc21hcmluZV9ibG9ja190eXBlBwBkZWZhdWx0AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:prismarine", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAAAACAQAbmFtZRQAbWluZWNyYWZ0OnByaXNtYXJpbmUECQBuYW1lX2hhc2jcnQCHi9CspQMKAG5ldHdvcmtfaWTDNWOvCgYAc3RhdGVzCBUAcHJpc21hcmluZV9ibG9ja190eXBlBABkYXJrAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:slime", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAAAACAQAbmFtZQ8AbWluZWNyYWZ0OnNsaW1lBAkAbmFtZV9oYXNoHJiEEJx+JlkDCgBuZXR3b3JrX2lkfgfVzAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:honey_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTbAQAACAQAbmFtZRUAbWluZWNyYWZ0OmhvbmV5X2Jsb2NrBAkAbmFtZV9oYXNo9zLYSUlelywDCgBuZXR3b3JrX2lko+dyWgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:honeycomb_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTcAQAACAQAbmFtZRkAbWluZWNyYWZ0OmhvbmV5Y29tYl9ibG9jawQJAG5hbWVfaGFzaASIPuOCYd1oAwoAbmV0d29ya19pZKys4n4KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:hay_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSqAAAACAQAbmFtZRMAbWluZWNyYWZ0OmhheV9ibG9jawQJAG5hbWVfaGFzaIB2VxKxX8EpAwoAbmV0d29ya19pZKuQSloKBgBzdGF0ZXMDCgBkZXByZWNhdGVkAAAAAAgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:bone_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTYAAAACAQAbmFtZRQAbWluZWNyYWZ0OmJvbmVfYmxvY2sECQBuYW1lX2hhc2i4ZX576W9AWgMKAG5ldHdvcmtfaWTWGacQCgYAc3RhdGVzAwoAZGVwcmVjYXRlZAAAAAAICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:nether_brick", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRwAAAACAQAbmFtZRYAbWluZWNyYWZ0Om5ldGhlcl9icmljawQJAG5hbWVfaGFzaMxcRiheU+nXAwoAbmV0d29ya19pZMkmzloKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:red_nether_brick", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTXAAAACAQAbmFtZRoAbWluZWNyYWZ0OnJlZF9uZXRoZXJfYnJpY2sECQBuYW1lX2hhc2j8pRO4LfoECAMKAG5ldHdvcmtfaWRpdF0YCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:netherite_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQNAgAACAQAbmFtZRkAbWluZWNyYWZ0Om5ldGhlcml0ZV9ibG9jawQJAG5hbWVfaGFzaMghh6Zib/ZKAwoAbmV0d29ya19pZIz0mq0KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:lodestone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTdAQAACAQAbmFtZRMAbWluZWNyYWZ0OmxvZGVzdG9uZQQJAG5hbWVfaGFzaJ2gmHOTlXv8AwoAbmV0d29ya19pZEfgB4wKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:white_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQjAAAACAQAbmFtZRQAbWluZWNyYWZ0OndoaXRlX3dvb2wECQBuYW1lX2hhc2jRWB7vaIEDiQMKAG5ldHdvcmtfaWSO8paQCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:light_gray_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQnAwAACAQAbmFtZRkAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfd29vbAQJAG5hbWVfaGFzaOpdQ1a2v4b3AwoAbmV0d29ya19pZIqZCYEKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:gray_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQoAwAACAQAbmFtZRMAbWluZWNyYWZ0OmdyYXlfd29vbAQJAG5hbWVfaGFzaLsc1Lp1xdIOAwoAbmV0d29ya19pZFUs+HgKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:black_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQpAwAACAQAbmFtZRQAbWluZWNyYWZ0OmJsYWNrX3dvb2wECQBuYW1lX2hhc2hP2HC6o0X4HAMKAG5ldHdvcmtfaWRUbORcCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:brown_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQqAwAACAQAbmFtZRQAbWluZWNyYWZ0OmJyb3duX3dvb2wECQBuYW1lX2hhc2ig5IW89PrREwMKAG5ldHdvcmtfaWRjT9j8CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:red_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQrAwAACAQAbmFtZRIAbWluZWNyYWZ0OnJlZF93b29sBAkAbmFtZV9oYXNoY4TBDq+mFgUDCgBuZXR3b3JrX2lktn9lcAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:orange_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAwAACAQAbmFtZRUAbWluZWNyYWZ0Om9yYW5nZV93b29sBAkAbmFtZV9oYXNoFstfrTZfSCgDCgBuZXR3b3JrX2lk+rqywwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:yellow_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQtAwAACAQAbmFtZRUAbWluZWNyYWZ0OnllbGxvd193b29sBAkAbmFtZV9oYXNoTFyus2RHegcDCgBuZXR3b3JrX2lkkKBhXAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:lime_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQuAwAACAQAbmFtZRMAbWluZWNyYWZ0OmxpbWVfd29vbAQJAG5hbWVfaGFzaNVnnzKiMxmeAwoAbmV0d29ya19pZG9b32kKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:green_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQvAwAACAQAbmFtZRQAbWluZWNyYWZ0OmdyZWVuX3dvb2wECQBuYW1lX2hhc2i3mElRYHIcSQMKAG5ldHdvcmtfaWSssprwCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cyan_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQwAwAACAQAbmFtZRMAbWluZWNyYWZ0OmN5YW5fd29vbAQJAG5hbWVfaGFzaBNDfvHn8dqFAwoAbmV0d29ya19pZK0hAbgKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:light_blue_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQxAwAACAQAbmFtZRkAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfd29vbAQJAG5hbWVfaGFzaLWFAUfyxFPNAwoAbmV0d29ya19pZL2oEugKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:blue_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQyAwAACAQAbmFtZRMAbWluZWNyYWZ0OmJsdWVfd29vbAQJAG5hbWVfaGFzaLjHyxxbTWCLAwoAbmV0d29ya19pZPaLdFQKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:purple_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQzAwAACAQAbmFtZRUAbWluZWNyYWZ0OnB1cnBsZV93b29sBAkAbmFtZV9oYXNojvFtqzjAf/4DCgBuZXR3b3JrX2lklqASNQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:magenta_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ0AwAACAQAbmFtZRYAbWluZWNyYWZ0Om1hZ2VudGFfd29vbAQJAG5hbWVfaGFzaGuOHvf+Pd4yAwoAbmV0d29ya19pZI4UoDQKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:pink_wool", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ1AwAACAQAbmFtZRMAbWluZWNyYWZ0OnBpbmtfd29vbAQJAG5hbWVfaGFzaPiVA2pFeoFLAwoAbmV0d29ya19pZOZRO6oKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:white_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSrAAAACAQAbmFtZRYAbWluZWNyYWZ0OndoaXRlX2NhcnBldAQJAG5hbWVfaGFzaNeMHTI1fWPXAwoAbmV0d29ya19pZEahDFcKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:light_gray_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRbAwAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY2FycGV0BAkAbmFtZV9oYXNoHPw6ArBAsP0DCgBuZXR3b3JrX2lkQoAeUAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:gray_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRaAwAACAQAbmFtZRUAbWluZWNyYWZ0OmdyYXlfY2FycGV0BAkAbmFtZV9oYXNoZVR0OI+1VRADCgBuZXR3b3JrX2lkETF4WwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:black_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJsYWNrX2NhcnBldAQJAG5hbWVfaGFzaOk7LP9NptyhAwoAbmV0d29ya19pZFjmXtIKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:brown_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRfAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJyb3duX2NhcnBldAQJAG5hbWVfaGFzaNaXFyOsAvIvAwoAbmV0d29ya19pZHPjFuoKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:red_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAwAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9jYXJwZXQECQBuYW1lX2hhc2i9eSKBf6SO3wMKAG5ldHdvcmtfaWQuhI/KCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:orange_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRUAwAACAQAbmFtZRcAbWluZWNyYWZ0Om9yYW5nZV9jYXJwZXQECQBuYW1lX2hhc2hIUkO4HlAdygMKAG5ldHdvcmtfaWSyKV9OCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:yellow_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRXAwAACAQAbmFtZRcAbWluZWNyYWZ0OnllbGxvd19jYXJwZXQECQBuYW1lX2hhc2hSDKX3scCamwMKAG5ldHdvcmtfaWT8nq+ECgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:lime_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRYAwAACAQAbmFtZRUAbWluZWNyYWZ0OmxpbWVfY2FycGV0BAkAbmFtZV9oYXNo+6KFOpzsib4DCgBuZXR3b3JrX2lkT+DS4woGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:green_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRgAwAACAQAbmFtZRYAbWluZWNyYWZ0OmdyZWVuX2NhcnBldAQJAG5hbWVfaGFzaCHPMP9ltqFJAwoAbmV0d29ya19pZBgwAvAKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cyan_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRcAwAACAQAbmFtZRUAbWluZWNyYWZ0OmN5YW5fY2FycGV0BAkAbmFtZV9oYXNobXf62dQBJj8DCgBuZXR3b3JrX2lkKVppLgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:light_blue_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRWAwAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY2FycGV0BAkAbmFtZV9oYXNo20l4oktdZ3sDCgBuZXR3b3JrX2lkjdeMiwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:blue_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWReAwAACAQAbmFtZRUAbWluZWNyYWZ0OmJsdWVfY2FycGV0BAkAbmFtZV9oYXNo3p3lsW0eQwsDCgBuZXR3b3JrX2lkAovdPQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:purple_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRdAwAACAQAbmFtZRcAbWluZWNyYWZ0OnB1cnBsZV9jYXJwZXQECQBuYW1lX2hhc2jwIA9pW/qp7QMKAG5ldHdvcmtfaWTqJqhjCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:magenta_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRVAwAACAQAbmFtZRgAbWluZWNyYWZ0Om1hZ2VudGFfY2FycGV0BAkAbmFtZV9oYXNoFXT36YNNZhMDCgBuZXR3b3JrX2lk+tqsGAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:pink_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRZAwAACAQAbmFtZRUAbWluZWNyYWZ0OnBpbmtfY2FycGV0BAkAbmFtZV9oYXNoHll72oqk+OoDCgBuZXR3b3JrX2lkrnBYDwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:white_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTtAAAACAQAbmFtZR8AbWluZWNyYWZ0OndoaXRlX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaFUk9iXVjwV8AwoAbmV0d29ya19pZJPZY8AKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:light_gray_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTLAwAACAQAbmFtZSQAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNo7EUk30hmUtYDCgBuZXR3b3JrX2lkh8jVIwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:gray_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTKAwAACAQAbmFtZR4AbWluZWNyYWZ0OmdyYXlfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoW77af6WihdwDCgBuZXR3b3JrX2lkSsqC1woGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:black_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTSAwAACAQAbmFtZR8AbWluZWNyYWZ0OmJsYWNrX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaAfWYp0xtgcfAwoAbmV0d29ya19pZMWTC8EKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:brown_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTPAwAACAQAbmFtZR8AbWluZWNyYWZ0OmJyb3duX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaB74EeiLO46XAwoAbmV0d29ya19pZEDHKqwKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:red_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTRAwAACAQAbmFtZR0AbWluZWNyYWZ0OnJlZF9jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2gjFut6Z/VH1gMKAG5ldHdvcmtfaWSvcmwYCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:orange_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTEAwAACAQAbmFtZSAAbWluZWNyYWZ0Om9yYW5nZV9jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2gADDj2IJiw+gMKAG5ldHdvcmtfaWTHph0FCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:yellow_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTHAwAACAQAbmFtZSAAbWluZWNyYWZ0OnllbGxvd19jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2iy6qKNn3ob5wMKAG5ldHdvcmtfaWQZAI39CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:lime_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTIAwAACAQAbmFtZR4AbWluZWNyYWZ0OmxpbWVfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNo4dYIPslbXPUDCgBuZXR3b3JrX2lk2O8X0AoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:green_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTQAwAACAQAbmFtZR8AbWluZWNyYWZ0OmdyZWVuX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaM/c9x2aJh3HAwoAbmV0d29ya19pZA0VfBMKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cyan_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTMAwAACAQAbmFtZR4AbWluZWNyYWZ0OmN5YW5fY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNok+xKAe7XXjoDCgBuZXR3b3JrX2lkmkn6uwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:light_blue_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTGAwAACAQAbmFtZSQAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNogScpIQceyAEDCgBuZXR3b3JrX2lkOmVSbgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:blue_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTOAwAACAQAbmFtZR4AbWluZWNyYWZ0OmJsdWVfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoFp7mmeL86r0DCgBuZXR3b3JrX2lkS3b3RQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:purple_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTNAwAACAQAbmFtZSAAbWluZWNyYWZ0OnB1cnBsZV9jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2iYcVU04hoStwMKAG5ldHdvcmtfaWQXimEjCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:magenta_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTFAwAACAQAbmFtZSEAbWluZWNyYWZ0Om1hZ2VudGFfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoy/70q6VPsWgDCgBuZXR3b3JrX2lkf9mxQwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:pink_concrete_powder", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAwAACAQAbmFtZR4AbWluZWNyYWZ0OnBpbmtfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoVikSAf8DwV0DCgBuZXR3b3JrX2lku2MivwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:white_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTsAAAACAQAbmFtZRgAbWluZWNyYWZ0OndoaXRlX2NvbmNyZXRlBAkAbmFtZV9oYXNo6zAp7lsLlvkDCgBuZXR3b3JrX2lk3MAYQAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:light_gray_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR6AwAACAQAbmFtZR0AbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY29uY3JldGUECQBuYW1lX2hhc2hEtet5wuDIKAMKAG5ldHdvcmtfaWQISs02CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:gray_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR5AwAACAQAbmFtZRcAbWluZWNyYWZ0OmdyYXlfY29uY3JldGUECQBuYW1lX2hhc2j92INnb0a83AMKAG5ldHdvcmtfaWQj8RHwCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:black_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSBAwAACAQAbmFtZRgAbWluZWNyYWZ0OmJsYWNrX2NvbmNyZXRlBAkAbmFtZV9oYXNo2X7NDIQmZ70DCgBuZXR3b3JrX2lk2uiVDQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:brown_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR+AwAACAQAbmFtZRgAbWluZWNyYWZ0OmJyb3duX2NvbmNyZXRlBAkAbmFtZV9oYXNoeka02BwXf6oDCgBuZXR3b3JrX2lkYf+xDQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:red_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSAAwAACAQAbmFtZRYAbWluZWNyYWZ0OnJlZF9jb25jcmV0ZQQJAG5hbWVfaGFzaPWmNowLGubqAwoAbmV0d29ya19pZKwyx58KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:orange_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRzAwAACAQAbmFtZRkAbWluZWNyYWZ0Om9yYW5nZV9jb25jcmV0ZQQJAG5hbWVfaGFzaAgE8XmaAi6+AwoAbmV0d29ya19pZMDQNz8KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:yellow_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR2AwAACAQAbmFtZRkAbWluZWNyYWZ0OnllbGxvd19jb25jcmV0ZQQJAG5hbWVfaGFzaE6ONfJPBd0+AwoAbmV0d29ya19pZMarutwKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:lime_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR3AwAACAQAbmFtZRcAbWluZWNyYWZ0OmxpbWVfY29uY3JldGUECQBuYW1lX2hhc2gnd8JW6wmJcAMKAG5ldHdvcmtfaWTd47aoCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:green_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR/AwAACAQAbmFtZRgAbWluZWNyYWZ0OmdyZWVuX2NvbmNyZXRlBAkAbmFtZV9oYXNokbFxRKchQZkDCgBuZXR3b3JrX2lkmhZWUgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cyan_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR7AwAACAQAbmFtZRcAbWluZWNyYWZ0OmN5YW5fY29uY3JldGUECQBuYW1lX2hhc2hFRrWJ33qj1wMKAG5ldHdvcmtfaWQbi5b8CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:light_blue_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR1AwAACAQAbmFtZR0AbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY29uY3JldGUECQBuYW1lX2hhc2gHAe0kl0SE4AMKAG5ldHdvcmtfaWRL/GbSCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:blue_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR9AwAACAQAbmFtZRcAbWluZWNyYWZ0OmJsdWVfY29uY3JldGUECQBuYW1lX2hhc2hiay301nnj1wMKAG5ldHdvcmtfaWRMvFXNCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:purple_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR8AwAACAQAbmFtZRkAbWluZWNyYWZ0OnB1cnBsZV9jb25jcmV0ZQQJAG5hbWVfaGFzaHBHflsPIwdXAwoAbmV0d29ya19pZCyKA5gKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:magenta_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR0AwAACAQAbmFtZRoAbWluZWNyYWZ0Om1hZ2VudGFfY29uY3JldGUECQBuYW1lX2hhc2gN7LuB/OvdZAMKAG5ldHdvcmtfaWTc6ZOdCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:pink_concrete", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR4AwAACAQAbmFtZRcAbWluZWNyYWZ0OnBpbmtfY29uY3JldGUECQBuYW1lX2hhc2ii2G5F0u3SOAMKAG5ldHdvcmtfaWSszGgrCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:clay", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRSAAAACAQAbmFtZQ4AbWluZWNyYWZ0OmNsYXkECQBuYW1lX2hhc2j/S6sKXRcpzwMKAG5ldHdvcmtfaWRmsb8nCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:hardened_clay", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSsAAAACAQAbmFtZRcAbWluZWNyYWZ0OmhhcmRlbmVkX2NsYXkECQBuYW1lX2hhc2jrnRwCJ0krJAMKAG5ldHdvcmtfaWRBCOrrCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:white_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSfAAAACAQAbmFtZRoAbWluZWNyYWZ0OndoaXRlX3RlcnJhY290dGEECQBuYW1lX2hhc2j3RSdgmnAIewMKAG5ldHdvcmtfaWSimKw+CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:light_gray_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTaAwAACAQAbmFtZR8AbWluZWNyYWZ0OmxpZ2h0X2dyYXlfdGVycmFjb3R0YQQJAG5hbWVfaGFzaAz1Ri3wIxomAwoAbmV0d29ya19pZH5qgOcKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:gray_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTZAwAACAQAbmFtZRkAbWluZWNyYWZ0OmdyYXlfdGVycmFjb3R0YQQJAG5hbWVfaGFzaAXdSLAaNZ9vAwoAbmV0d29ya19pZM1QDV0KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:black_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWThAwAACAQAbmFtZRoAbWluZWNyYWZ0OmJsYWNrX3RlcnJhY290dGEECQBuYW1lX2hhc2jxssdv5vlbpgMKAG5ldHdvcmtfaWRE3Ru/CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:brown_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTeAwAACAQAbmFtZRoAbWluZWNyYWZ0OmJyb3duX3RlcnJhY290dGEECQBuYW1lX2hhc2gG4kPenmOF9gMKAG5ldHdvcmtfaWQ/i0iNCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:red_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTgAwAACAQAbmFtZRgAbWluZWNyYWZ0OnJlZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNo7fX56HXFejEDCgBuZXR3b3JrX2lk8tTF8QoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:orange_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAwAACAQAbmFtZRsAbWluZWNyYWZ0Om9yYW5nZV90ZXJyYWNvdHRhBAkAbmFtZV9oYXNo0Hjmql3sruMDCgBuZXR3b3JrX2lklmqmkAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:yellow_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTWAwAACAQAbmFtZRsAbWluZWNyYWZ0OnllbGxvd190ZXJyYWNvdHRhBAkAbmFtZV9oYXNoqkyKKrmA3VcDCgBuZXR3b3JrX2lkaM/orAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:lime_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTXAwAACAQAbmFtZRkAbWluZWNyYWZ0OmxpbWVfdGVycmFjb3R0YQQJAG5hbWVfaGFzaANjADFOF9v7AwoAbmV0d29ya19pZJt0XsgKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:green_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTfAwAACAQAbmFtZRoAbWluZWNyYWZ0OmdyZWVuX3RlcnJhY290dGEECQBuYW1lX2hhc2j5Ybq36yYwRQMKAG5ldHdvcmtfaWQ8kGdHCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cyan_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTbAwAACAQAbmFtZRkAbWluZWNyYWZ0OmN5YW5fdGVycmFjb3R0YQQJAG5hbWVfaGFzaN09COzMuHwAAwoAbmV0d29ya19pZIWPCzoKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:light_blue_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTVAwAACAQAbmFtZR8AbWluZWNyYWZ0OmxpZ2h0X2JsdWVfdGVycmFjb3R0YQQJAG5hbWVfaGFzaOMytez7cOZiAwoAbmV0d29ya19pZFHK1UsKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:blue_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTdAwAACAQAbmFtZRkAbWluZWNyYWZ0OmJsdWVfdGVycmFjb3R0YQQJAG5hbWVfaGFzaF6inyTK5RpAAwoAbmV0d29ya19pZF5mVZIKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:purple_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTcAwAACAQAbmFtZRsAbWluZWNyYWZ0OnB1cnBsZV90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoKF7YG61yTbEDCgBuZXR3b3JrX2lkhtRDlwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:magenta_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTUAwAACAQAbmFtZRwAbWluZWNyYWZ0Om1hZ2VudGFfdGVycmFjb3R0YQQJAG5hbWVfaGFzaLWvtpAVtztyAwoAbmV0d29ya19pZN5SoakKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:pink_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTYAwAACAQAbmFtZRkAbWluZWNyYWZ0OnBpbmtfdGVycmFjb3R0YQQJAG5hbWVfaGFzaJ7mzvyzSQZTAwoAbmV0d29ya19pZDJWe4YKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:white_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTcAAAACAQAbmFtZSEAbWluZWNyYWZ0OndoaXRlX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoiVzCdoHAJo0DCgBuZXR3b3JrX2lkIlj9AAoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:silver_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTkAAAACAQAbmFtZSIAbWluZWNyYWZ0OnNpbHZlcl9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaAVsA0CnhzA4AwoAbmV0d29ya19pZPnxtJEKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:gray_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTjAAAACAQAbmFtZSAAbWluZWNyYWZ0OmdyYXlfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2jvLZt9u/lF/AMKAG5ldHdvcmtfaWQVU8eFCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:black_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTrAAAACAQAbmFtZSEAbWluZWNyYWZ0OmJsYWNrX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoe8I4xAXbO5UDCgBuZXR3b3JrX2lk2Icb9AoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:brown_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWToAAAACAQAbmFtZSEAbWluZWNyYWZ0OmJyb3duX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoSiNZOobbpjoDCgBuZXR3b3JrX2lkJy0jwgoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:red_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTqAAAACAQAbmFtZR8AbWluZWNyYWZ0OnJlZF9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaBdWFGLmCLFVAwoAbmV0d29ya19pZMYBJSEKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:orange_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTdAAAACAQAbmFtZSIAbWluZWNyYWZ0Om9yYW5nZV9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaMyJMrnPr7szAwoAbmV0d29ya19pZN6+7TUKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:yellow_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTgAAAACAQAbmFtZSIAbWluZWNyYWZ0OnllbGxvd19nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaN6NaIhf6m0uAwoAbmV0d29ya19pZKRHXeoKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:lime_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWThAAAACAQAbmFtZSAAbWluZWNyYWZ0OmxpbWVfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2iF3E68/rB2EAMKAG5ldHdvcmtfaWSP7qQWCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:green_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTpAAAACAQAbmFtZSEAbWluZWNyYWZ0OmdyZWVuX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNow5mo8aQDFboDCgBuZXR3b3JrX2lkoF11kgoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:cyan_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTlAAAACAQAbmFtZSAAbWluZWNyYWZ0OmN5YW5fZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2gnNB+cCFRJhwMKAG5ldHdvcmtfaWT9buMtCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:light_blue_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTfAAAACAQAbmFtZSYAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2gladnCDBKCigMKAG5ldHdvcmtfaWS5CszFCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:blue_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTnAAAACAQAbmFtZSAAbWluZWNyYWZ0OmJsdWVfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2giOZK+2nB1igMKAG5ldHdvcmtfaWR+e22CCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:purple_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTbAAAACAQAbmFtZSIAbWluZWNyYWZ0OnB1cnBsZV9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaIQU03txeAfHAwoAbmV0d29ya19pZLKbSE4KBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:magenta_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTeAAAACAQAbmFtZSMAbWluZWNyYWZ0Om1hZ2VudGFfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2i/SNqDJbfjMgMKAG5ldHdvcmtfaWQKf9UvCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:pink_glazed_terracotta", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTiAAAACAQAbmFtZSAAbWluZWNyYWZ0OnBpbmtfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2hik8DVt4g+twMKAG5ldHdvcmtfaWTKzav2CgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:purpur_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAAAACAQAbmFtZRYAbWluZWNyYWZ0OnB1cnB1cl9ibG9jawQJAG5hbWVfaGFzaAgLwnUZGlzsAwoAbmV0d29ya19pZLD8ox4KBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQcAZGVmYXVsdAgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:purpur_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAAAACAQAbmFtZRYAbWluZWNyYWZ0OnB1cnB1cl9ibG9jawQJAG5hbWVfaGFzaAgLwnUZGlzsAwoAbmV0d29ya19pZPSAFFsKBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQUAbGluZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:packed_mud", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTcAgAACAQAbmFtZRQAbWluZWNyYWZ0OnBhY2tlZF9tdWQECQBuYW1lX2hhc2gHOMa121h4FgMKAG5ldHdvcmtfaWTUb6LyCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:mud_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTaAgAACAQAbmFtZRQAbWluZWNyYWZ0Om11ZF9icmlja3MECQBuYW1lX2hhc2iDL/SVl/PewQMKAG5ldHdvcmtfaWSkBjaDCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:nether_wart_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTWAAAACAQAbmFtZRsAbWluZWNyYWZ0Om5ldGhlcl93YXJ0X2Jsb2NrBAkAbmFtZV9oYXNo9XGS4GNnlV4DCgBuZXR3b3JrX2lkh3apIgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:warped_wart_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTiAQAACAQAbmFtZRsAbWluZWNyYWZ0OndhcnBlZF93YXJ0X2Jsb2NrBAkAbmFtZV9oYXNo9IqDS9yUPJoDCgBuZXR3b3JrX2lkMpKAbAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:shroomlight", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTlAQAACAQAbmFtZRUAbWluZWNyYWZ0OnNocm9vbWxpZ2h0BAkAbmFtZV9oYXNoZHCHcHX/HYADCgBuZXR3b3JrX2lkLG2JiwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:crimson_nylium", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTnAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fbnlsaXVtBAkAbmFtZV9oYXNoOr6DJYW2bFYDCgBuZXR3b3JrX2lkuWpRDgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:warped_nylium", + "block_state_b64": "CgAAAwgAYmxvY2tfaWToAQAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9ueWxpdW0ECQBuYW1lX2hhc2g0Zf89cfr3rwMKAG5ldHdvcmtfaWSu/kekCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:netherrack", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRXAAAACAQAbmFtZRQAbWluZWNyYWZ0Om5ldGhlcnJhY2sECQBuYW1lX2hhc2i/r5ZyRsvPyQMKAG5ldHdvcmtfaWTAiTOACgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:basalt", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTpAQAACAQAbmFtZRAAbWluZWNyYWZ0OmJhc2FsdAQJAG5hbWVfaGFzaH+UQO2yWodiAwoAbmV0d29ya19pZBPNSV4KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:polished_basalt", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTqAQAACAQAbmFtZRkAbWluZWNyYWZ0OnBvbGlzaGVkX2Jhc2FsdAQJAG5hbWVfaGFzaMS+L0gMnRcBAwoAbmV0d29ya19pZF+/mHwKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:smooth_basalt", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR4AgAACAQAbmFtZRcAbWluZWNyYWZ0OnNtb290aF9iYXNhbHQECQBuYW1lX2hhc2jKPUdz89kuNAMKAG5ldHdvcmtfaWTkb/oVCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:soul_soil", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTrAQAACAQAbmFtZRMAbWluZWNyYWZ0OnNvdWxfc29pbAQJAG5hbWVfaGFzaC1/87ccutuTAwoAbmV0d29ya19pZKc63SMKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:dirt", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAAAACAQAbmFtZQ4AbWluZWNyYWZ0OmRpcnQECQBuYW1lX2hhc2hXp6jnXAe+kQMKAG5ldHdvcmtfaWQmkQtoCgYAc3RhdGVzCAkAZGlydF90eXBlBgBub3JtYWwAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:dirt", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAAAACAQAbmFtZQ4AbWluZWNyYWZ0OmRpcnQECQBuYW1lX2hhc2hXp6jnXAe+kQMKAG5ldHdvcmtfaWQId9pLCgYAc3RhdGVzCAkAZGlydF90eXBlBgBjb2Fyc2UAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:farmland", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ8AAAACAQAbmFtZRIAbWluZWNyYWZ0OmZhcm1sYW5kBAkAbmFtZV9oYXNoxyQ5ag7LolADCgBuZXR3b3JrX2lkX618FQoGAHN0YXRlcwMSAG1vaXN0dXJpemVkX2Ftb3VudAAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:grass_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQCAAAACAQAbmFtZRUAbWluZWNyYWZ0OmdyYXNzX2Jsb2NrBAkAbmFtZV9oYXNojPyGp3/CSZwDCgBuZXR3b3JrX2lktCgx3goGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:grass_path", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTGAAAACAQAbmFtZRQAbWluZWNyYWZ0OmdyYXNzX3BhdGgECQBuYW1lX2hhc2i0/KZV8Qsy+gMKAG5ldHdvcmtfaWT7CcdzCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:podzol", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTzAAAACAQAbmFtZRAAbWluZWNyYWZ0OnBvZHpvbAQJAG5hbWVfaGFzaBzqokRjH4Z1AwoAbmV0d29ya19pZPPS/GUKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:mycelium", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRuAAAACAQAbmFtZRIAbWluZWNyYWZ0Om15Y2VsaXVtBAkAbmFtZV9oYXNojTN09cKickIDCgBuZXR3b3JrX2lkLNPxXQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:mud", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTYAgAACAQAbmFtZQ0AbWluZWNyYWZ0Om11ZAQJAG5hbWVfaGFzaPb/3P+uLy+9AwoAbmV0d29ya19pZPIUlUkKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQBAAAACAQAbmFtZQ8AbWluZWNyYWZ0OnN0b25lBAkAbmFtZV9oYXNoE3mqhJxzJycDCgBuZXR3b3JrX2lkIQ4xgAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:iron_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQPAAAACAQAbmFtZRIAbWluZWNyYWZ0Omlyb25fb3JlBAkAbmFtZV9oYXNoS7BYtLnfx3gDCgBuZXR3b3JrX2lk3loneQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:gold_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQOAAAACAQAbmFtZRIAbWluZWNyYWZ0OmdvbGRfb3JlBAkAbmFtZV9oYXNoC5Y+DUGXLC4DCgBuZXR3b3JrX2lkNhvMfwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:diamond_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ4AAAACAQAbmFtZRUAbWluZWNyYWZ0OmRpYW1vbmRfb3JlBAkAbmFtZV9oYXNokUOJ2wZZrGQDCgBuZXR3b3JrX2lk/dChVAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:lapis_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQVAAAACAQAbmFtZRMAbWluZWNyYWZ0OmxhcGlzX29yZQQJAG5hbWVfaGFzaMrmrUrSzb7qAwoAbmV0d29ya19pZMg+qK4KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:redstone_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRJAAAACAQAbmFtZRYAbWluZWNyYWZ0OnJlZHN0b25lX29yZQQJAG5hbWVfaGFzaFHVnp8Wc4JbAwoAbmV0d29ya19pZKDYvQoKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:coal_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQQAAAACAQAbmFtZRIAbWluZWNyYWZ0OmNvYWxfb3JlBAkAbmFtZV9oYXNo1OjA+Iuy51oDCgBuZXR3b3JrX2lk+R/aKAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:copper_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ2AgAACAQAbmFtZRQAbWluZWNyYWZ0OmNvcHBlcl9vcmUECQBuYW1lX2hhc2iSZduSntOzOwMKAG5ldHdvcmtfaWQtIuCnCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:emerald_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSBAAAACAQAbmFtZRUAbWluZWNyYWZ0OmVtZXJhbGRfb3JlBAkAbmFtZV9oYXNoJTovr+VgINsDCgBuZXR3b3JrX2lknbkqCgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:quartz_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSZAAAACAQAbmFtZRQAbWluZWNyYWZ0OnF1YXJ0el9vcmUECQBuYW1lX2hhc2g0yNHLMK9TaQMKAG5ldHdvcmtfaWSzN7nzCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:nether_gold_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQfAgAACAQAbmFtZRkAbWluZWNyYWZ0Om5ldGhlcl9nb2xkX29yZQQJAG5hbWVfaGFzaEJZ7segIBgBAwoAbmV0d29ya19pZNI9pDgKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:ancient_debris", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQOAgAACAQAbmFtZRgAbWluZWNyYWZ0OmFuY2llbnRfZGVicmlzBAkAbmFtZV9oYXNoNrbxMc9AwKcDCgBuZXR3b3JrX2lkrSNjEAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:deepslate_iron_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSQAgAACAQAbmFtZRwAbWluZWNyYWZ0OmRlZXBzbGF0ZV9pcm9uX29yZQQJAG5hbWVfaGFzaB/fDL9pgvXXAwoAbmV0d29ya19pZFA0bz4KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:deepslate_gold_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAgAACAQAbmFtZRwAbWluZWNyYWZ0OmRlZXBzbGF0ZV9nb2xkX29yZQQJAG5hbWVfaGFzaF9G7WYhKFinAwoAbmV0d29ya19pZHQTfBUKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:deepslate_diamond_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSUAgAACAQAbmFtZR8AbWluZWNyYWZ0OmRlZXBzbGF0ZV9kaWFtb25kX29yZQQJAG5hbWVfaGFzaEUH5USh+iD3AwoAbmV0d29ya19pZHP6VzAKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:deepslate_lapis_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSPAgAACAQAbmFtZR0AbWluZWNyYWZ0OmRlZXBzbGF0ZV9sYXBpc19vcmUECQBuYW1lX2hhc2j+yFxU/KZs1gMKAG5ldHdvcmtfaWRKINzICgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:deepslate_redstone_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSSAgAACAQAbmFtZSAAbWluZWNyYWZ0OmRlZXBzbGF0ZV9yZWRzdG9uZV9vcmUECQBuYW1lX2hhc2iVgM3wWWD6ugMKAG5ldHdvcmtfaWReBdYRCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:deepslate_emerald_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSWAgAACAQAbmFtZR8AbWluZWNyYWZ0OmRlZXBzbGF0ZV9lbWVyYWxkX29yZQQJAG5hbWVfaGFzaNlfo5HTwS6wAwoAbmV0d29ya19pZNeie6sKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:deepslate_coal_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSVAgAACAQAbmFtZRwAbWluZWNyYWZ0OmRlZXBzbGF0ZV9jb2FsX29yZQQJAG5hbWVfaGFzaIjikmcbRrPPAwoAbmV0d29ya19pZD9TiygKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:deepslate_copper_ore", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSXAgAACAQAbmFtZR4AbWluZWNyYWZ0OmRlZXBzbGF0ZV9jb3BwZXJfb3JlBAkAbmFtZV9oYXNottjV4Ev5LAQDCgBuZXR3b3JrX2lkP23rgQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:gravel", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQNAAAACAQAbmFtZRAAbWluZWNyYWZ0OmdyYXZlbAQJAG5hbWVfaGFzaOFxz8XJd2r/AwoAbmV0d29ya19pZBpfI1sKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:granite", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRNAwAACAQAbmFtZREAbWluZWNyYWZ0OmdyYW5pdGUECQBuYW1lX2hhc2iq+Dur2pw4AwMKAG5ldHdvcmtfaWT2NMfJCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:diorite", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRPAwAACAQAbmFtZREAbWluZWNyYWZ0OmRpb3JpdGUECQBuYW1lX2hhc2iaFsq2iinZBQMKAG5ldHdvcmtfaWQqGE6XCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:andesite", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRRAwAACAQAbmFtZRIAbWluZWNyYWZ0OmFuZGVzaXRlBAkAbmFtZV9oYXNosaLIEnQQoSYDCgBuZXR3b3JrX2lkEApRZAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:blackstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQQAgAACAQAbmFtZRQAbWluZWNyYWZ0OmJsYWNrc3RvbmUECQBuYW1lX2hhc2iMFYziD80D6QMKAG5ldHdvcmtfaWSrUryHCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:deepslate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR5AgAACAQAbmFtZRMAbWluZWNyYWZ0OmRlZXBzbGF0ZQQJAG5hbWVfaGFzaKX5pAblxz8TAwoAbmV0d29ya19pZOJoQjsKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:polished_granite", + "block_state_b64": "CgAAAwgAYmxvY2tfaWROAwAACAQAbmFtZRoAbWluZWNyYWZ0OnBvbGlzaGVkX2dyYW5pdGUECQBuYW1lX2hhc2iLiEfys8pFIAMKAG5ldHdvcmtfaWTCxxcHCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:polished_diorite", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRQAwAACAQAbmFtZRoAbWluZWNyYWZ0OnBvbGlzaGVkX2Rpb3JpdGUECQBuYW1lX2hhc2hTxY4fKmNmlAMKAG5ldHdvcmtfaWTmtjdRCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:polished_andesite", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRSAwAACAQAbmFtZRsAbWluZWNyYWZ0OnBvbGlzaGVkX2FuZGVzaXRlBAkAbmFtZV9oYXNovl28uFk4HuQDCgBuZXR3b3JrX2lklFjuCwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:polished_blackstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQiAgAACAQAbmFtZR0AbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmUECQBuYW1lX2hhc2jT9fHCl6vWQQMKAG5ldHdvcmtfaWR/Ho6oCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:polished_deepslate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR+AgAACAQAbmFtZRwAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZQQJAG5hbWVfaGFzaHC1edoaWF3uAwoAbmV0d29ya19pZCPeQsEKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:sand", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQMAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnNhbmQECQBuYW1lX2hhc2i6lthXXbAyWAMKAG5ldHdvcmtfaWTekU/mCgYAc3RhdGVzCAkAc2FuZF90eXBlBgBub3JtYWwAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:sand", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQMAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnNhbmQECQBuYW1lX2hhc2i6lthXXbAyWAMKAG5ldHdvcmtfaWSTgcqmCgYAc3RhdGVzCAkAc2FuZF90eXBlAwByZWQAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cactus", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRRAAAACAQAbmFtZRAAbWluZWNyYWZ0OmNhY3R1cwQJAG5hbWVfaGFzaCG9zL0N4wvGAwoAbmV0d29ya19pZDeCERAKBgBzdGF0ZXMDAwBhZ2UAAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:oak_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQRAAAACAQAbmFtZREAbWluZWNyYWZ0Om9ha19sb2cECQBuYW1lX2hhc2ho6TS+K7PZFQMKAG5ldHdvcmtfaWQjfjoxCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stripped_oak_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQJAQAACAQAbmFtZRoAbWluZWNyYWZ0OnN0cmlwcGVkX29ha19sb2cECQBuYW1lX2hhc2h8dqh+OOHU4wMKAG5ldHdvcmtfaWSYKjdrCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:spruce_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ4AwAACAQAbmFtZRQAbWluZWNyYWZ0OnNwcnVjZV9sb2cECQBuYW1lX2hhc2hZ03qaLoF3WgMKAG5ldHdvcmtfaWRlFD8eCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stripped_spruce_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQEAQAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX3NwcnVjZV9sb2cECQBuYW1lX2hhc2iNrhKjS5IyrgMKAG5ldHdvcmtfaWRQcEC3CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:birch_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ5AwAACAQAbmFtZRMAbWluZWNyYWZ0OmJpcmNoX2xvZwQJAG5hbWVfaGFzaBUzT3NxsZAnAwoAbmV0d29ya19pZBKN3VQKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stripped_birch_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQFAQAACAQAbmFtZRwAbWluZWNyYWZ0OnN0cmlwcGVkX2JpcmNoX2xvZwQJAG5hbWVfaGFzaCFKS4AeuSidAwoAbmV0d29ya19pZN0IONIKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:jungle_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ6AwAACAQAbmFtZRQAbWluZWNyYWZ0Omp1bmdsZV9sb2cECQBuYW1lX2hhc2gkwW0KNulqDgMKAG5ldHdvcmtfaWQaziU/CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stripped_jungle_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAQAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2p1bmdsZV9sb2cECQBuYW1lX2hhc2hAwMsgOk02JAMKAG5ldHdvcmtfaWQvls0eCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:acacia_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSiAAAACAQAbmFtZRQAbWluZWNyYWZ0OmFjYWNpYV9sb2cECQBuYW1lX2hhc2iV48VpYhjoYQMKAG5ldHdvcmtfaWRxEqe0CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stripped_acacia_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQHAQAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2FjYWNpYV9sb2cECQBuYW1lX2hhc2hJb0lQqnEqlgMKAG5ldHdvcmtfaWRg3IdRCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:dark_oak_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ7AwAACAQAbmFtZRYAbWluZWNyYWZ0OmRhcmtfb2FrX2xvZwQJAG5hbWVfaGFzaIWfVRd0XUo3AwoAbmV0d29ya19pZPMM7LYKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stripped_dark_oak_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQIAQAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX2Rhcmtfb2FrX2xvZwQJAG5hbWVfaGFzaPFTdxRdPwkOAwoAbmV0d29ya19pZDIzenIKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:mangrove_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTjAgAACAQAbmFtZRYAbWluZWNyYWZ0Om1hbmdyb3ZlX2xvZwQJAG5hbWVfaGFzaHZe6DzPZBobAwoAbmV0d29ya19pZG6DuYkKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stripped_mangrove_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTkAgAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX21hbmdyb3ZlX2xvZwQJAG5hbWVfaGFzaLqIBo4hwA//AwoAbmV0d29ya19pZPtRn7UKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cherry_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQXAwAACAQAbmFtZRQAbWluZWNyYWZ0OmNoZXJyeV9sb2cECQBuYW1lX2hhc2hwFlaioppB1wMKAG5ldHdvcmtfaWS2sdXECgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stripped_cherry_log", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQWAwAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2NoZXJyeV9sb2cECQBuYW1lX2hhc2i85H6G+WhXaAMKAG5ldHdvcmtfaWRjzoglCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:crimson_stem", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTgAQAACAQAbmFtZRYAbWluZWNyYWZ0OmNyaW1zb25fc3RlbQQJAG5hbWVfaGFzaM0FzfL0UTKZAwoAbmV0d29ya19pZKvzID0KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stripped_crimson_stem", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTvAQAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX2NyaW1zb25fc3RlbQQJAG5hbWVfaGFzaDlA6nood57EAwoAbmV0d29ya19pZHrIqjIKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:warped_stem", + "block_state_b64": "CgAAAwgAYmxvY2tfaWThAQAACAQAbmFtZRUAbWluZWNyYWZ0OndhcnBlZF9zdGVtBAkAbmFtZV9oYXNon7cKfPZxdrUDCgBuZXR3b3JrX2lkerWyMwoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stripped_warped_stem", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTwAQAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX3dhcnBlZF9zdGVtBAkAbmFtZV9oYXNoEw+y0dDPSd8DCgBuZXR3b3JrX2lkIQ9vBAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:oak_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAQAACAQAbmFtZRIAbWluZWNyYWZ0Om9ha193b29kBAkAbmFtZV9oYXNoqQIkuVPyJX0DCgBuZXR3b3JrX2lku2G1YAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:spruce_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQtBAAACAQAbmFtZRUAbWluZWNyYWZ0OnNwcnVjZV93b29kBAkAbmFtZV9oYXNoTrIJ5TAQ+OgDCgBuZXR3b3JrX2lkaXLxCwoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:birch_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQuBAAACAQAbmFtZRQAbWluZWNyYWZ0OmJpcmNoX3dvb2QECQBuYW1lX2hhc2iqVjG4xt0cKQMKAG5ldHdvcmtfaWS06c5VCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:jungle_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQvBAAACAQAbmFtZRUAbWluZWNyYWZ0Omp1bmdsZV93b29kBAkAbmFtZV9oYXNo9bYW29ORWCoDCgBuZXR3b3JrX2lkyFyKLQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:acacia_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQwBAAACAQAbmFtZRUAbWluZWNyYWZ0OmFjYWNpYV93b29kBAkAbmFtZV9oYXNoKkDfgzlJUcIDCgBuZXR3b3JrX2lkuTWlcgoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:dark_oak_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQxBAAACAQAbmFtZRcAbWluZWNyYWZ0OmRhcmtfb2FrX3dvb2QECQBuYW1lX2hhc2jaKv4ORLadAAMKAG5ldHdvcmtfaWSDrNQ8CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stripped_oak_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQyBAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0cmlwcGVkX29ha193b29kBAkAbmFtZV9oYXNovW6KCv+VZnsDCgBuZXR3b3JrX2lkkhWGegoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stripped_spruce_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQzBAAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX3NwcnVjZV93b29kBAkAbmFtZV9oYXNoMnuUk4Xo6icDCgBuZXR3b3JrX2lkes2ydAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stripped_birch_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ0BAAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2JpcmNoX3dvb2QECQBuYW1lX2hhc2hm88R604TKbAMKAG5ldHdvcmtfaWRleEMJCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stripped_jungle_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ1BAAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX2p1bmdsZV93b29kBAkAbmFtZV9oYXNoUVs6KsZQRBoDCgBuZXR3b3JrX2lk92k8HQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stripped_acacia_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ2BAAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX2FjYWNpYV93b29kBAkAbmFtZV9oYXNo/kOPN2bCJhUDCgBuZXR3b3JrX2lktl6LwQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stripped_dark_oak_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ3BAAACAQAbmFtZSAAbWluZWNyYWZ0OnN0cmlwcGVkX2Rhcmtfb2FrX3dvb2QECQBuYW1lX2hhc2h2jFDfKVFgfAMKAG5ldHdvcmtfaWTgZQ5VCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:mangrove_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTwAgAACAQAbmFtZRcAbWluZWNyYWZ0Om1hbmdyb3ZlX3dvb2QECQBuYW1lX2hhc2iXVxG0JG2fVAMKAG5ldHdvcmtfaWTok1JCCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stripped_mangrove_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTxAgAACAQAbmFtZSAAbWluZWNyYWZ0OnN0cmlwcGVkX21hbmdyb3ZlX3dvb2QECQBuYW1lX2hhc2h7CkbaBF7/WAMKAG5ldHdvcmtfaWQLAX88CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cherry_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQhAwAACAQAbmFtZRUAbWluZWNyYWZ0OmNoZXJyeV93b29kBAkAbmFtZV9oYXNoAW8srlmpBM8DCgBuZXR3b3JrX2lkEALMfAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AQwAc3RyaXBwZWRfYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stripped_cherry_wood", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQgAwAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX2NoZXJyeV93b29kBAkAbmFtZV9oYXNo/e7KXv+CB38DCgBuZXR3b3JrX2lkg5aVtQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:crimson_hyphae", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQqAgAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25faHlwaGFlBAkAbmFtZV9oYXNouRmKmfSqEWADCgBuZXR3b3JrX2lk+Tm5rQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stripped_crimson_hyphae", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQrAgAACAQAbmFtZSEAbWluZWNyYWZ0OnN0cmlwcGVkX2NyaW1zb25faHlwaGFlBAkAbmFtZV9oYXNoFffwmABq4LUDCgBuZXR3b3JrX2lkZAlUbgoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:warped_hyphae", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQpAgAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9oeXBoYWUECQBuYW1lX2hhc2hn8plQUr6pmQMKAG5ldHdvcmtfaWRU2AIBCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:stripped_warped_hyphae", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAgAACAQAbmFtZSAAbWluZWNyYWZ0OnN0cmlwcGVkX3dhcnBlZF9oeXBoYWUECQBuYW1lX2hhc2irKq+HYPSgjQMKAG5ldHdvcmtfaWSbrOPDCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:bamboo_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQOAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJhbWJvb19ibG9jawQJAG5hbWVfaGFzaAbDeur6stIBAwoAbmV0d29ya19pZCJAwn0KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:stripped_bamboo_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQPAwAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX2JhbWJvb19ibG9jawQJAG5hbWVfaGFzaJpwytpZOZM9AwoAbmV0d29ya19pZKuRbNEKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:oak_leaves", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQSAAAACAQAbmFtZRQAbWluZWNyYWZ0Om9ha19sZWF2ZXMECQBuYW1lX2hhc2h6O4xGqA2oKgMKAG5ldHdvcmtfaWT98c59CgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:spruce_leaves", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQfBAAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9sZWF2ZXMECQBuYW1lX2hhc2i9x1CtNAuqZwMKAG5ldHdvcmtfaWSzF7pTCgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:birch_leaves", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQgBAAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX2xlYXZlcwQJAG5hbWVfaGFzaBlAGHaoaLZSAwoAbmV0d29ya19pZOjtvWcKBgBzdGF0ZXMBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:jungle_leaves", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQhBAAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9sZWF2ZXMECQBuYW1lX2hhc2iW1uAH07zGhgMKAG5ldHdvcmtfaWSA5KX0CgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:acacia_leaves", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAAAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9sZWF2ZXMECQBuYW1lX2hhc2iZJf8dAgDRNQMKAG5ldHdvcmtfaWQ/G7VuCgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:dark_oak_leaves", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQiBAAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX2xlYXZlcwQJAG5hbWVfaGFzaCk7rDipWFSjAwoAbmV0d29ya19pZJ2AkbYKBgBzdGF0ZXMBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:mangrove_leaves", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTXAgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX2xlYXZlcwQJAG5hbWVfaGFzaKyI/dWvhEG8AwoAbmV0d29ya19pZPQxCZ8KBgBzdGF0ZXMBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cherry_leaves", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQjAwAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9sZWF2ZXMECQBuYW1lX2hhc2giTs9ChhYBlQMKAG5ldHdvcmtfaWR8bPpwCgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:azalea_leaves", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRDAgAACAQAbmFtZRcAbWluZWNyYWZ0OmF6YWxlYV9sZWF2ZXMECQBuYW1lX2hhc2iXFhD57wFS7AMKAG5ldHdvcmtfaWTNB/9ECgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:azalea_leaves_flowered", + "block_state_b64": "CgAAAwgAYmxvY2tfaWREAgAACAQAbmFtZSAAbWluZWNyYWZ0OmF6YWxlYV9sZWF2ZXNfZmxvd2VyZWQECQBuYW1lX2hhc2gs8jxlS/pMrwMKAG5ldHdvcmtfaWQ7W4PyCgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:oak_sapling", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAAAACAQAbmFtZRUAbWluZWNyYWZ0Om9ha19zYXBsaW5nBAkAbmFtZV9oYXNoogXcT9QfjiUDCgBuZXR3b3JrX2lkG22C+AoGAHN0YXRlcwEHAGFnZV9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:spruce_sapling", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ4BAAACAQAbmFtZRgAbWluZWNyYWZ0OnNwcnVjZV9zYXBsaW5nBAkAbmFtZV9oYXNoe8hz4uYP0FcDCgBuZXR3b3JrX2lkUQmhaQoGAHN0YXRlcwEHAGFnZV9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:birch_sapling", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ5BAAACAQAbmFtZRcAbWluZWNyYWZ0OmJpcmNoX3NhcGxpbmcECQBuYW1lX2hhc2h348iJQ/tK4wMKAG5ldHdvcmtfaWQ2Uh53CgYAc3RhdGVzAQcAYWdlX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:jungle_sapling", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ6BAAACAQAbmFtZRgAbWluZWNyYWZ0Omp1bmdsZV9zYXBsaW5nBAkAbmFtZV9oYXNo7tyTOdSrxaADCgBuZXR3b3JrX2lkXmBAdAoGAHN0YXRlcwEHAGFnZV9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:acacia_sapling", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ7BAAACAQAbmFtZRgAbWluZWNyYWZ0OmFjYWNpYV9zYXBsaW5nBAkAbmFtZV9oYXNo99sg15uoX7ADCgBuZXR3b3JrX2lkPXX1KgoGAHN0YXRlcwEHAGFnZV9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:dark_oak_sapling", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ8BAAACAQAbmFtZRoAbWluZWNyYWZ0OmRhcmtfb2FrX3NhcGxpbmcECQBuYW1lX2hhc2jnVzFplW7cHgMKAG5ldHdvcmtfaWTD4giHCgYAc3RhdGVzAQcAYWdlX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:mangrove_propagule", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTZAgAACAQAbmFtZRwAbWluZWNyYWZ0Om1hbmdyb3ZlX3Byb3BhZ3VsZQQJAG5hbWVfaGFzaJGeox6hkfLFAwoAbmV0d29ya19pZAIpvpYKBgBzdGF0ZXMBBwBoYW5naW5nAAMPAHByb3BhZ3VsZV9zdGFnZQAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cherry_sapling", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQiAwAACAQAbmFtZRgAbWluZWNyYWZ0OmNoZXJyeV9zYXBsaW5nBAkAbmFtZV9oYXNoGrPpNMf1LtcDCgBuZXR3b3JrX2lkypakXQoGAHN0YXRlcwEHAGFnZV9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:bee_nest", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTZAQAACAQAbmFtZRIAbWluZWNyYWZ0OmJlZV9uZXN0BAkAbmFtZV9oYXNo2R2WBxUHEZIDCgBuZXR3b3JrX2lkiXWLEAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAADCwBob25leV9sZXZlbAAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:wheat_seeds" + }, + { + "id": "minecraft:pumpkin_seeds" + }, + { + "id": "minecraft:melon_seeds" + }, + { + "id": "minecraft:beetroot_seeds" + }, + { + "id": "minecraft:torchflower_seeds" + }, + { + "id": "minecraft:pitcher_pod" + }, + { + "id": "minecraft:wheat" + }, + { + "id": "minecraft:beetroot" + }, + { + "id": "minecraft:potato" + }, + { + "id": "minecraft:poisonous_potato" + }, + { + "id": "minecraft:carrot" + }, + { + "id": "minecraft:golden_carrot" + }, + { + "id": "minecraft:apple" + }, + { + "id": "minecraft:golden_apple" + }, + { + "id": "minecraft:enchanted_golden_apple" + }, + { + "id": "minecraft:melon_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRnAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1lbG9uX2Jsb2NrBAkAbmFtZV9oYXNoXxSm0iYpAx8DCgBuZXR3b3JrX2lkC9rqygoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:melon_slice" + }, + { + "id": "minecraft:glistering_melon_slice" + }, + { + "id": "minecraft:sweet_berries" + }, + { + "id": "minecraft:glow_berries" + }, + { + "id": "minecraft:pumpkin", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRWAAAACAQAbmFtZREAbWluZWNyYWZ0OnB1bXBraW4ECQBuYW1lX2hhc2gc8A3jaSzWbgMKAG5ldHdvcmtfaWRFGA+xCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:carved_pumpkin", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSaAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNhcnZlZF9wdW1wa2luBAkAbmFtZV9oYXNoPu1T0MJuG90DCgBuZXR3b3JrX2lkXNNn5QoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:lit_pumpkin", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRbAAAACAQAbmFtZRUAbWluZWNyYWZ0OmxpdF9wdW1wa2luBAkAbmFtZV9oYXNo7gWtEm2uPL0DCgBuZXR3b3JrX2lki8sU4AoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:honeycomb" + }, + { + "id": "minecraft:tallgrass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQfAAAACAQAbmFtZRMAbWluZWNyYWZ0OnRhbGxncmFzcwQJAG5hbWVfaGFzaC3PXpAXXYswAwoAbmV0d29ya19pZOh33DMKBgBzdGF0ZXMIDwB0YWxsX2dyYXNzX3R5cGUEAGZlcm4AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:double_plant", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZMx1sfgKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQQAZmVybgEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:tallgrass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQfAAAACAQAbmFtZRMAbWluZWNyYWZ0OnRhbGxncmFzcwQJAG5hbWVfaGFzaC3PXpAXXYswAwoAbmV0d29ya19pZErptfIKBgBzdGF0ZXMIDwB0YWxsX2dyYXNzX3R5cGUEAHRhbGwAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:double_plant", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZAbadmIKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQUAZ3Jhc3MBDwB1cHBlcl9ibG9ja19iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:nether_sprouts" + }, + { + "id": "minecraft:fire_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRGAwAACAQAbmFtZRQAbWluZWNyYWZ0OmZpcmVfY29yYWwECQBuYW1lX2hhc2hOHyyECVQVJwMKAG5ldHdvcmtfaWS9vF0UCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:brain_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWREAwAACAQAbmFtZRUAbWluZWNyYWZ0OmJyYWluX2NvcmFsBAkAbmFtZV9oYXNoRiWlLCwA2ycDCgBuZXR3b3JrX2lkrjAuhgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:bubble_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRFAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJ1YmJsZV9jb3JhbAQJAG5hbWVfaGFzaJz6rWnl+v2qAwoAbmV0d29ya19pZImIWy0KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:tube_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSCAQAACAQAbmFtZRQAbWluZWNyYWZ0OnR1YmVfY29yYWwECQBuYW1lX2hhc2iYa8oO/tgk7wMKAG5ldHdvcmtfaWRTfND5CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:horn_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRHAwAACAQAbmFtZRQAbWluZWNyYWZ0Omhvcm5fY29yYWwECQBuYW1lX2hhc2iZnRHjZbnLPgMKAG5ldHdvcmtfaWR+GGp8CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:dead_fire_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRLAwAACAQAbmFtZRkAbWluZWNyYWZ0OmRlYWRfZmlyZV9jb3JhbAQJAG5hbWVfaGFzaEPU6tFy/latAwoAbmV0d29ya19pZNMa7V4KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:dead_brain_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRJAwAACAQAbmFtZRoAbWluZWNyYWZ0OmRlYWRfYnJhaW5fY29yYWwECQBuYW1lX2hhc2j5L6QJCISvzwMKAG5ldHdvcmtfaWQkKzeiCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:dead_bubble_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRKAwAACAQAbmFtZRsAbWluZWNyYWZ0OmRlYWRfYnViYmxlX2NvcmFsBAkAbmFtZV9oYXNoSTOZ/8wpeNYDCgBuZXR3b3JrX2lka6w9DAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:dead_tube_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRIAwAACAQAbmFtZRkAbWluZWNyYWZ0OmRlYWRfdHViZV9jb3JhbAQJAG5hbWVfaGFzaJGjNWhlaIJeAwoAbmV0d29ya19pZO3Z0ygKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:dead_horn_coral", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRMAwAACAQAbmFtZRkAbWluZWNyYWZ0OmRlYWRfaG9ybl9jb3JhbAQJAG5hbWVfaGFzaJBkz3qt+g2cAwoAbmV0d29ya19pZBAN+eYKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:fire_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRJBAAACAQAbmFtZRgAbWluZWNyYWZ0OmZpcmVfY29yYWxfZmFuBAkAbmFtZV9oYXNosOTxYYxsDLgDCgBuZXR3b3JrX2lkFKxbEgoGAHN0YXRlcwMTAGNvcmFsX2Zhbl9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:brain_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRHBAAACAQAbmFtZRkAbWluZWNyYWZ0OmJyYWluX2NvcmFsX2ZhbgQJAG5hbWVfaGFzaAi5uHizSNcqAwoAbmV0d29ya19pZFtLjNwKBgBzdGF0ZXMDEwBjb3JhbF9mYW5fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:bubble_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRIBAAACAQAbmFtZRoAbWluZWNyYWZ0OmJ1YmJsZV9jb3JhbF9mYW4ECQBuYW1lX2hhc2hy/rX2on17DgMKAG5ldHdvcmtfaWQof60VCgYAc3RhdGVzAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:tube_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAQAACAQAbmFtZRgAbWluZWNyYWZ0OnR1YmVfY29yYWxfZmFuBAkAbmFtZV9oYXNo9pbJbo+PphIDCgBuZXR3b3JrX2lkenDTYgoGAHN0YXRlcwMTAGNvcmFsX2Zhbl9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:horn_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRKBAAACAQAbmFtZRgAbWluZWNyYWZ0Omhvcm5fY29yYWxfZmFuBAkAbmFtZV9oYXNoA+ri6NPDkbUDCgBuZXR3b3JrX2lkezoHNwoGAHN0YXRlcwMTAGNvcmFsX2Zhbl9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:dead_fire_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRNBAAACAQAbmFtZR0AbWluZWNyYWZ0OmRlYWRfZmlyZV9jb3JhbF9mYW4ECQBuYW1lX2hhc2hpQO02NDxPvwMKAG5ldHdvcmtfaWTaOJgLCgYAc3RhdGVzAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:dead_brain_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRLBAAACAQAbmFtZR4AbWluZWNyYWZ0OmRlYWRfYnJhaW5fY29yYWxfZmFuBAkAbmFtZV9oYXNoI9/+Z4YqMhIDCgBuZXR3b3JrX2lkqYXxYgoGAHN0YXRlcwMTAGNvcmFsX2Zhbl9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:dead_bubble_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRMBAAACAQAbmFtZR8AbWluZWNyYWZ0OmRlYWRfYnViYmxlX2NvcmFsX2ZhbgQJAG5hbWVfaGFzaBNECtIM6VIOAwoAbmV0d29ya19pZLrNtBEKBgBzdGF0ZXMDEwBjb3JhbF9mYW5fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:dead_tube_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAQAACAQAbmFtZR0AbWluZWNyYWZ0OmRlYWRfdHViZV9jb3JhbF9mYW4ECQBuYW1lX2hhc2hbBBM9jFKWvQMKAG5ldHdvcmtfaWSkJKUWCgYAc3RhdGVzAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:dead_horn_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWROBAAACAQAbmFtZR0AbWluZWNyYWZ0OmRlYWRfaG9ybl9jb3JhbF9mYW4ECQBuYW1lX2hhc2hObElFrHfPygMKAG5ldHdvcmtfaWQ1ZxvmCgYAc3RhdGVzAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:crimson_roots", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTeAQAACAQAbmFtZRcAbWluZWNyYWZ0OmNyaW1zb25fcm9vdHMECQBuYW1lX2hhc2j1fWgQLViv5QMKAG5ldHdvcmtfaWRLh5DXCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:warped_roots", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTfAQAACAQAbmFtZRYAbWluZWNyYWZ0OndhcnBlZF9yb290cwQJAG5hbWVfaGFzaBc3WvbJOLlkAwoAbmV0d29ya19pZNLgDnAKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:yellow_flower", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQlAAAACAQAbmFtZRcAbWluZWNyYWZ0OnllbGxvd19mbG93ZXIECQBuYW1lX2hhc2jWbU1pF0OUGAMKAG5ldHdvcmtfaWQgO3hpCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:poppy", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZQ8AbWluZWNyYWZ0OnBvcHB5BAkAbmFtZV9oYXNocMF8pITMbkcDCgBuZXR3b3JrX2lk8im6ywoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:blue_orchid", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ9BAAACAQAbmFtZRUAbWluZWNyYWZ0OmJsdWVfb3JjaGlkBAkAbmFtZV9oYXNoBjz2MsgB21EDCgBuZXR3b3JrX2lk/iLsSwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:allium", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ+BAAACAQAbmFtZRAAbWluZWNyYWZ0OmFsbGl1bQQJAG5hbWVfaGFzaDCGQBHNDTkcAwoAbmV0d29ya19pZD9Dgr0KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:azure_bluet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ/BAAACAQAbmFtZRUAbWluZWNyYWZ0OmF6dXJlX2JsdWV0BAkAbmFtZV9oYXNo9N5egqMT2QcDCgBuZXR3b3JrX2lkwIgDnwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:red_tulip", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRABAAACAQAbmFtZRMAbWluZWNyYWZ0OnJlZF90dWxpcAQJAG5hbWVfaGFzaAjMi9Rd+6rhAwoAbmV0d29ya19pZAZCnt8KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:orange_tulip", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRBBAAACAQAbmFtZRYAbWluZWNyYWZ0Om9yYW5nZV90dWxpcAQJAG5hbWVfaGFzaP+NjxMBZ8vAAwoAbmV0d29ya19pZPYatsMKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:white_tulip", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRCBAAACAQAbmFtZRUAbWluZWNyYWZ0OndoaXRlX3R1bGlwBAkAbmFtZV9oYXNo5vbU4VRPh3ADCgBuZXR3b3JrX2lkok+4rQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:pink_tulip", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRDBAAACAQAbmFtZRQAbWluZWNyYWZ0OnBpbmtfdHVsaXAECQBuYW1lX2hhc2hxDHZa6OaNXAMKAG5ldHdvcmtfaWTiOT+VCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:oxeye_daisy", + "block_state_b64": "CgAAAwgAYmxvY2tfaWREBAAACAQAbmFtZRUAbWluZWNyYWZ0Om94ZXllX2RhaXN5BAkAbmFtZV9oYXNoXwxsqNQTN9gDCgBuZXR3b3JrX2lkw7R7dwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cornflower", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRFBAAACAQAbmFtZRQAbWluZWNyYWZ0OmNvcm5mbG93ZXIECQBuYW1lX2hhc2gnhyC3EeqHgAMKAG5ldHdvcmtfaWR4VrvACgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:lily_of_the_valley", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRGBAAACAQAbmFtZRwAbWluZWNyYWZ0OmxpbHlfb2ZfdGhlX3ZhbGxleQQJAG5hbWVfaGFzaI64TJSf9mgQAwoAbmV0d29ya19pZFE9+nwKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:double_plant", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZOemRt4KBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQkAc3VuZmxvd2VyAQ8AdXBwZXJfYmxvY2tfYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:double_plant", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZOFugoEKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQcAc3lyaW5nYQEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:double_plant", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZN4O+/gKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQQAcm9zZQEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:double_plant", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZI3w4GMKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQcAcGFlb25pYQEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:pitcher_plant", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAwAACAQAbmFtZRcAbWluZWNyYWZ0OnBpdGNoZXJfcGxhbnQECQBuYW1lX2hhc2hRJHzsbDH+SQMKAG5ldHdvcmtfaWRnY76VCgYAc3RhdGVzAQ8AdXBwZXJfYmxvY2tfYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:pink_petals", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQkAwAACAQAbmFtZRUAbWluZWNyYWZ0OnBpbmtfcGV0YWxzBAkAbmFtZV9oYXNo6DQwN9SwV3QDCgBuZXR3b3JrX2lkNWneGgoGAHN0YXRlcwMGAGdyb3d0aAAAAAAIHABtaW5lY3JhZnQ6Y2FyZGluYWxfZGlyZWN0aW9uBQBzb3V0aAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:wither_rose", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTXAQAACAQAbmFtZRUAbWluZWNyYWZ0OndpdGhlcl9yb3NlBAkAbmFtZV9oYXNoaSKxl3I516gDCgBuZXR3b3JrX2lkATXLPwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:torchflower", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ3AwAACAQAbmFtZRUAbWluZWNyYWZ0OnRvcmNoZmxvd2VyBAkAbmFtZV9oYXNoL+mHtElwbqQDCgBuZXR3b3JrX2lkI34O+AoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:white_dye" + }, + { + "id": "minecraft:light_gray_dye" + }, + { + "id": "minecraft:gray_dye" + }, + { + "id": "minecraft:black_dye" + }, + { + "id": "minecraft:brown_dye" + }, + { + "id": "minecraft:red_dye" + }, + { + "id": "minecraft:orange_dye" + }, + { + "id": "minecraft:yellow_dye" + }, + { + "id": "minecraft:lime_dye" + }, + { + "id": "minecraft:green_dye" + }, + { + "id": "minecraft:cyan_dye" + }, + { + "id": "minecraft:light_blue_dye" + }, + { + "id": "minecraft:blue_dye" + }, + { + "id": "minecraft:purple_dye" + }, + { + "id": "minecraft:magenta_dye" + }, + { + "id": "minecraft:pink_dye" + }, + { + "id": "minecraft:ink_sac" + }, + { + "id": "minecraft:glow_ink_sac" + }, + { + "id": "minecraft:cocoa_beans" + }, + { + "id": "minecraft:lapis_lazuli" + }, + { + "id": "minecraft:bone_meal" + }, + { + "id": "minecraft:vine", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRqAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnZpbmUECQBuYW1lX2hhc2j0Sj8/XeXOLAMKAG5ldHdvcmtfaWSUkDtbCgYAc3RhdGVzAxMAdmluZV9kaXJlY3Rpb25fYml0cwAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:weeping_vines", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTmAQAACAQAbmFtZRcAbWluZWNyYWZ0OndlZXBpbmdfdmluZXMECQBuYW1lX2hhc2jrLgLHkQygiwMKAG5ldHdvcmtfaWQ8NHSJCgYAc3RhdGVzAxEAd2VlcGluZ192aW5lc19hZ2UAAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:twisting_vines", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQeAgAACAQAbmFtZRgAbWluZWNyYWZ0OnR3aXN0aW5nX3ZpbmVzBAkAbmFtZV9oYXNoDYR5QgVUQJADCgBuZXR3b3JrX2lk5kYVIQoGAHN0YXRlcwMSAHR3aXN0aW5nX3ZpbmVzX2FnZQAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:waterlily", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRvAAAACAQAbmFtZRMAbWluZWNyYWZ0OndhdGVybGlseQQJAG5hbWVfaGFzaEHgC4c1SXg0AwoAbmV0d29ya19pZOOerp8KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:seagrass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSBAQAACAQAbmFtZRIAbWluZWNyYWZ0OnNlYWdyYXNzBAkAbmFtZV9oYXNoHSBFtoHdWxIDCgBuZXR3b3JrX2lkd3lhEAoGAHN0YXRlcwgOAHNlYV9ncmFzc190eXBlBwBkZWZhdWx0AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:kelp" + }, + { + "id": "minecraft:deadbush", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQgAAAACAQAbmFtZRIAbWluZWNyYWZ0OmRlYWRidXNoBAkAbmFtZV9oYXNoPFODe4IScnYDCgBuZXR3b3JrX2lkVfnl+goGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:bamboo", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSiAQAACAQAbmFtZRAAbWluZWNyYWZ0OmJhbWJvbwQJAG5hbWVfaGFzaBgpGmyzhedCAwoAbmV0d29ya19pZIZv1nYKBgBzdGF0ZXMBBwBhZ2VfYml0AAgQAGJhbWJvb19sZWFmX3NpemUJAG5vX2xlYXZlcwgWAGJhbWJvb19zdGFsa190aGlja25lc3MEAHRoaW4AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:snow", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRQAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnNub3cECQBuYW1lX2hhc2gVHr5XXdETWAMKAG5ldHdvcmtfaWQ0zCeHCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:ice", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRPAAAACAQAbmFtZQ0AbWluZWNyYWZ0OmljZQQJAG5hbWVfaGFzaNF26f+uUT29AwoAbmV0d29ya19pZOUMaQYKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:packed_ice", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSuAAAACAQAbmFtZRQAbWluZWNyYWZ0OnBhY2tlZF9pY2UECQBuYW1lX2hhc2hk4bu123ZrFgMKAG5ldHdvcmtfaWTr/ooaCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:blue_ice", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQKAQAACAQAbmFtZRIAbWluZWNyYWZ0OmJsdWVfaWNlBAkAbmFtZV9oYXNo+EKxYgFhKcgDCgBuZXR3b3JrX2lkxfsA8goGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:snow_layer", + "block_state_b64": "CgAAAwgAYmxvY2tfaWROAAAACAQAbmFtZRQAbWluZWNyYWZ0OnNub3dfbGF5ZXIECQBuYW1lX2hhc2hXka6atMYUCQMKAG5ldHdvcmtfaWRCrIPcCgYAc3RhdGVzAQsAY292ZXJlZF9iaXQAAwYAaGVpZ2h0AAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:pointed_dripstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQzAgAACAQAbmFtZRsAbWluZWNyYWZ0OnBvaW50ZWRfZHJpcHN0b25lBAkAbmFtZV9oYXNoJMISzmHQgt8DCgBuZXR3b3JrX2lkbWrtYgoGAHN0YXRlcwgTAGRyaXBzdG9uZV90aGlja25lc3MDAHRpcAEHAGhhbmdpbmcBAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:dripstone_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ8AgAACAQAbmFtZRkAbWluZWNyYWZ0OmRyaXBzdG9uZV9ibG9jawQJAG5hbWVfaGFzaIIXnEqY77YsAwoAbmV0d29ya19pZMZi2kwKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:moss_carpet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWROAgAACAQAbmFtZRUAbWluZWNyYWZ0Om1vc3NfY2FycGV0BAkAbmFtZV9oYXNo/NEDxRPTshYDCgBuZXR3b3JrX2lkaGG3QwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:moss_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ/AgAACAQAbmFtZRQAbWluZWNyYWZ0Om1vc3NfYmxvY2sECQBuYW1lX2hhc2iovcsPUYX2tgMKAG5ldHdvcmtfaWT3JSbfCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:dirt_with_roots", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ9AgAACAQAbmFtZRkAbWluZWNyYWZ0OmRpcnRfd2l0aF9yb290cwQJAG5hbWVfaGFzaLCNDYPviDCIAwoAbmV0d29ya19pZNCkwzoKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:hanging_roots", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ+AgAACAQAbmFtZRcAbWluZWNyYWZ0Omhhbmdpbmdfcm9vdHMECQBuYW1lX2hhc2jaXn+Y5UZpDAMKAG5ldHdvcmtfaWRU4c2vCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:mangrove_roots", + "block_state_b64": "CgAAAwgAYmxvY2tfaWThAgAACAQAbmFtZRgAbWluZWNyYWZ0Om1hbmdyb3ZlX3Jvb3RzBAkAbmFtZV9oYXNoa786PzQGZ6kDCgBuZXR3b3JrX2lklA0AHgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:muddy_mangrove_roots", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTiAgAACAQAbmFtZR4AbWluZWNyYWZ0Om11ZGR5X21hbmdyb3ZlX3Jvb3RzBAkAbmFtZV9oYXNo9YApdHpo1RkDCgBuZXR3b3JrX2lkH0Oc4woGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:big_dripleaf", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRCAgAACAQAbmFtZRYAbWluZWNyYWZ0OmJpZ19kcmlwbGVhZgQJAG5hbWVfaGFzaGBEhXjo6qSdAwoAbmV0d29ya19pZMETsb8KBgBzdGF0ZXMBEQBiaWdfZHJpcGxlYWZfaGVhZAEIEQBiaWdfZHJpcGxlYWZfdGlsdAQAbm9uZQgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:small_dripleaf_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRPAgAACAQAbmFtZR4AbWluZWNyYWZ0OnNtYWxsX2RyaXBsZWFmX2Jsb2NrBAkAbmFtZV9oYXNojxRAgXP9uWADCgBuZXR3b3JrX2lkozbVPwoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24EAGVhc3QBDwB1cHBlcl9ibG9ja19iaXQBAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:spore_blossom", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRAAgAACAQAbmFtZRcAbWluZWNyYWZ0OnNwb3JlX2Jsb3Nzb20ECQBuYW1lX2hhc2il3U72Gbco2gMKAG5ldHdvcmtfaWSbbbgcCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:azalea", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRQAgAACAQAbmFtZRAAbWluZWNyYWZ0OmF6YWxlYQQJAG5hbWVfaGFzaNyUl+BW9JrBAwoAbmV0d29ya19pZO/XZtQKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:flowering_azalea", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRRAgAACAQAbmFtZRoAbWluZWNyYWZ0OmZsb3dlcmluZ19hemFsZWEECQBuYW1lX2hhc2ie9r33wz8kiwMKAG5ldHdvcmtfaWQ3ij0VCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:glow_lichen", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSaAgAACAQAbmFtZRUAbWluZWNyYWZ0Omdsb3dfbGljaGVuBAkAbmFtZV9oYXNobyPUrIYlo44DCgBuZXR3b3JrX2lkCh8lSAoGAHN0YXRlcwMZAG11bHRpX2ZhY2VfZGlyZWN0aW9uX2JpdHM/AAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:amethyst_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRGAgAACAQAbmFtZRgAbWluZWNyYWZ0OmFtZXRoeXN0X2Jsb2NrBAkAbmFtZV9oYXNob+JK1iiAthcDCgBuZXR3b3JrX2lk8HtpzgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:budding_amethyst", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRHAgAACAQAbmFtZRoAbWluZWNyYWZ0OmJ1ZGRpbmdfYW1ldGh5c3QECQBuYW1lX2hhc2gJvAwfI14fxgMKAG5ldHdvcmtfaWTQYqfACgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:amethyst_cluster", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRIAgAACAQAbmFtZRoAbWluZWNyYWZ0OmFtZXRoeXN0X2NsdXN0ZXIECQBuYW1lX2hhc2jK82S88Jgm8wMKAG5ldHdvcmtfaWSCPMPGCgYAc3RhdGVzCBQAbWluZWNyYWZ0OmJsb2NrX2ZhY2UCAHVwAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:large_amethyst_bud", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRJAgAACAQAbmFtZRwAbWluZWNyYWZ0OmxhcmdlX2FtZXRoeXN0X2J1ZAQJAG5hbWVfaGFzaAHhdpWD+sd5AwoAbmV0d29ya19pZKkQxOcKBgBzdGF0ZXMIFABtaW5lY3JhZnQ6YmxvY2tfZmFjZQIAdXAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:medium_amethyst_bud", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRKAgAACAQAbmFtZR0AbWluZWNyYWZ0Om1lZGl1bV9hbWV0aHlzdF9idWQECQBuYW1lX2hhc2g5lBGtC0DzZQMKAG5ldHdvcmtfaWSYiP4gCgYAc3RhdGVzCBQAbWluZWNyYWZ0OmJsb2NrX2ZhY2UCAHVwAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:small_amethyst_bud", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRLAgAACAQAbmFtZRwAbWluZWNyYWZ0OnNtYWxsX2FtZXRoeXN0X2J1ZAQJAG5hbWVfaGFzaEnb4+q9PO4YAwoAbmV0d29ya19pZGWzxrQKBgBzdGF0ZXMIFABtaW5lY3JhZnQ6YmxvY2tfZmFjZQIAdXAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:tuff", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRMAgAACAQAbmFtZQ4AbWluZWNyYWZ0OnR1ZmYECQBuYW1lX2hhc2h1Rwc1XYsBGwMKAG5ldHdvcmtfaWRwQGn0CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:calcite", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRFAgAACAQAbmFtZREAbWluZWNyYWZ0OmNhbGNpdGUECQBuYW1lX2hhc2ixKLu8ZIdzDQMKAG5ldHdvcmtfaWQlSbJDCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:chicken" + }, + { + "id": "minecraft:porkchop" + }, + { + "id": "minecraft:beef" + }, + { + "id": "minecraft:mutton" + }, + { + "id": "minecraft:rabbit" + }, + { + "id": "minecraft:cod" + }, + { + "id": "minecraft:salmon" + }, + { + "id": "minecraft:tropical_fish" + }, + { + "id": "minecraft:pufferfish" + }, + { + "id": "minecraft:brown_mushroom", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQnAAAACAQAbmFtZRgAbWluZWNyYWZ0OmJyb3duX211c2hyb29tBAkAbmFtZV9oYXNonYw/FO78WDoDCgBuZXR3b3JrX2lkLh1OXAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:red_mushroom", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQoAAAACAQAbmFtZRYAbWluZWNyYWZ0OnJlZF9tdXNocm9vbQQJAG5hbWVfaGFzaPpzJua7669xAwoAbmV0d29ya19pZCvWPYkKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:crimson_fungus", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTjAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fZnVuZ3VzBAkAbmFtZV9oYXNolIcCUuFM2u0DCgBuZXR3b3JrX2lkD2NN0QoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:warped_fungus", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTkAQAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9mdW5ndXMECQBuYW1lX2hhc2gq8bSnRVTAFgMKAG5ldHdvcmtfaWTkwS+rCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:brown_mushroom_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAAAACAQAbmFtZR4AbWluZWNyYWZ0OmJyb3duX211c2hyb29tX2Jsb2NrBAkAbmFtZV9oYXNoIyjnbI6xy9sDCgBuZXR3b3JrX2lkdOMhDAoGAHN0YXRlcwMSAGh1Z2VfbXVzaHJvb21fYml0cw4AAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:red_mushroom_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRkAAAACAQAbmFtZRwAbWluZWNyYWZ0OnJlZF9tdXNocm9vbV9ibG9jawQJAG5hbWVfaGFzaJTTyJbth9M9AwoAbmV0d29ya19pZM+AyboKBgBzdGF0ZXMDEgBodWdlX211c2hyb29tX2JpdHMOAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:brown_mushroom_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAAAACAQAbmFtZR4AbWluZWNyYWZ0OmJyb3duX211c2hyb29tX2Jsb2NrBAkAbmFtZV9oYXNoIyjnbI6xy9sDCgBuZXR3b3JrX2lkbdt3CAoGAHN0YXRlcwMSAGh1Z2VfbXVzaHJvb21fYml0cw8AAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:brown_mushroom_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAAAACAQAbmFtZR4AbWluZWNyYWZ0OmJyb3duX211c2hyb29tX2Jsb2NrBAkAbmFtZV9oYXNoIyjnbI6xy9sDCgBuZXR3b3JrX2lkSrMl9goGAHN0YXRlcwMSAGh1Z2VfbXVzaHJvb21fYml0cwAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:egg" + }, + { + "id": "minecraft:sugar_cane" + }, + { + "id": "minecraft:sugar" + }, + { + "id": "minecraft:rotten_flesh" + }, + { + "id": "minecraft:bone" + }, + { + "id": "minecraft:web", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQeAAAACAQAbmFtZQ0AbWluZWNyYWZ0OndlYgQJAG5hbWVfaGFzaA4GKQCvG4i9AwoAbmV0d29ya19pZApt+jgKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:spider_eye" + }, + { + "id": "minecraft:mob_spawner", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ0AAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vYl9zcGF3bmVyBAkAbmFtZV9oYXNoNwGrCV/Fkh8DCgBuZXR3b3JrX2lkM1wTmgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:end_portal_frame", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR4AAAACAQAbmFtZRoAbWluZWNyYWZ0OmVuZF9wb3J0YWxfZnJhbWUECQBuYW1lX2hhc2gqofyUIjGOpQMKAG5ldHdvcmtfaWRbGHf8CgYAc3RhdGVzARIAZW5kX3BvcnRhbF9leWVfYml0AAgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:monster_egg", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkqXH7RgoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGUFAHN0b25lAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:monster_egg", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkeIBb6QoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGULAGNvYmJsZXN0b25lAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:monster_egg", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkDZ2cFQoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGULAHN0b25lX2JyaWNrAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:monster_egg", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkOR/cTAoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGURAG1vc3N5X3N0b25lX2JyaWNrAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:monster_egg", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkqdwlHAoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGUTAGNyYWNrZWRfc3RvbmVfYnJpY2sAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:monster_egg", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkFqqPggoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGUUAGNoaXNlbGVkX3N0b25lX2JyaWNrAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:infested_deepslate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTFAgAACAQAbmFtZRwAbWluZWNyYWZ0OmluZmVzdGVkX2RlZXBzbGF0ZQQJAG5hbWVfaGFzaICF2VYccxF1AwoAbmV0d29ya19pZDa/624KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:dragon_egg", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR6AAAACAQAbmFtZRQAbWluZWNyYWZ0OmRyYWdvbl9lZ2cECQBuYW1lX2hhc2inMzXrV+/e1wMKAG5ldHdvcmtfaWTgO1yRCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:turtle_egg", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSeAQAACAQAbmFtZRQAbWluZWNyYWZ0OnR1cnRsZV9lZ2cECQBuYW1lX2hhc2iwSRcxOJIJ9gMKAG5ldHdvcmtfaWSIRNUhCgYAc3RhdGVzCA0AY3JhY2tlZF9zdGF0ZQkAbm9fY3JhY2tzCBAAdHVydGxlX2VnZ19jb3VudAcAb25lX2VnZwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:sniffer_egg", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRTAwAACAQAbmFtZRUAbWluZWNyYWZ0OnNuaWZmZXJfZWdnBAkAbmFtZV9oYXNoY1lozc8lPcYDCgBuZXR3b3JrX2lk7yb/2QoGAHN0YXRlcwgNAGNyYWNrZWRfc3RhdGUJAG5vX2NyYWNrcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:frog_spawn", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAgAACAQAbmFtZRQAbWluZWNyYWZ0OmZyb2dfc3Bhd24ECQBuYW1lX2hhc2iWmd7idp3ZZwMKAG5ldHdvcmtfaWRFzJudCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:pearlescent_froglight", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTUAgAACAQAbmFtZR8AbWluZWNyYWZ0OnBlYXJsZXNjZW50X2Zyb2dsaWdodAQJAG5hbWVfaGFzaKkcFRyycYGyAwoAbmV0d29ya19pZJqYakAKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:verdant_froglight", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTVAgAACAQAbmFtZRsAbWluZWNyYWZ0OnZlcmRhbnRfZnJvZ2xpZ2h0BAkAbmFtZV9oYXNoA+eXuTBohrQDCgBuZXR3b3JrX2lkDIVnsQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:ochre_froglight", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTWAgAACAQAbmFtZRkAbWluZWNyYWZ0Om9jaHJlX2Zyb2dsaWdodAQJAG5hbWVfaGFzaMY59kjPe+c3AwoAbmV0d29ya19pZO2TD50KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:chicken_spawn_egg" + }, + { + "id": "minecraft:bee_spawn_egg" + }, + { + "id": "minecraft:cow_spawn_egg" + }, + { + "id": "minecraft:pig_spawn_egg" + }, + { + "id": "minecraft:sheep_spawn_egg" + }, + { + "id": "minecraft:wolf_spawn_egg" + }, + { + "id": "minecraft:polar_bear_spawn_egg" + }, + { + "id": "minecraft:ocelot_spawn_egg" + }, + { + "id": "minecraft:cat_spawn_egg" + }, + { + "id": "minecraft:mooshroom_spawn_egg" + }, + { + "id": "minecraft:bat_spawn_egg" + }, + { + "id": "minecraft:parrot_spawn_egg" + }, + { + "id": "minecraft:rabbit_spawn_egg" + }, + { + "id": "minecraft:llama_spawn_egg" + }, + { + "id": "minecraft:horse_spawn_egg" + }, + { + "id": "minecraft:donkey_spawn_egg" + }, + { + "id": "minecraft:mule_spawn_egg" + }, + { + "id": "minecraft:skeleton_horse_spawn_egg" + }, + { + "id": "minecraft:zombie_horse_spawn_egg" + }, + { + "id": "minecraft:tropical_fish_spawn_egg" + }, + { + "id": "minecraft:cod_spawn_egg" + }, + { + "id": "minecraft:pufferfish_spawn_egg" + }, + { + "id": "minecraft:salmon_spawn_egg" + }, + { + "id": "minecraft:dolphin_spawn_egg" + }, + { + "id": "minecraft:turtle_spawn_egg" + }, + { + "id": "minecraft:panda_spawn_egg" + }, + { + "id": "minecraft:fox_spawn_egg" + }, + { + "id": "minecraft:creeper_spawn_egg" + }, + { + "id": "minecraft:enderman_spawn_egg" + }, + { + "id": "minecraft:silverfish_spawn_egg" + }, + { + "id": "minecraft:skeleton_spawn_egg" + }, + { + "id": "minecraft:wither_skeleton_spawn_egg" + }, + { + "id": "minecraft:stray_spawn_egg" + }, + { + "id": "minecraft:slime_spawn_egg" + }, + { + "id": "minecraft:spider_spawn_egg" + }, + { + "id": "minecraft:zombie_spawn_egg" + }, + { + "id": "minecraft:zombie_pigman_spawn_egg" + }, + { + "id": "minecraft:husk_spawn_egg" + }, + { + "id": "minecraft:drowned_spawn_egg" + }, + { + "id": "minecraft:squid_spawn_egg" + }, + { + "id": "minecraft:glow_squid_spawn_egg" + }, + { + "id": "minecraft:cave_spider_spawn_egg" + }, + { + "id": "minecraft:witch_spawn_egg" + }, + { + "id": "minecraft:guardian_spawn_egg" + }, + { + "id": "minecraft:elder_guardian_spawn_egg" + }, + { + "id": "minecraft:endermite_spawn_egg" + }, + { + "id": "minecraft:magma_cube_spawn_egg" + }, + { + "id": "minecraft:strider_spawn_egg" + }, + { + "id": "minecraft:hoglin_spawn_egg" + }, + { + "id": "minecraft:piglin_spawn_egg" + }, + { + "id": "minecraft:zoglin_spawn_egg" + }, + { + "id": "minecraft:piglin_brute_spawn_egg" + }, + { + "id": "minecraft:goat_spawn_egg" + }, + { + "id": "minecraft:axolotl_spawn_egg" + }, + { + "id": "minecraft:warden_spawn_egg" + }, + { + "id": "minecraft:allay_spawn_egg" + }, + { + "id": "minecraft:frog_spawn_egg" + }, + { + "id": "minecraft:tadpole_spawn_egg" + }, + { + "id": "minecraft:trader_llama_spawn_egg" + }, + { + "id": "minecraft:camel_spawn_egg" + }, + { + "id": "minecraft:ghast_spawn_egg" + }, + { + "id": "minecraft:blaze_spawn_egg" + }, + { + "id": "minecraft:shulker_spawn_egg" + }, + { + "id": "minecraft:vindicator_spawn_egg" + }, + { + "id": "minecraft:evoker_spawn_egg" + }, + { + "id": "minecraft:vex_spawn_egg" + }, + { + "id": "minecraft:villager_spawn_egg" + }, + { + "id": "minecraft:wandering_trader_spawn_egg" + }, + { + "id": "minecraft:zombie_villager_spawn_egg" + }, + { + "id": "minecraft:phantom_spawn_egg" + }, + { + "id": "minecraft:pillager_spawn_egg" + }, + { + "id": "minecraft:ravager_spawn_egg" + }, + { + "id": "minecraft:iron_golem_spawn_egg" + }, + { + "id": "minecraft:snow_golem_spawn_egg" + }, + { + "id": "minecraft:sniffer_spawn_egg" + }, + { + "id": "minecraft:armadillo_spawn_egg" + }, + { + "id": "minecraft:obsidian", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQxAAAACAQAbmFtZRIAbWluZWNyYWZ0Om9ic2lkaWFuBAkAbmFtZV9oYXNoiz4qrb8QjyEDCgBuZXR3b3JrX2lkuqnPpQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:crying_obsidian", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQgAgAACAQAbmFtZRkAbWluZWNyYWZ0OmNyeWluZ19vYnNpZGlhbgQJAG5hbWVfaGFzaKT0JlA7Z1K+AwoAbmV0d29ya19pZCjbPV4KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:bedrock", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQHAAAACAQAbmFtZREAbWluZWNyYWZ0OmJlZHJvY2sECQBuYW1lX2hhc2hWfFrh4LVtxwMKAG5ldHdvcmtfaWT7fKz1CgYAc3RhdGVzAQ4AaW5maW5pYnVybl9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:soul_sand", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNvdWxfc2FuZAQJAG5hbWVfaGFzaMaf+bccu+KTAwoAbmV0d29ya19pZBQSHrMKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:magma", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTVAAAACAQAbmFtZQ8AbWluZWNyYWZ0Om1hZ21hBAkAbmFtZV9oYXNoqyTjKaIsWfYDCgBuZXR3b3JrX2lkyfWAZgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:nether_wart" + }, + { + "id": "minecraft:end_stone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR5AAAACAQAbmFtZRMAbWluZWNyYWZ0OmVuZF9zdG9uZQQJAG5hbWVfaGFzaH1J9jA39GJNAwoAbmV0d29ya19pZFeFQ7UKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:chorus_flower", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTIAAAACAQAbmFtZRcAbWluZWNyYWZ0OmNob3J1c19mbG93ZXIECQBuYW1lX2hhc2iMpSodli5uawMKAG5ldHdvcmtfaWRnd1ZWCgYAc3RhdGVzAwMAYWdlAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:chorus_plant", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTwAAAACAQAbmFtZRYAbWluZWNyYWZ0OmNob3J1c19wbGFudAQJAG5hbWVfaGFzaJhSrmNGKwaMAwoAbmV0d29ya19pZA3uVqMKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:chorus_fruit" + }, + { + "id": "minecraft:popped_chorus_fruit" + }, + { + "id": "minecraft:sponge", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQTAAAACAQAbmFtZRAAbWluZWNyYWZ0OnNwb25nZQQJAG5hbWVfaGFzaLrd2ScYRDMiAwoAbmV0d29ya19pZF01rO0KBgBzdGF0ZXMICwBzcG9uZ2VfdHlwZQMAZHJ5AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:sponge", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQTAAAACAQAbmFtZRAAbWluZWNyYWZ0OnNwb25nZQQJAG5hbWVfaGFzaLrd2ScYRDMiAwoAbmV0d29ya19pZPiOc4QKBgBzdGF0ZXMICwBzcG9uZ2VfdHlwZQMAd2V0AAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkGnlaAwoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABibHVlAQgAZGVhZF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkSnHuagoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABwaW5rAQgAZGVhZF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkmkHyegoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgBwdXJwbGUBCABkZWFkX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkdpUDxgoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yAwByZWQBCABkZWFkX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkYNWvYgoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgB5ZWxsb3cBCABkZWFkX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkZSxBQgoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABibHVlAQgAZGVhZF9iaXQBAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lklSTVqQoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABwaW5rAQgAZGVhZF9iaXQBAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lk5fTYuQoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgBwdXJwbGUBCABkZWFkX2JpdAEAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkwUjqBAoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yAwByZWQBCABkZWFkX2JpdAEAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkq4iWoQoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgB5ZWxsb3cBCABkZWFkX2JpdAEAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:sculk", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAgAACAQAbmFtZQ8AbWluZWNyYWZ0OnNjdWxrBAkAbmFtZV9oYXNo2Lq7T5yQF8kDCgBuZXR3b3JrX2lkyqUPPgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:sculk_vein", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTKAgAACAQAbmFtZRQAbWluZWNyYWZ0OnNjdWxrX3ZlaW4ECQBuYW1lX2hhc2gJUdhVooV4zwMKAG5ldHdvcmtfaWSUfn1XCgYAc3RhdGVzAxkAbXVsdGlfZmFjZV9kaXJlY3Rpb25fYml0cwAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:sculk_catalyst", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTLAgAACAQAbmFtZRgAbWluZWNyYWZ0OnNjdWxrX2NhdGFseXN0BAkAbmFtZV9oYXNo+gCpbrCHST4DCgBuZXR3b3JrX2lkMJ2n/woGAHN0YXRlcwEFAGJsb29tAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:sculk_shrieker", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTMAgAACAQAbmFtZRgAbWluZWNyYWZ0OnNjdWxrX3Nocmlla2VyBAkAbmFtZV9oYXNo5OXtyObniQ4DCgBuZXR3b3JrX2lkxapoNAoGAHN0YXRlcwEGAGFjdGl2ZQABCgBjYW5fc3VtbW9uAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:sculk_sensor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQyAgAACAQAbmFtZRYAbWluZWNyYWZ0OnNjdWxrX3NlbnNvcgQJAG5hbWVfaGFzaCkmHreeTgNnAwoAbmV0d29ya19pZLj2WPcKBgBzdGF0ZXMDEgBzY3Vsa19zZW5zb3JfcGhhc2UAAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:calibrated_sculk_sensor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRDAwAACAQAbmFtZSEAbWluZWNyYWZ0OmNhbGlicmF0ZWRfc2N1bGtfc2Vuc29yBAkAbmFtZV9oYXNoffAcXXN/iJUDCgBuZXR3b3JrX2lkwOx3QQoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAxIAc2N1bGtfc2Vuc29yX3BoYXNlAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:reinforced_deepslate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTRAgAACAQAbmFtZR4AbWluZWNyYWZ0OnJlaW5mb3JjZWRfZGVlcHNsYXRlBAkAbmFtZV9oYXNoldDmj91EapQDCgBuZXR3b3JrX2lkHIt+aQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:leather_helmet" + }, + { + "id": "minecraft:chainmail_helmet" + }, + { + "id": "minecraft:iron_helmet" + }, + { + "id": "minecraft:golden_helmet" + }, + { + "id": "minecraft:diamond_helmet" + }, + { + "id": "minecraft:netherite_helmet" + }, + { + "id": "minecraft:leather_chestplate" + }, + { + "id": "minecraft:chainmail_chestplate" + }, + { + "id": "minecraft:iron_chestplate" + }, + { + "id": "minecraft:golden_chestplate" + }, + { + "id": "minecraft:diamond_chestplate" + }, + { + "id": "minecraft:netherite_chestplate" + }, + { + "id": "minecraft:leather_leggings" + }, + { + "id": "minecraft:chainmail_leggings" + }, + { + "id": "minecraft:iron_leggings" + }, + { + "id": "minecraft:golden_leggings" + }, + { + "id": "minecraft:diamond_leggings" + }, + { + "id": "minecraft:netherite_leggings" + }, + { + "id": "minecraft:leather_boots" + }, + { + "id": "minecraft:chainmail_boots" + }, + { + "id": "minecraft:iron_boots" + }, + { + "id": "minecraft:golden_boots" + }, + { + "id": "minecraft:diamond_boots" + }, + { + "id": "minecraft:netherite_boots" + }, + { + "id": "minecraft:wooden_sword" + }, + { + "id": "minecraft:stone_sword" + }, + { + "id": "minecraft:iron_sword" + }, + { + "id": "minecraft:golden_sword" + }, + { + "id": "minecraft:diamond_sword" + }, + { + "id": "minecraft:netherite_sword" + }, + { + "id": "minecraft:wooden_axe" + }, + { + "id": "minecraft:stone_axe" + }, + { + "id": "minecraft:iron_axe" + }, + { + "id": "minecraft:golden_axe" + }, + { + "id": "minecraft:diamond_axe" + }, + { + "id": "minecraft:netherite_axe" + }, + { + "id": "minecraft:wooden_pickaxe" + }, + { + "id": "minecraft:stone_pickaxe" + }, + { + "id": "minecraft:iron_pickaxe" + }, + { + "id": "minecraft:golden_pickaxe" + }, + { + "id": "minecraft:diamond_pickaxe" + }, + { + "id": "minecraft:netherite_pickaxe" + }, + { + "id": "minecraft:wooden_shovel" + }, + { + "id": "minecraft:stone_shovel" + }, + { + "id": "minecraft:iron_shovel" + }, + { + "id": "minecraft:golden_shovel" + }, + { + "id": "minecraft:diamond_shovel" + }, + { + "id": "minecraft:netherite_shovel" + }, + { + "id": "minecraft:wooden_hoe" + }, + { + "id": "minecraft:stone_hoe" + }, + { + "id": "minecraft:iron_hoe" + }, + { + "id": "minecraft:golden_hoe" + }, + { + "id": "minecraft:diamond_hoe" + }, + { + "id": "minecraft:netherite_hoe" + }, + { + "id": "minecraft:bow" + }, + { + "id": "minecraft:crossbow" + }, + { + "id": "minecraft:arrow" + }, + { + "id": "minecraft:arrow", + "damage": 6 + }, + { + "id": "minecraft:arrow", + "damage": 7 + }, + { + "id": "minecraft:arrow", + "damage": 8 + }, + { + "id": "minecraft:arrow", + "damage": 9 + }, + { + "id": "minecraft:arrow", + "damage": 10 + }, + { + "id": "minecraft:arrow", + "damage": 11 + }, + { + "id": "minecraft:arrow", + "damage": 12 + }, + { + "id": "minecraft:arrow", + "damage": 13 + }, + { + "id": "minecraft:arrow", + "damage": 14 + }, + { + "id": "minecraft:arrow", + "damage": 15 + }, + { + "id": "minecraft:arrow", + "damage": 16 + }, + { + "id": "minecraft:arrow", + "damage": 17 + }, + { + "id": "minecraft:arrow", + "damage": 18 + }, + { + "id": "minecraft:arrow", + "damage": 19 + }, + { + "id": "minecraft:arrow", + "damage": 20 + }, + { + "id": "minecraft:arrow", + "damage": 21 + }, + { + "id": "minecraft:arrow", + "damage": 22 + }, + { + "id": "minecraft:arrow", + "damage": 23 + }, + { + "id": "minecraft:arrow", + "damage": 24 + }, + { + "id": "minecraft:arrow", + "damage": 25 + }, + { + "id": "minecraft:arrow", + "damage": 26 + }, + { + "id": "minecraft:arrow", + "damage": 27 + }, + { + "id": "minecraft:arrow", + "damage": 28 + }, + { + "id": "minecraft:arrow", + "damage": 29 + }, + { + "id": "minecraft:arrow", + "damage": 30 + }, + { + "id": "minecraft:arrow", + "damage": 31 + }, + { + "id": "minecraft:arrow", + "damage": 32 + }, + { + "id": "minecraft:arrow", + "damage": 33 + }, + { + "id": "minecraft:arrow", + "damage": 34 + }, + { + "id": "minecraft:arrow", + "damage": 35 + }, + { + "id": "minecraft:arrow", + "damage": 36 + }, + { + "id": "minecraft:arrow", + "damage": 37 + }, + { + "id": "minecraft:arrow", + "damage": 38 + }, + { + "id": "minecraft:arrow", + "damage": 39 + }, + { + "id": "minecraft:arrow", + "damage": 40 + }, + { + "id": "minecraft:arrow", + "damage": 41 + }, + { + "id": "minecraft:arrow", + "damage": 42 + }, + { + "id": "minecraft:arrow", + "damage": 43 + }, + { + "id": "minecraft:shield" + }, + { + "id": "minecraft:cooked_chicken" + }, + { + "id": "minecraft:cooked_porkchop" + }, + { + "id": "minecraft:cooked_beef" + }, + { + "id": "minecraft:cooked_mutton" + }, + { + "id": "minecraft:cooked_rabbit" + }, + { + "id": "minecraft:cooked_cod" + }, + { + "id": "minecraft:cooked_salmon" + }, + { + "id": "minecraft:bread" + }, + { + "id": "minecraft:mushroom_stew" + }, + { + "id": "minecraft:beetroot_soup" + }, + { + "id": "minecraft:rabbit_stew" + }, + { + "id": "minecraft:baked_potato" + }, + { + "id": "minecraft:cookie" + }, + { + "id": "minecraft:pumpkin_pie" + }, + { + "id": "minecraft:cake" + }, + { + "id": "minecraft:dried_kelp" + }, + { + "id": "minecraft:fishing_rod" + }, + { + "id": "minecraft:carrot_on_a_stick" + }, + { + "id": "minecraft:warped_fungus_on_a_stick" + }, + { + "id": "minecraft:snowball" + }, + { + "id": "minecraft:shears" + }, + { + "id": "minecraft:flint_and_steel" + }, + { + "id": "minecraft:lead" + }, + { + "id": "minecraft:clock" + }, + { + "id": "minecraft:compass" + }, + { + "id": "minecraft:recovery_compass" + }, + { + "id": "minecraft:goat_horn" + }, + { + "id": "minecraft:goat_horn", + "damage": 1 + }, + { + "id": "minecraft:goat_horn", + "damage": 2 + }, + { + "id": "minecraft:goat_horn", + "damage": 3 + }, + { + "id": "minecraft:goat_horn", + "damage": 4 + }, + { + "id": "minecraft:goat_horn", + "damage": 5 + }, + { + "id": "minecraft:goat_horn", + "damage": 6 + }, + { + "id": "minecraft:goat_horn", + "damage": 7 + }, + { + "id": "minecraft:empty_map" + }, + { + "id": "minecraft:empty_map", + "damage": 2 + }, + { + "id": "minecraft:saddle" + }, + { + "id": "minecraft:leather_horse_armor" + }, + { + "id": "minecraft:iron_horse_armor" + }, + { + "id": "minecraft:golden_horse_armor" + }, + { + "id": "minecraft:diamond_horse_armor" + }, + { + "id": "minecraft:wolf_armor" + }, + { + "id": "minecraft:trident" + }, + { + "id": "minecraft:turtle_helmet" + }, + { + "id": "minecraft:elytra" + }, + { + "id": "minecraft:totem_of_undying" + }, + { + "id": "minecraft:glass_bottle" + }, + { + "id": "minecraft:experience_bottle" + }, + { + "id": "minecraft:potion" + }, + { + "id": "minecraft:potion", + "damage": 1 + }, + { + "id": "minecraft:potion", + "damage": 2 + }, + { + "id": "minecraft:potion", + "damage": 3 + }, + { + "id": "minecraft:potion", + "damage": 4 + }, + { + "id": "minecraft:potion", + "damage": 5 + }, + { + "id": "minecraft:potion", + "damage": 6 + }, + { + "id": "minecraft:potion", + "damage": 7 + }, + { + "id": "minecraft:potion", + "damage": 8 + }, + { + "id": "minecraft:potion", + "damage": 9 + }, + { + "id": "minecraft:potion", + "damage": 10 + }, + { + "id": "minecraft:potion", + "damage": 11 + }, + { + "id": "minecraft:potion", + "damage": 12 + }, + { + "id": "minecraft:potion", + "damage": 13 + }, + { + "id": "minecraft:potion", + "damage": 14 + }, + { + "id": "minecraft:potion", + "damage": 15 + }, + { + "id": "minecraft:potion", + "damage": 16 + }, + { + "id": "minecraft:potion", + "damage": 17 + }, + { + "id": "minecraft:potion", + "damage": 18 + }, + { + "id": "minecraft:potion", + "damage": 19 + }, + { + "id": "minecraft:potion", + "damage": 20 + }, + { + "id": "minecraft:potion", + "damage": 21 + }, + { + "id": "minecraft:potion", + "damage": 22 + }, + { + "id": "minecraft:potion", + "damage": 23 + }, + { + "id": "minecraft:potion", + "damage": 24 + }, + { + "id": "minecraft:potion", + "damage": 25 + }, + { + "id": "minecraft:potion", + "damage": 26 + }, + { + "id": "minecraft:potion", + "damage": 27 + }, + { + "id": "minecraft:potion", + "damage": 28 + }, + { + "id": "minecraft:potion", + "damage": 29 + }, + { + "id": "minecraft:potion", + "damage": 30 + }, + { + "id": "minecraft:potion", + "damage": 31 + }, + { + "id": "minecraft:potion", + "damage": 32 + }, + { + "id": "minecraft:potion", + "damage": 33 + }, + { + "id": "minecraft:potion", + "damage": 34 + }, + { + "id": "minecraft:potion", + "damage": 35 + }, + { + "id": "minecraft:potion", + "damage": 36 + }, + { + "id": "minecraft:potion", + "damage": 37 + }, + { + "id": "minecraft:potion", + "damage": 38 + }, + { + "id": "minecraft:potion", + "damage": 39 + }, + { + "id": "minecraft:potion", + "damage": 40 + }, + { + "id": "minecraft:potion", + "damage": 41 + }, + { + "id": "minecraft:potion", + "damage": 42 + }, + { + "id": "minecraft:splash_potion" + }, + { + "id": "minecraft:splash_potion", + "damage": 1 + }, + { + "id": "minecraft:splash_potion", + "damage": 2 + }, + { + "id": "minecraft:splash_potion", + "damage": 3 + }, + { + "id": "minecraft:splash_potion", + "damage": 4 + }, + { + "id": "minecraft:splash_potion", + "damage": 5 + }, + { + "id": "minecraft:splash_potion", + "damage": 6 + }, + { + "id": "minecraft:splash_potion", + "damage": 7 + }, + { + "id": "minecraft:splash_potion", + "damage": 8 + }, + { + "id": "minecraft:splash_potion", + "damage": 9 + }, + { + "id": "minecraft:splash_potion", + "damage": 10 + }, + { + "id": "minecraft:splash_potion", + "damage": 11 + }, + { + "id": "minecraft:splash_potion", + "damage": 12 + }, + { + "id": "minecraft:splash_potion", + "damage": 13 + }, + { + "id": "minecraft:splash_potion", + "damage": 14 + }, + { + "id": "minecraft:splash_potion", + "damage": 15 + }, + { + "id": "minecraft:splash_potion", + "damage": 16 + }, + { + "id": "minecraft:splash_potion", + "damage": 17 + }, + { + "id": "minecraft:splash_potion", + "damage": 18 + }, + { + "id": "minecraft:splash_potion", + "damage": 19 + }, + { + "id": "minecraft:splash_potion", + "damage": 20 + }, + { + "id": "minecraft:splash_potion", + "damage": 21 + }, + { + "id": "minecraft:splash_potion", + "damage": 22 + }, + { + "id": "minecraft:splash_potion", + "damage": 23 + }, + { + "id": "minecraft:splash_potion", + "damage": 24 + }, + { + "id": "minecraft:splash_potion", + "damage": 25 + }, + { + "id": "minecraft:splash_potion", + "damage": 26 + }, + { + "id": "minecraft:splash_potion", + "damage": 27 + }, + { + "id": "minecraft:splash_potion", + "damage": 28 + }, + { + "id": "minecraft:splash_potion", + "damage": 29 + }, + { + "id": "minecraft:splash_potion", + "damage": 30 + }, + { + "id": "minecraft:splash_potion", + "damage": 31 + }, + { + "id": "minecraft:splash_potion", + "damage": 32 + }, + { + "id": "minecraft:splash_potion", + "damage": 33 + }, + { + "id": "minecraft:splash_potion", + "damage": 34 + }, + { + "id": "minecraft:splash_potion", + "damage": 35 + }, + { + "id": "minecraft:splash_potion", + "damage": 36 + }, + { + "id": "minecraft:splash_potion", + "damage": 37 + }, + { + "id": "minecraft:splash_potion", + "damage": 38 + }, + { + "id": "minecraft:splash_potion", + "damage": 39 + }, + { + "id": "minecraft:splash_potion", + "damage": 40 + }, + { + "id": "minecraft:splash_potion", + "damage": 41 + }, + { + "id": "minecraft:splash_potion", + "damage": 42 + }, + { + "id": "minecraft:lingering_potion" + }, + { + "id": "minecraft:lingering_potion", + "damage": 1 + }, + { + "id": "minecraft:lingering_potion", + "damage": 2 + }, + { + "id": "minecraft:lingering_potion", + "damage": 3 + }, + { + "id": "minecraft:lingering_potion", + "damage": 4 + }, + { + "id": "minecraft:lingering_potion", + "damage": 5 + }, + { + "id": "minecraft:lingering_potion", + "damage": 6 + }, + { + "id": "minecraft:lingering_potion", + "damage": 7 + }, + { + "id": "minecraft:lingering_potion", + "damage": 8 + }, + { + "id": "minecraft:lingering_potion", + "damage": 9 + }, + { + "id": "minecraft:lingering_potion", + "damage": 10 + }, + { + "id": "minecraft:lingering_potion", + "damage": 11 + }, + { + "id": "minecraft:lingering_potion", + "damage": 12 + }, + { + "id": "minecraft:lingering_potion", + "damage": 13 + }, + { + "id": "minecraft:lingering_potion", + "damage": 14 + }, + { + "id": "minecraft:lingering_potion", + "damage": 15 + }, + { + "id": "minecraft:lingering_potion", + "damage": 16 + }, + { + "id": "minecraft:lingering_potion", + "damage": 17 + }, + { + "id": "minecraft:lingering_potion", + "damage": 18 + }, + { + "id": "minecraft:lingering_potion", + "damage": 19 + }, + { + "id": "minecraft:lingering_potion", + "damage": 20 + }, + { + "id": "minecraft:lingering_potion", + "damage": 21 + }, + { + "id": "minecraft:lingering_potion", + "damage": 22 + }, + { + "id": "minecraft:lingering_potion", + "damage": 23 + }, + { + "id": "minecraft:lingering_potion", + "damage": 24 + }, + { + "id": "minecraft:lingering_potion", + "damage": 25 + }, + { + "id": "minecraft:lingering_potion", + "damage": 26 + }, + { + "id": "minecraft:lingering_potion", + "damage": 27 + }, + { + "id": "minecraft:lingering_potion", + "damage": 28 + }, + { + "id": "minecraft:lingering_potion", + "damage": 29 + }, + { + "id": "minecraft:lingering_potion", + "damage": 30 + }, + { + "id": "minecraft:lingering_potion", + "damage": 31 + }, + { + "id": "minecraft:lingering_potion", + "damage": 32 + }, + { + "id": "minecraft:lingering_potion", + "damage": 33 + }, + { + "id": "minecraft:lingering_potion", + "damage": 34 + }, + { + "id": "minecraft:lingering_potion", + "damage": 35 + }, + { + "id": "minecraft:lingering_potion", + "damage": 36 + }, + { + "id": "minecraft:lingering_potion", + "damage": 37 + }, + { + "id": "minecraft:lingering_potion", + "damage": 38 + }, + { + "id": "minecraft:lingering_potion", + "damage": 39 + }, + { + "id": "minecraft:lingering_potion", + "damage": 40 + }, + { + "id": "minecraft:lingering_potion", + "damage": 41 + }, + { + "id": "minecraft:lingering_potion", + "damage": 42 + }, + { + "id": "minecraft:spyglass" + }, + { + "id": "minecraft:brush" + }, + { + "id": "minecraft:stick" + }, + { + "id": "minecraft:bed" + }, + { + "id": "minecraft:bed", + "damage": 8 + }, + { + "id": "minecraft:bed", + "damage": 7 + }, + { + "id": "minecraft:bed", + "damage": 15 + }, + { + "id": "minecraft:bed", + "damage": 12 + }, + { + "id": "minecraft:bed", + "damage": 14 + }, + { + "id": "minecraft:bed", + "damage": 1 + }, + { + "id": "minecraft:bed", + "damage": 4 + }, + { + "id": "minecraft:bed", + "damage": 5 + }, + { + "id": "minecraft:bed", + "damage": 13 + }, + { + "id": "minecraft:bed", + "damage": 9 + }, + { + "id": "minecraft:bed", + "damage": 3 + }, + { + "id": "minecraft:bed", + "damage": 11 + }, + { + "id": "minecraft:bed", + "damage": 10 + }, + { + "id": "minecraft:bed", + "damage": 2 + }, + { + "id": "minecraft:bed", + "damage": 6 + }, + { + "id": "minecraft:torch", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQyAAAACAQAbmFtZQ8AbWluZWNyYWZ0OnRvcmNoBAkAbmFtZV9oYXNoagn7rmDBzisDCgBuZXR3b3JrX2lk+BwwuQoGAHN0YXRlcwgWAHRvcmNoX2ZhY2luZ19kaXJlY3Rpb24HAHVua25vd24AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:soul_torch", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQLAgAACAQAbmFtZRQAbWluZWNyYWZ0OnNvdWxfdG9yY2gECQBuYW1lX2hhc2huixOT04BRdQMKAG5ldHdvcmtfaWShbFILCgYAc3RhdGVzCBYAdG9yY2hfZmFjaW5nX2RpcmVjdGlvbgcAdW5rbm93bgADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:sea_pickle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAQAACAQAbmFtZRQAbWluZWNyYWZ0OnNlYV9waWNrbGUECQBuYW1lX2hhc2iONEfZJB+glgMKAG5ldHdvcmtfaWSINWQyCgYAc3RhdGVzAw0AY2x1c3Rlcl9jb3VudAAAAAABCABkZWFkX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:lantern", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTPAQAACAQAbmFtZREAbWluZWNyYWZ0OmxhbnRlcm4ECQBuYW1lX2hhc2hMw44VI2HWygMKAG5ldHdvcmtfaWRkjQvzCgYAc3RhdGVzAQcAaGFuZ2luZwAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:soul_lantern", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQMAgAACAQAbmFtZRYAbWluZWNyYWZ0OnNvdWxfbGFudGVybgQJAG5hbWVfaGFzaGjIpjxk9z+RAwoAbmV0d29ya19pZGfoP8cKBgBzdGF0ZXMBBwBoYW5naW5nAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAgAACAQAbmFtZRAAbWluZWNyYWZ0OmNhbmRsZQQJAG5hbWVfaGFzaHPd+MsNdWTfAwoAbmV0d29ya19pZHsBMA0KBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:white_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWScAgAACAQAbmFtZRYAbWluZWNyYWZ0OndoaXRlX2NhbmRsZQQJAG5hbWVfaGFzaN1EG5Q1mHiEAwoAbmV0d29ya19pZKN1mmgKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:orange_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSdAgAACAQAbmFtZRcAbWluZWNyYWZ0Om9yYW5nZV9jYW5kbGUECQBuYW1lX2hhc2jySEVWHgUIHQMKAG5ldHdvcmtfaWSfVz82CgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:magenta_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSeAgAACAQAbmFtZRgAbWluZWNyYWZ0Om1hZ2VudGFfY2FuZGxlBAkAbmFtZV9oYXNoG0u6YIOoBSEDCgBuZXR3b3JrX2lk9xGNkQoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:light_blue_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSfAgAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY2FuZGxlBAkAbmFtZV9oYXNocXGeK0zgrG0DCgBuZXR3b3JrX2lk2m1y8goGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:yellow_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSgAgAACAQAbmFtZRcAbWluZWNyYWZ0OnllbGxvd19jYW5kbGUECQBuYW1lX2hhc2i00dtusU3CqQMKAG5ldHdvcmtfaWR9LTmpCgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:lime_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAgAACAQAbmFtZRUAbWluZWNyYWZ0OmxpbWVfY2FuZGxlBAkAbmFtZV9oYXNokcmrw5xvz7ADCgBuZXR3b3JrX2lkIAUu6QoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:pink_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSiAgAACAQAbmFtZRUAbWluZWNyYWZ0OnBpbmtfY2FuZGxlBAkAbmFtZV9oYXNoQJdEY4sZ0dwDCgBuZXR3b3JrX2lk23Rn5AoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:gray_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSjAgAACAQAbmFtZRUAbWluZWNyYWZ0OmdyYXlfY2FuZGxlBAkAbmFtZV9oYXNoS5poSo9wBDEDCgBuZXR3b3JrX2lk3trRCAoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:light_gray_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSkAgAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY2FuZGxlBAkAbmFtZV9oYXNo9ruTZLBNMasDCgBuZXR3b3JrX2lkb6DOegoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cyan_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAgAACAQAbmFtZRUAbWluZWNyYWZ0OmN5YW5fY2FuZGxlBAkAbmFtZV9oYXNoc/M8PNVcjOwDCgBuZXR3b3JrX2lkZoIQOQoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:purple_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSmAgAACAQAbmFtZRcAbWluZWNyYWZ0OnB1cnBsZV9jYW5kbGUECQBuYW1lX2hhc2jaI3xUW0/myQMKAG5ldHdvcmtfaWSnLI2BCgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:blue_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSnAgAACAQAbmFtZRUAbWluZWNyYWZ0OmJsdWVfY2FuZGxlBAkAbmFtZV9oYXNoAASSPW6TgQADCgBuZXR3b3JrX2lkrxrjQAoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:brown_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAgAACAQAbmFtZRYAbWluZWNyYWZ0OmJyb3duX2NhbmRsZQQJAG5hbWVfaGFzaDia0l6s1+WYAwoAbmV0d29ya19pZKSkBXYKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:green_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSpAgAACAQAbmFtZRYAbWluZWNyYWZ0OmdyZWVuX2NhbmRsZQQJAG5hbWVfaGFzaLeFPO1l+fIoAwoAbmV0d29ya19pZBkznDsKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:red_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSqAgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9jYW5kbGUECQBuYW1lX2hhc2jjAQpGf59ZdwMKAG5ldHdvcmtfaWRbb88GCgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:black_candle", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSrAgAACAQAbmFtZRYAbWluZWNyYWZ0OmJsYWNrX2NhbmRsZQQJAG5hbWVfaGFzaB+wRDpOqREKAwoAbmV0d29ya19pZNnOnuEKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:crafting_table", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ6AAAACAQAbmFtZRgAbWluZWNyYWZ0OmNyYWZ0aW5nX3RhYmxlBAkAbmFtZV9oYXNoe76VAmjvbpYDCgBuZXR3b3JrX2lkwCxwaAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cartography_table", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTHAQAACAQAbmFtZRsAbWluZWNyYWZ0OmNhcnRvZ3JhcGh5X3RhYmxlBAkAbmFtZV9oYXNomaWiiD/znP8DCgBuZXR3b3JrX2lkI6FzMwoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:fletching_table", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTIAQAACAQAbmFtZRkAbWluZWNyYWZ0OmZsZXRjaGluZ190YWJsZQQJAG5hbWVfaGFzaPFibh8unKyUAwoAbmV0d29ya19pZJ2mW0oKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:smithing_table", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAQAACAQAbmFtZRgAbWluZWNyYWZ0OnNtaXRoaW5nX3RhYmxlBAkAbmFtZV9oYXNo4tFES2xOXEYDCgBuZXR3b3JrX2lkXWMBzQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:beehive", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTaAQAACAQAbmFtZREAbWluZWNyYWZ0OmJlZWhpdmUECQBuYW1lX2hhc2hCcqn12UbNpwMKAG5ldHdvcmtfaWR/idcaCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAMLAGhvbmV5X2xldmVsAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:suspicious_sand", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQQAwAACAQAbmFtZRkAbWluZWNyYWZ0OnN1c3BpY2lvdXNfc2FuZAQJAG5hbWVfaGFzaL67QsuvLP00AwoAbmV0d29ya19pZKnkaIAKBgBzdGF0ZXMDEABicnVzaGVkX3Byb2dyZXNzAAAAAAEHAGhhbmdpbmcBAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:suspicious_gravel", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ8AwAACAQAbmFtZRsAbWluZWNyYWZ0OnN1c3BpY2lvdXNfZ3JhdmVsBAkAbmFtZV9oYXNoJSVbGNk7C3oDCgBuZXR3b3JrX2lkvIEJAAoGAHN0YXRlcwMQAGJydXNoZWRfcHJvZ3Jlc3MAAAAAAQcAaGFuZ2luZwEAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:campfire" + }, + { + "id": "minecraft:soul_campfire" + }, + { + "id": "minecraft:furnace", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ9AAAACAQAbmFtZREAbWluZWNyYWZ0OmZ1cm5hY2UECQBuYW1lX2hhc2ioOQrludYY8wMKAG5ldHdvcmtfaWRZxnDOCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:blast_furnace", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTDAQAACAQAbmFtZRcAbWluZWNyYWZ0OmJsYXN0X2Z1cm5hY2UECQBuYW1lX2hhc2ivDbnjkpGm5QMKAG5ldHdvcmtfaWTcEbV/CgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:smoker", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTFAQAACAQAbmFtZRAAbWluZWNyYWZ0OnNtb2tlcgQJAG5hbWVfaGFzaJd1rDMkRWomAwoAbmV0d29ya19pZGWswMwKBgBzdGF0ZXMIHABtaW5lY3JhZnQ6Y2FyZGluYWxfZGlyZWN0aW9uBQBzb3V0aAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:respawn_anchor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQPAgAACAQAbmFtZRgAbWluZWNyYWZ0OnJlc3Bhd25fYW5jaG9yBAkAbmFtZV9oYXNoZOdcjW05qigDCgBuZXR3b3JrX2lkmhMcaQoGAHN0YXRlcwMVAHJlc3Bhd25fYW5jaG9yX2NoYXJnZQAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:brewing_stand" + }, + { + "id": "minecraft:anvil", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmFudmlsBAkAbmFtZV9oYXNoNqB3fgcUCbwDCgBuZXR3b3JrX2lk8Z3VowoGAHN0YXRlcwgGAGRhbWFnZQkAdW5kYW1hZ2VkCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:anvil", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmFudmlsBAkAbmFtZV9oYXNoNqB3fgcUCbwDCgBuZXR3b3JrX2lkpiv8BAoGAHN0YXRlcwgGAGRhbWFnZRAAc2xpZ2h0bHlfZGFtYWdlZAgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:anvil", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmFudmlsBAkAbmFtZV9oYXNoNqB3fgcUCbwDCgBuZXR3b3JrX2lkFu+pdwoGAHN0YXRlcwgGAGRhbWFnZQwAdmVyeV9kYW1hZ2VkCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:grindstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTCAQAACAQAbmFtZRQAbWluZWNyYWZ0OmdyaW5kc3RvbmUECQBuYW1lX2hhc2id56zc0nk99wMKAG5ldHdvcmtfaWS4Es07CgYAc3RhdGVzCAoAYXR0YWNobWVudAgAc3RhbmRpbmcDCQBkaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:enchanting_table", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR0AAAACAQAbmFtZRoAbWluZWNyYWZ0OmVuY2hhbnRpbmdfdGFibGUECQBuYW1lX2hhc2jgIx24VLvMvwMKAG5ldHdvcmtfaWRliFFJCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:bookshelf", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQvAAAACAQAbmFtZRMAbWluZWNyYWZ0OmJvb2tzaGVsZgQJAG5hbWVfaGFzaDU04DrgJCS9AwoAbmV0d29ya19pZBcWwIwKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:chiseled_bookshelf", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQNAwAACAQAbmFtZRwAbWluZWNyYWZ0OmNoaXNlbGVkX2Jvb2tzaGVsZgQJAG5hbWVfaGFzaNXDBnsIsywYAwoAbmV0d29ya19pZIprt5IKBgBzdGF0ZXMDDABib29rc19zdG9yZWQAAAAAAwkAZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:lectern", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTBAQAACAQAbmFtZREAbWluZWNyYWZ0OmxlY3Rlcm4ECQBuYW1lX2hhc2j5Z4Mmi/1QxAMKAG5ldHdvcmtfaWR4JfDHCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgBCwBwb3dlcmVkX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cauldron" + }, + { + "id": "minecraft:composter", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTUAQAACAQAbmFtZRMAbWluZWNyYWZ0OmNvbXBvc3RlcgQJAG5hbWVfaGFzaPAADHptzeWJAwoAbmV0d29ya19pZHIL6i4KBgBzdGF0ZXMDFABjb21wb3N0ZXJfZmlsbF9sZXZlbAAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:chest", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ2AAAACAQAbmFtZQ8AbWluZWNyYWZ0OmNoZXN0BAkAbmFtZV9oYXNog9ozMxlcA88DCgBuZXR3b3JrX2lkDkOFvAoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAG5vcnRoAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:trapped_chest", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSSAAAACAQAbmFtZRcAbWluZWNyYWZ0OnRyYXBwZWRfY2hlc3QECQBuYW1lX2hhc2g2qpF9stsEjgMKAG5ldHdvcmtfaWTjJWYxCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAbm9ydGgAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:ender_chest", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSCAAAACAQAbmFtZRUAbWluZWNyYWZ0OmVuZGVyX2NoZXN0BAkAbmFtZV9oYXNohEZzOFdg0WUDCgBuZXR3b3JrX2lkx4jiSQoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAG5vcnRoAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:barrel", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTKAQAACAQAbmFtZRAAbWluZWNyYWZ0OmJhcnJlbAQJAG5hbWVfaGFzaHDkRPGymiRqAwoAbmV0d29ya19pZPnxzgsKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:undyed_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTNAAAACAQAbmFtZRwAbWluZWNyYWZ0OnVuZHllZF9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaOC9mypm/MlBAwoAbmV0d29ya19pZJ8rxp0KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:white_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTaAAAACAQAbmFtZRsAbWluZWNyYWZ0OndoaXRlX3NodWxrZXJfYm94BAkAbmFtZV9oYXNosK79m1rPUBwDCgBuZXR3b3JrX2lkjrET6goGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:light_gray_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRrAwAACAQAbmFtZSAAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2iBe5zq7PxHmgMKAG5ldHdvcmtfaWSCVJv0CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:gray_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRqAwAACAQAbmFtZRoAbWluZWNyYWZ0OmdyYXlfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2ga2s8ctjHUhgMKAG5ldHdvcmtfaWS3WMsWCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:black_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRyAwAACAQAbmFtZRsAbWluZWNyYWZ0OmJsYWNrX3NodWxrZXJfYm94BAkAbmFtZV9oYXNoPm03OZphrp8DCgBuZXR3b3JrX2lkXHztNAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:brown_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRvAwAACAQAbmFtZRsAbWluZWNyYWZ0OmJyb3duX3NodWxrZXJfYm94BAkAbmFtZV9oYXNoT3DD6qAL9cADCgBuZXR3b3JrX2lkaXxpYQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:red_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRxAwAACAQAbmFtZRkAbWluZWNyYWZ0OnJlZF9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaMIlKSCzqSZoAwoAbmV0d29ya19pZNrf+icKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:orange_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRkAwAACAQAbmFtZRwAbWluZWNyYWZ0Om9yYW5nZV9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaG2MAXU67wGrAwoAbmV0d29ya19pZGoO05gKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:yellow_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRnAwAACAQAbmFtZRwAbWluZWNyYWZ0OnllbGxvd19zaHVsa2VyX2JveAQJAG5hbWVfaGFzaIsLwQHYjcIEAwoAbmV0d29ya19pZBCBSiYKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:lime_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRoAwAACAQAbmFtZRoAbWluZWNyYWZ0OmxpbWVfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2hUwBkg+faUGAMKAG5ldHdvcmtfaWRJeKqqCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:green_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRwAwAACAQAbmFtZRsAbWluZWNyYWZ0OmdyZWVuX3NodWxrZXJfYm94BAkAbmFtZV9oYXNoZgUeT3LupLUDCgBuZXR3b3JrX2lkzJiohQoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:cyan_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRsAwAACAQAbmFtZRoAbWluZWNyYWZ0OmN5YW5fc2h1bGtlcl9ib3gECQBuYW1lX2hhc2gSfbjteXg5yAMKAG5ldHdvcmtfaWTHeliECgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:light_blue_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRmAwAACAQAbmFtZSAAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2h0VFCX0qsRxQMKAG5ldHdvcmtfaWQXD8U0CgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:blue_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRuAwAACAQAbmFtZRoAbWluZWNyYWZ0OmJsdWVfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2hn9gS0XIe6rAMKAG5ldHdvcmtfaWTO4PJaCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:purple_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRtAwAACAQAbmFtZRwAbWluZWNyYWZ0OnB1cnBsZV9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaEV/lkNPxRDdAwoAbmV0d29ya19pZFK25GAKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:magenta_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRlAwAACAQAbmFtZR0AbWluZWNyYWZ0Om1hZ2VudGFfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2iqWM7IJHxcFgMKAG5ldHdvcmtfaWTyyudTCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:pink_shulker_box", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRpAwAACAQAbmFtZRoAbWluZWNyYWZ0OnBpbmtfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2in1tkJ1GNcZgMKAG5ldHdvcmtfaWQOEGXjCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:armor_stand" + }, + { + "id": "minecraft:noteblock", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQZAAAACAQAbmFtZRMAbWluZWNyYWZ0Om5vdGVibG9jawQJAG5hbWVfaGFzaHPA8dBBH0UaAwoAbmV0d29ya19pZH1U5QkKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:jukebox", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRUAAAACAQAbmFtZREAbWluZWNyYWZ0Omp1a2Vib3gECQBuYW1lX2hhc2ieAIPExf/ZfgMKAG5ldHdvcmtfaWSmR7JfCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:music_disc_13" + }, + { + "id": "minecraft:music_disc_cat" + }, + { + "id": "minecraft:music_disc_blocks" + }, + { + "id": "minecraft:music_disc_chirp" + }, + { + "id": "minecraft:music_disc_far" + }, + { + "id": "minecraft:music_disc_mall" + }, + { + "id": "minecraft:music_disc_mellohi" + }, + { + "id": "minecraft:music_disc_stal" + }, + { + "id": "minecraft:music_disc_strad" + }, + { + "id": "minecraft:music_disc_ward" + }, + { + "id": "minecraft:music_disc_11" + }, + { + "id": "minecraft:music_disc_wait" + }, + { + "id": "minecraft:music_disc_otherside" + }, + { + "id": "minecraft:music_disc_5" + }, + { + "id": "minecraft:music_disc_pigstep" + }, + { + "id": "minecraft:music_disc_relic" + }, + { + "id": "minecraft:disc_fragment_5" + }, + { + "id": "minecraft:glowstone_dust" + }, + { + "id": "minecraft:glowstone", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRZAAAACAQAbmFtZRMAbWluZWNyYWZ0Omdsb3dzdG9uZQQJAG5hbWVfaGFzaFYqXNkefIlPAwoAbmV0d29ya19pZGT7WYYKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:redstone_lamp", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR7AAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZHN0b25lX2xhbXAECQBuYW1lX2hhc2hJ9V80caPvEgMKAG5ldHdvcmtfaWRvNPwnCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:sea_lantern", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSpAAAACAQAbmFtZRUAbWluZWNyYWZ0OnNlYV9sYW50ZXJuBAkAbmFtZV9oYXNoLPsv1TX9M+QDCgBuZXR3b3JrX2lk1PPVyAoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:oak_sign" + }, + { + "id": "minecraft:spruce_sign" + }, + { + "id": "minecraft:birch_sign" + }, + { + "id": "minecraft:jungle_sign" + }, + { + "id": "minecraft:acacia_sign" + }, + { + "id": "minecraft:dark_oak_sign" + }, + { + "id": "minecraft:mangrove_sign" + }, + { + "id": "minecraft:cherry_sign" + }, + { + "id": "minecraft:bamboo_sign" + }, + { + "id": "minecraft:crimson_sign" + }, + { + "id": "minecraft:warped_sign" + }, + { + "id": "minecraft:oak_hanging_sign" + }, + { + "id": "minecraft:spruce_hanging_sign" + }, + { + "id": "minecraft:birch_hanging_sign" + }, + { + "id": "minecraft:jungle_hanging_sign" + }, + { + "id": "minecraft:acacia_hanging_sign" + }, + { + "id": "minecraft:dark_oak_hanging_sign" + }, + { + "id": "minecraft:mangrove_hanging_sign" + }, + { + "id": "minecraft:cherry_hanging_sign" + }, + { + "id": "minecraft:bamboo_hanging_sign" + }, + { + "id": "minecraft:crimson_hanging_sign" + }, + { + "id": "minecraft:warped_hanging_sign" + }, + { + "id": "minecraft:painting" + }, + { + "id": "minecraft:frame" + }, + { + "id": "minecraft:glow_frame" + }, + { + "id": "minecraft:honey_bottle" + }, + { + "id": "minecraft:flower_pot" + }, + { + "id": "minecraft:bowl" + }, + { + "id": "minecraft:bucket" + }, + { + "id": "minecraft:milk_bucket" + }, + { + "id": "minecraft:water_bucket" + }, + { + "id": "minecraft:lava_bucket" + }, + { + "id": "minecraft:cod_bucket" + }, + { + "id": "minecraft:salmon_bucket" + }, + { + "id": "minecraft:tropical_fish_bucket" + }, + { + "id": "minecraft:pufferfish_bucket" + }, + { + "id": "minecraft:powder_snow_bucket" + }, + { + "id": "minecraft:axolotl_bucket" + }, + { + "id": "minecraft:tadpole_bucket" + }, + { + "id": "minecraft:skull", + "damage": 3 + }, + { + "id": "minecraft:skull", + "damage": 2 + }, + { + "id": "minecraft:skull", + "damage": 4 + }, + { + "id": "minecraft:skull", + "damage": 5 + }, + { + "id": "minecraft:skull" + }, + { + "id": "minecraft:skull", + "damage": 1 + }, + { + "id": "minecraft:skull", + "damage": 6 + }, + { + "id": "minecraft:beacon", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSKAAAACAQAbmFtZRAAbWluZWNyYWZ0OmJlYWNvbgQJAG5hbWVfaGFzaACwhhfSkdkHAwoAbmV0d29ya19pZF8jfiEKBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:bell", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTNAQAACAQAbmFtZQ4AbWluZWNyYWZ0OmJlbGwECQBuYW1lX2hhc2iPqsgDXRcsxAMKAG5ldHdvcmtfaWT7zhOoCgYAc3RhdGVzCAoAYXR0YWNobWVudAgAc3RhbmRpbmcDCQBkaXJlY3Rpb24AAAAAAQoAdG9nZ2xlX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:conduit", + "block_state_b64": "CgAAAwgAYmxvY2tfaWScAQAACAQAbmFtZREAbWluZWNyYWZ0OmNvbmR1aXQECQBuYW1lX2hhc2jqxKAxq2EaWQMKAG5ldHdvcmtfaWTWcBVnCgYAc3RhdGVzAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stonecutter_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTEAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lY3V0dGVyX2Jsb2NrBAkAbmFtZV9oYXNoQAXTbAM3MeYDCgBuZXR3b3JrX2lkWS4RjAoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAG5vcnRoAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:coal" + }, + { + "id": "minecraft:charcoal" + }, + { + "id": "minecraft:diamond" + }, + { + "id": "minecraft:iron_nugget" + }, + { + "id": "minecraft:raw_iron" + }, + { + "id": "minecraft:raw_gold" + }, + { + "id": "minecraft:raw_copper" + }, + { + "id": "minecraft:copper_ingot" + }, + { + "id": "minecraft:iron_ingot" + }, + { + "id": "minecraft:netherite_scrap" + }, + { + "id": "minecraft:netherite_ingot" + }, + { + "id": "minecraft:gold_nugget" + }, + { + "id": "minecraft:gold_ingot" + }, + { + "id": "minecraft:emerald" + }, + { + "id": "minecraft:quartz" + }, + { + "id": "minecraft:clay_ball" + }, + { + "id": "minecraft:brick" + }, + { + "id": "minecraft:netherbrick" + }, + { + "id": "minecraft:prismarine_shard" + }, + { + "id": "minecraft:amethyst_shard" + }, + { + "id": "minecraft:prismarine_crystals" + }, + { + "id": "minecraft:nautilus_shell" + }, + { + "id": "minecraft:heart_of_the_sea" + }, + { + "id": "minecraft:turtle_scute" + }, + { + "id": "minecraft:armadillo_scute" + }, + { + "id": "minecraft:phantom_membrane" + }, + { + "id": "minecraft:string" + }, + { + "id": "minecraft:feather" + }, + { + "id": "minecraft:flint" + }, + { + "id": "minecraft:gunpowder" + }, + { + "id": "minecraft:leather" + }, + { + "id": "minecraft:rabbit_hide" + }, + { + "id": "minecraft:rabbit_foot" + }, + { + "id": "minecraft:fire_charge" + }, + { + "id": "minecraft:blaze_rod" + }, + { + "id": "minecraft:blaze_powder" + }, + { + "id": "minecraft:magma_cream" + }, + { + "id": "minecraft:fermented_spider_eye" + }, + { + "id": "minecraft:echo_shard" + }, + { + "id": "minecraft:dragon_breath" + }, + { + "id": "minecraft:shulker_shell" + }, + { + "id": "minecraft:ghast_tear" + }, + { + "id": "minecraft:slime_ball" + }, + { + "id": "minecraft:ender_pearl" + }, + { + "id": "minecraft:ender_eye" + }, + { + "id": "minecraft:nether_star" + }, + { + "id": "minecraft:end_rod", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTQAAAACAQAbmFtZREAbWluZWNyYWZ0OmVuZF9yb2QECQBuYW1lX2hhc2jx/q5cEA0hmQMKAG5ldHdvcmtfaWQ2eM8kCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:lightning_rod", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ3AgAACAQAbmFtZRcAbWluZWNyYWZ0OmxpZ2h0bmluZ19yb2QECQBuYW1lX2hhc2ioXQF1xvfHNQMKAG5ldHdvcmtfaWRLuHyACgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:end_crystal" + }, + { + "id": "minecraft:paper" + }, + { + "id": "minecraft:book" + }, + { + "id": "minecraft:writable_book" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQFAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQFAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQFAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQGAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQGAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQGAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQHAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQHAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQHAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQIAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAUAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAUAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAUAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQMAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQMAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQNAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQNAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQOAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQOAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQOAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAUAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQQAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQRAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQRAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQRAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQSAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQSAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQSAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAUAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQUAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQUAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQVAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQWAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQXAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQXAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQXAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQYAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQYAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQYAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQZAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQZAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQaAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQbAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQcAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAUAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQeAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQeAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQeAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQfAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQfAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQfAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQgAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQhAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQjAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQjAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQjAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQkAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQkAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQkAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQlAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQlAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQlAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:oak_boat" + }, + { + "id": "minecraft:spruce_boat" + }, + { + "id": "minecraft:birch_boat" + }, + { + "id": "minecraft:jungle_boat" + }, + { + "id": "minecraft:acacia_boat" + }, + { + "id": "minecraft:dark_oak_boat" + }, + { + "id": "minecraft:mangrove_boat" + }, + { + "id": "minecraft:cherry_boat" + }, + { + "id": "minecraft:bamboo_raft" + }, + { + "id": "minecraft:oak_chest_boat" + }, + { + "id": "minecraft:spruce_chest_boat" + }, + { + "id": "minecraft:birch_chest_boat" + }, + { + "id": "minecraft:jungle_chest_boat" + }, + { + "id": "minecraft:acacia_chest_boat" + }, + { + "id": "minecraft:dark_oak_chest_boat" + }, + { + "id": "minecraft:mangrove_chest_boat" + }, + { + "id": "minecraft:cherry_chest_boat" + }, + { + "id": "minecraft:bamboo_chest_raft" + }, + { + "id": "minecraft:rail", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRCAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnJhaWwECQBuYW1lX2hhc2hUzmhUXYJDUQMKAG5ldHdvcmtfaWR+Sp6YCgYAc3RhdGVzAw4AcmFpbF9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:golden_rail", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQbAAAACAQAbmFtZRUAbWluZWNyYWZ0OmdvbGRlbl9yYWlsBAkAbmFtZV9oYXNoOoV5MaKipoUDCgBuZXR3b3JrX2lkfAcxLwoGAHN0YXRlcwENAHJhaWxfZGF0YV9iaXQAAw4AcmFpbF9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:detector_rail", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQcAAAACAQAbmFtZRcAbWluZWNyYWZ0OmRldGVjdG9yX3JhaWwECQBuYW1lX2hhc2gVUk31qOysUQMKAG5ldHdvcmtfaWRVW/aICgYAc3RhdGVzAQ0AcmFpbF9kYXRhX2JpdAADDgByYWlsX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:activator_rail", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR+AAAACAQAbmFtZRgAbWluZWNyYWZ0OmFjdGl2YXRvcl9yYWlsBAkAbmFtZV9oYXNosIL91qriCRkDCgBuZXR3b3JrX2lkZfckmwoGAHN0YXRlcwENAHJhaWxfZGF0YV9iaXQAAw4AcmFpbF9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:minecart" + }, + { + "id": "minecraft:chest_minecart" + }, + { + "id": "minecraft:hopper_minecart" + }, + { + "id": "minecraft:tnt_minecart" + }, + { + "id": "minecraft:redstone" + }, + { + "id": "minecraft:redstone_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSYAAAACAQAbmFtZRgAbWluZWNyYWZ0OnJlZHN0b25lX2Jsb2NrBAkAbmFtZV9oYXNoRhULL0r8o0sDCgBuZXR3b3JrX2lklayOHgoGAHN0YXRlcwADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:redstone_torch", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRMAAAACAQAbmFtZRgAbWluZWNyYWZ0OnJlZHN0b25lX3RvcmNoBAkAbmFtZV9oYXNoizFRjpYMIDgDCgBuZXR3b3JrX2lkuHz7yAoGAHN0YXRlcwgWAHRvcmNoX2ZhY2luZ19kaXJlY3Rpb24HAHVua25vd24AAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:lever", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRFAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmxldmVyBAkAbmFtZV9oYXNoGMJeLJsUMLYDCgBuZXR3b3JrX2lkEF/GuAoGAHN0YXRlcwgPAGxldmVyX2RpcmVjdGlvbg4AZG93bl9lYXN0X3dlc3QBCABvcGVuX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:wooden_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSPAAAACAQAbmFtZRcAbWluZWNyYWZ0Ondvb2Rlbl9idXR0b24ECQBuYW1lX2hhc2hR7PgSTQt0sQMKAG5ldHdvcmtfaWSU07kYCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:spruce_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSPAQAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9idXR0b24ECQBuYW1lX2hhc2jBW9Z8aYE7YQMKAG5ldHdvcmtfaWTkUIGuCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:birch_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSMAQAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX2J1dHRvbgQJAG5hbWVfaGFzaJXYgGuSHbTwAwoAbmV0d29ya19pZGWp3yoKBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:jungle_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSOAQAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9idXR0b24ECQBuYW1lX2hhc2iCgNANcJs+BQMKAG5ldHdvcmtfaWT9fImWCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:acacia_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAQAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9idXR0b24ECQBuYW1lX2hhc2gVvmcT7LTO0wMKAG5ldHdvcmtfaWRQnxIJCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:dark_oak_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSNAQAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX2J1dHRvbgQJAG5hbWVfaGFzaIV10ZGGrCIEAwoAbmV0d29ya19pZN5vAmIKBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:mangrove_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTmAgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX2J1dHRvbgQJAG5hbWVfaGFzaNzeYYKLgOzJAwoAbmV0d29ya19pZAFEGQ0KBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cherry_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQRAwAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9idXR0b24ECQBuYW1lX2hhc2j2/IHjeAbUcwMKAG5ldHdvcmtfaWRJ1irQCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:bamboo_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT+AgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19idXR0b24ECQBuYW1lX2hhc2j7AddMi+6nsgMKAG5ldHdvcmtfaWSa9w4/CgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stone_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRNAAAACAQAbmFtZRYAbWluZWNyYWZ0OnN0b25lX2J1dHRvbgQJAG5hbWVfaGFzaM4ejMctmvohAwoAbmV0d29ya19pZMw+aC0KBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:crimson_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAgAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fYnV0dG9uBAkAbmFtZV9oYXNofnjYHaYIeWgDCgBuZXR3b3JrX2lk+n1vyQoGAHN0YXRlcwESAGJ1dHRvbl9wcmVzc2VkX2JpdAADEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:warped_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQEAgAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9idXR0b24ECQBuYW1lX2hhc2jwkV2EU6Cn1QMKAG5ldHdvcmtfaWTnHnk1CgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:polished_blackstone_button", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQnAgAACAQAbmFtZSQAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnV0dG9uBAkAbmFtZV9oYXNojmxzQKS0S/EDCgBuZXR3b3JrX2lkDtQ95woGAHN0YXRlcwESAGJ1dHRvbl9wcmVzc2VkX2JpdAADEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:tripwire_hook", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAAAACAQAbmFtZRcAbWluZWNyYWZ0OnRyaXB3aXJlX2hvb2sECQBuYW1lX2hhc2gQdp+oGZLNnAMKAG5ldHdvcmtfaWSy+1KJCgYAc3RhdGVzAQwAYXR0YWNoZWRfYml0AAMJAGRpcmVjdGlvbgAAAAABCwBwb3dlcmVkX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:wooden_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRIAAAACAQAbmFtZR8AbWluZWNyYWZ0Ondvb2Rlbl9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaGkGs5kCuA74AwoAbmV0d29ya19pZDRzPNwKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:spruce_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSZAQAACAQAbmFtZR8AbWluZWNyYWZ0OnNwcnVjZV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaNmwuq549fJKAwoAbmV0d29ya19pZLQMCw0KBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:birch_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSWAQAACAQAbmFtZR4AbWluZWNyYWZ0OmJpcmNoX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNorQkT9kDdlTwDCgBuZXR3b3JrX2lkH0G97AoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:jungle_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSYAQAACAQAbmFtZR8AbWluZWNyYWZ0Omp1bmdsZV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaJ7DcteCkb8/AwoAbmV0d29ya19pZLdPBSAKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:acacia_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSVAQAACAQAbmFtZR8AbWluZWNyYWZ0OmFjYWNpYV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaC2frZtfoYqCAwoAbmV0d29ya19pZIDdI18KBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:dark_oak_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSXAQAACAQAbmFtZSEAbWluZWNyYWZ0OmRhcmtfb2FrX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoHUCJsTy52pwDCgBuZXR3b3JrX2lkKpi8rAoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:mangrove_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTpAgAACAQAbmFtZSEAbWluZWNyYWZ0Om1hbmdyb3ZlX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoiDsTfJaX100DCgBuZXR3b3JrX2lkuwWDyQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:cherry_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQZAwAACAQAbmFtZR8AbWluZWNyYWZ0OmNoZXJyeV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaALMqYEZDUQHAwoAbmV0d29ya19pZPNT+r0KBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:bamboo_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQBAwAACAQAbmFtZR8AbWluZWNyYWZ0OmJhbWJvb19wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaNvxJ7NIAaqlAwoAbmV0d29ya19pZIZ8XnYKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:crimson_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQFAgAACAQAbmFtZSAAbWluZWNyYWZ0OmNyaW1zb25fcHJlc3N1cmVfcGxhdGUECQBuYW1lX2hhc2hqBDVDAd31/gMKAG5ldHdvcmtfaWRmV18LCgYAc3RhdGVzAw8AcmVkc3RvbmVfc2lnbmFsAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:warped_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAgAACAQAbmFtZR8AbWluZWNyYWZ0OndhcnBlZF9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaBxFoQksWtYUAwoAbmV0d29ya19pZJVRoIcKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:stone_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRGAAAACAQAbmFtZR4AbWluZWNyYWZ0OnN0b25lX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNounJuTBUTrU8DCgBuZXR3b3JrX2lkjDydwQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:light_weighted_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSTAAAACAQAbmFtZScAbWluZWNyYWZ0OmxpZ2h0X3dlaWdodGVkX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoOyOJkNxLtkEDCgBuZXR3b3JrX2lkrr2AjgoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:heavy_weighted_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSUAAAACAQAbmFtZScAbWluZWNyYWZ0OmhlYXZ5X3dlaWdodGVkX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoltgDmDvTajUDCgBuZXR3b3JrX2lkFxVKuQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:polished_blackstone_pressure_plate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAgAACAQAbmFtZSwAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfcHJlc3N1cmVfcGxhdGUECQBuYW1lX2hhc2h65Ci6/CeGqwMKAG5ldHdvcmtfaWTaSW5xCgYAc3RhdGVzAw8AcmVkc3RvbmVfc2lnbmFsAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:observer", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT7AAAACAQAbmFtZRIAbWluZWNyYWZ0Om9ic2VydmVyBAkAbmFtZV9oYXNoYhlh1lpmHTgDCgBuZXR3b3JrX2lkQEh55goGAHN0YXRlcwgaAG1pbmVjcmFmdDpmYWNpbmdfZGlyZWN0aW9uBABkb3duAQsAcG93ZXJlZF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:daylight_detector", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSXAAAACAQAbmFtZRsAbWluZWNyYWZ0OmRheWxpZ2h0X2RldGVjdG9yBAkAbmFtZV9oYXNoV0F0s7B7PVgDCgBuZXR3b3JrX2lkri5afQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:repeater" + }, + { + "id": "minecraft:comparator" + }, + { + "id": "minecraft:hopper" + }, + { + "id": "minecraft:dropper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWR9AAAACAQAbmFtZREAbWluZWNyYWZ0OmRyb3BwZXIECQBuYW1lX2hhc2joXP7XqU0l3QMKAG5ldHdvcmtfaWQfQN6zCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgMAAAABDQB0cmlnZ2VyZWRfYml0AAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:dispenser", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQXAAAACAQAbmFtZRMAbWluZWNyYWZ0OmRpc3BlbnNlcgQJAG5hbWVfaGFzaP1RR+zAbYP2AwoAbmV0d29ya19pZGAayD0KBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAwAAAAENAHRyaWdnZXJlZF9iaXQAAAMHAHZlcnNpb24DUBQBAA==" + }, + { + "id": "minecraft:piston", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQhAAAACAQAbmFtZRAAbWluZWNyYWZ0OnBpc3RvbgQJAG5hbWVfaGFzaDs3AFh1fL0uAwoAbmV0d29ya19pZLD/5XQKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAQAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:sticky_piston", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQdAAAACAQAbmFtZRcAbWluZWNyYWZ0OnN0aWNreV9waXN0b24ECQBuYW1lX2hhc2hPFJFJSiJ0ZQMKAG5ldHdvcmtfaWT/MzCJCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgEAAAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:tnt", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQuAAAACAQAbmFtZQ0AbWluZWNyYWZ0OnRudAQJAG5hbWVfaGFzaEYOHwCvJH29AwoAbmV0d29ya19pZCGfjU4KBgBzdGF0ZXMBFABhbGxvd191bmRlcndhdGVyX2JpdAABCwBleHBsb2RlX2JpdAAAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:name_tag" + }, + { + "id": "minecraft:loom", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTLAQAACAQAbmFtZQ4AbWluZWNyYWZ0Omxvb20ECQBuYW1lX2hhc2i7DKjAXNq8TAMKAG5ldHdvcmtfaWR/49HXCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:banner", + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 8, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 7, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 15, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 12, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 14, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 1, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 4, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 5, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 13, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 9, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 3, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 11, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 10, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 2, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 6, + "nbt_b64": "CgAAAwQAVHlwZQAAAAAA" + }, + { + "id": "minecraft:banner", + "damage": 15, + "nbt_b64": "CgAAAwQAVHlwZQEAAAAA" + }, + { + "id": "minecraft:creeper_banner_pattern" + }, + { + "id": "minecraft:skull_banner_pattern" + }, + { + "id": "minecraft:flower_banner_pattern" + }, + { + "id": "minecraft:mojang_banner_pattern" + }, + { + "id": "minecraft:field_masoned_banner_pattern" + }, + { + "id": "minecraft:bordure_indented_banner_pattern" + }, + { + "id": "minecraft:piglin_banner_pattern" + }, + { + "id": "minecraft:globe_banner_pattern" + }, + { + "id": "minecraft:angler_pottery_sherd" + }, + { + "id": "minecraft:archer_pottery_sherd" + }, + { + "id": "minecraft:arms_up_pottery_sherd" + }, + { + "id": "minecraft:blade_pottery_sherd" + }, + { + "id": "minecraft:brewer_pottery_sherd" + }, + { + "id": "minecraft:burn_pottery_sherd" + }, + { + "id": "minecraft:danger_pottery_sherd" + }, + { + "id": "minecraft:explorer_pottery_sherd" + }, + { + "id": "minecraft:friend_pottery_sherd" + }, + { + "id": "minecraft:heart_pottery_sherd" + }, + { + "id": "minecraft:heartbreak_pottery_sherd" + }, + { + "id": "minecraft:howl_pottery_sherd" + }, + { + "id": "minecraft:miner_pottery_sherd" + }, + { + "id": "minecraft:mourner_pottery_sherd" + }, + { + "id": "minecraft:plenty_pottery_sherd" + }, + { + "id": "minecraft:prize_pottery_sherd" + }, + { + "id": "minecraft:sheaf_pottery_sherd" + }, + { + "id": "minecraft:shelter_pottery_sherd" + }, + { + "id": "minecraft:skull_pottery_sherd" + }, + { + "id": "minecraft:snort_pottery_sherd" + }, + { + "id": "minecraft:netherite_upgrade_smithing_template" + }, + { + "id": "minecraft:sentry_armor_trim_smithing_template" + }, + { + "id": "minecraft:vex_armor_trim_smithing_template" + }, + { + "id": "minecraft:wild_armor_trim_smithing_template" + }, + { + "id": "minecraft:coast_armor_trim_smithing_template" + }, + { + "id": "minecraft:dune_armor_trim_smithing_template" + }, + { + "id": "minecraft:wayfinder_armor_trim_smithing_template" + }, + { + "id": "minecraft:shaper_armor_trim_smithing_template" + }, + { + "id": "minecraft:raiser_armor_trim_smithing_template" + }, + { + "id": "minecraft:host_armor_trim_smithing_template" + }, + { + "id": "minecraft:ward_armor_trim_smithing_template" + }, + { + "id": "minecraft:silence_armor_trim_smithing_template" + }, + { + "id": "minecraft:tide_armor_trim_smithing_template" + }, + { + "id": "minecraft:snout_armor_trim_smithing_template" + }, + { + "id": "minecraft:rib_armor_trim_smithing_template" + }, + { + "id": "minecraft:eye_armor_trim_smithing_template" + }, + { + "id": "minecraft:spire_armor_trim_smithing_template" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwAAAAAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAABwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAIBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAHBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAPBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAMBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAOBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAABBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAEBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAFBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAANBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAJBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAADBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAALBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAKBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAACBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_rocket", + "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAGBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" + }, + { + "id": "minecraft:firework_star", + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yIR0d/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 8, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yUk9H/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 7, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yl52d/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 15, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9y8PDw/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 12, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9y2rM6/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 14, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yHYD5/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 1, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yJi6w/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 4, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yqkQ8/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 5, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yuDKJ/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 13, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yvU7H/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 9, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yqovz/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 3, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yMlSD/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 11, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yPdj+/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 10, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yH8eA/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 2, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yFnxe/wA=" + }, + { + "id": "minecraft:firework_star", + "damage": 6, + "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9ynJwW/wA=" + }, + { + "id": "minecraft:chain" + }, + { + "id": "minecraft:target", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTuAQAACAQAbmFtZRAAbWluZWNyYWZ0OnRhcmdldAQJAG5hbWVfaGFzaJc66SVbYlaxAwoAbmV0d29ya19pZPBozs0KBgBzdGF0ZXMAAwcAdmVyc2lvbgNQFAEA" + }, + { + "id": "minecraft:decorated_pot", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAwAACAQAbmFtZRcAbWluZWNyYWZ0OmRlY29yYXRlZF9wb3QECQBuYW1lX2hhc2jjQgckn8VTvwMKAG5ldHdvcmtfaWRwvkUUCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uA1AUAQA=" + }, + { + "id": "minecraft:lodestone_compass" + }, + { + "id": "minecraft:wither_spawn_egg" + }, + { + "id": "minecraft:ender_dragon_spawn_egg" + } + ] +} \ No newline at end of file diff --git a/core/src/main/resources/bedrock/entity_identifiers.dat b/core/src/main/resources/bedrock/entity_identifiers.dat index 9a986cf5c435ac467cac73c25a0ba160cbfbb0be..9a123f8d8834e6af5c98b000778665b6e2022887 100644 GIT binary patch delta 62 zcmX?S+i%Cq#lXpynUa%PT*CE@ak3+$#N;#F+#3y|$w#lXpynUa%PT*CE*ak3+$#N;#F+#3y| Date: Tue, 23 Apr 2024 12:34:24 -0400 Subject: [PATCH 063/272] Serialize disconnects --- .../main/java/org/geysermc/geyser/network/CodecProcessor.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java b/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java index 4ad02a644..0516b1601 100644 --- a/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java +++ b/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java @@ -261,7 +261,6 @@ class CodecProcessor { .updateSerializer(ScriptMessagePacket.class, ILLEGAL_SERIALIZER) // // Ignored bidirectional packets .updateSerializer(ClientCacheStatusPacket.class, IGNORED_SERIALIZER) - .updateSerializer(DisconnectPacket.class, IGNORED_SERIALIZER) .updateSerializer(SimpleEventPacket.class, IGNORED_SERIALIZER) .updateSerializer(TickSyncPacket.class, IGNORED_SERIALIZER) .updateSerializer(MultiplayerSettingsPacket.class, IGNORED_SERIALIZER) From 3bd5ab7f35c52d9a76990cedc30151b03b402a82 Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Tue, 23 Apr 2024 11:23:09 -0700 Subject: [PATCH 064/272] Use old SetEntityMotionSerializer for codec < 662 (#4593) --- .../geyser/network/CodecProcessor.java | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java b/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java index 0516b1601..6bd767fb7 100644 --- a/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java +++ b/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java @@ -33,6 +33,7 @@ import org.cloudburstmc.protocol.bedrock.codec.v291.serializer.MobArmorEquipment import org.cloudburstmc.protocol.bedrock.codec.v291.serializer.MobEquipmentSerializer_v291; import org.cloudburstmc.protocol.bedrock.codec.v291.serializer.PlayerHotbarSerializer_v291; import org.cloudburstmc.protocol.bedrock.codec.v291.serializer.SetEntityLinkSerializer_v291; +import org.cloudburstmc.protocol.bedrock.codec.v291.serializer.SetEntityMotionSerializer_v291; import org.cloudburstmc.protocol.bedrock.codec.v390.serializer.PlayerSkinSerializer_v390; import org.cloudburstmc.protocol.bedrock.codec.v407.serializer.InventoryContentSerializer_v407; import org.cloudburstmc.protocol.bedrock.codec.v407.serializer.InventorySlotSerializer_v407; @@ -50,7 +51,6 @@ import org.cloudburstmc.protocol.bedrock.packet.CodeBuilderSourcePacket; import org.cloudburstmc.protocol.bedrock.packet.CraftingEventPacket; import org.cloudburstmc.protocol.bedrock.packet.CreatePhotoPacket; import org.cloudburstmc.protocol.bedrock.packet.DebugInfoPacket; -import org.cloudburstmc.protocol.bedrock.packet.DisconnectPacket; import org.cloudburstmc.protocol.bedrock.packet.EditorNetworkPacket; import org.cloudburstmc.protocol.bedrock.packet.EntityFallPacket; import org.cloudburstmc.protocol.bedrock.packet.GameTestRequestPacket; @@ -182,9 +182,18 @@ class CodecProcessor { }; /** - * Serializer that does nothing when trying to deserialize SetEntityMotionPacket since it is not used from the client. + * Serializer that does nothing when trying to deserialize SetEntityMotionPacket since it is not used from the client for codec v291. */ - private static final BedrockPacketSerializer SET_ENTITY_MOTION_SERIALIZER = new SetEntityMotionSerializer_v662() { + private static final BedrockPacketSerializer SET_ENTITY_MOTION_SERIALIZER_V291 = new SetEntityMotionSerializer_v291() { + @Override + public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, SetEntityMotionPacket packet) { + } + }; + + /** + * Serializer that does nothing when trying to deserialize SetEntityMotionPacket since it is not used from the client for codec v662. + */ + private static final BedrockPacketSerializer SET_ENTITY_MOTION_SERIALIZER_V662 = new SetEntityMotionSerializer_v662() { @Override public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, SetEntityMotionPacket packet) { } @@ -251,7 +260,9 @@ class CodecProcessor { .updateSerializer(PlayerHotbarPacket.class, PLAYER_HOTBAR_SERIALIZER) .updateSerializer(PlayerSkinPacket.class, PLAYER_SKIN_SERIALIZER) .updateSerializer(SetEntityDataPacket.class, SET_ENTITY_DATA_SERIALIZER) - .updateSerializer(SetEntityMotionPacket.class, SET_ENTITY_MOTION_SERIALIZER) + .updateSerializer(SetEntityMotionPacket.class, codec.getProtocolVersion() < 662 ? + SET_ENTITY_MOTION_SERIALIZER_V291 : + SET_ENTITY_MOTION_SERIALIZER_V662) .updateSerializer(SetEntityLinkPacket.class, SET_ENTITY_LINK_SERIALIZER) // Valid serverbound packets where reading of some fields can be skipped .updateSerializer(MobEquipmentPacket.class, MOB_EQUIPMENT_SERIALIZER) From c34295829f17b16c5d3d3a321a472c5c1d40117b Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 23 Apr 2024 23:14:54 +0200 Subject: [PATCH 065/272] update actions to use java 21 (#4594) * update actions to use java 21 * jdk name correction --- .github/workflows/build-remote.yml | 4 ++-- .github/workflows/build.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-remote.yml b/.github/workflows/build-remote.yml index 75bcfaff5..d49920785 100644 --- a/.github/workflows/build-remote.yml +++ b/.github/workflows/build-remote.yml @@ -22,11 +22,11 @@ jobs: run: | echo "BUILD_NUMBER=${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV - - name: Set up JDK 17 + - name: Set up JDK 21 # See https://github.com/actions/setup-java/commits uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0 with: - java-version: 17 + java-version: 21 distribution: temurin - name: Checkout repository and submodules diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1ef0118ff..284fa265a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,7 +44,7 @@ jobs: # See https://github.com/actions/setup-java/commits - uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0 with: - java-version: 17 + java-version: 21 distribution: temurin - name: Build From 16385a4e2b5db5c049fc28af5e032b459cdfc64a Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Wed, 24 Apr 2024 01:39:37 -0400 Subject: [PATCH 066/272] Check if session is closed when running scheduled tasks (#4595) --- .../main/java/org/geysermc/geyser/session/GeyserSession.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index aff21182e..95d5acb47 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -1171,7 +1171,9 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { public ScheduledFuture scheduleInEventLoop(Runnable runnable, long duration, TimeUnit timeUnit) { return eventLoop.schedule(() -> { try { - runnable.run(); + if (!closed) { + runnable.run(); + } } catch (Throwable e) { geyser.getLogger().error("Error thrown in " + this.bedrockUsername() + "'s event loop!", e); } From c19b4ad306b92b146999b374fffe965012ebf55b Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Wed, 24 Apr 2024 08:41:57 -0400 Subject: [PATCH 067/272] Check if boat is valid when updating paddles (#4597) * Check if boat is valid when updating paddles * Add comment * Refactor boat paddling to use ticks * Null check --- .../geyser/entity/type/BoatEntity.java | 58 ++++++------------- .../geyser/session/GeyserSession.java | 2 + 2 files changed, 21 insertions(+), 39 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/BoatEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/BoatEntity.java index 5527e773a..e3420abeb 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/BoatEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/BoatEntity.java @@ -42,7 +42,7 @@ import org.geysermc.geyser.util.InteractiveTag; import java.util.UUID; import java.util.concurrent.TimeUnit; -public class BoatEntity extends Entity { +public class BoatEntity extends Entity implements Tickable { /** * Required when IS_BUOYANT is sent in order for boats to work in the water.
@@ -58,6 +58,7 @@ public class BoatEntity extends Entity { private float paddleTimeLeft; private boolean isPaddlingRight; private float paddleTimeRight; + private boolean doTick; /** * Saved for using the "pick" functionality on a boat. @@ -133,34 +134,16 @@ public class BoatEntity extends Entity { public void setPaddlingLeft(BooleanEntityMetadata entityMetadata) { isPaddlingLeft = entityMetadata.getPrimitiveValue(); - if (isPaddlingLeft) { - // Java sends simply "true" and "false" (is_paddling_left), Bedrock keeps sending packets as you're rowing - // This is an asynchronous method that emulates Bedrock rowing until "false" is sent. - paddleTimeLeft = 0f; - if (!this.passengers.isEmpty()) { - // Get the entity by the first stored passenger and convey motion in this manner - Entity entity = this.passengers.get(0); - if (entity != null) { - updateLeftPaddle(session, entity); - } - } - } else { - // Indicate that the row position should be reset + if (!isPaddlingLeft) { + paddleTimeLeft = 0.0f; dirtyMetadata.put(EntityDataTypes.ROW_TIME_LEFT, 0.0f); } } public void setPaddlingRight(BooleanEntityMetadata entityMetadata) { isPaddlingRight = entityMetadata.getPrimitiveValue(); - if (isPaddlingRight) { - paddleTimeRight = 0f; - if (!this.passengers.isEmpty()) { - Entity entity = this.passengers.get(0); - if (entity != null) { - updateRightPaddle(session, entity); - } - } - } else { + if (!isPaddlingRight) { + paddleTimeRight = 0.0f; dirtyMetadata.put(EntityDataTypes.ROW_TIME_RIGHT, 0.0f); } } @@ -186,29 +169,26 @@ public class BoatEntity extends Entity { } } - private void updateLeftPaddle(GeyserSession session, Entity rower) { + @Override + public void tick() { + // Java sends simply "true" and "false" (is_paddling_left), Bedrock keeps sending packets as you're rowing + doTick = !doTick; // Run every 100 ms + if (!doTick || passengers.isEmpty()) { + return; + } + + Entity rower = passengers.get(0); + if (rower == null) { + return; + } + if (isPaddlingLeft) { paddleTimeLeft += ROWING_SPEED; sendAnimationPacket(session, rower, AnimatePacket.Action.ROW_LEFT, paddleTimeLeft); - - session.scheduleInEventLoop(() -> - updateLeftPaddle(session, rower), - 100, - TimeUnit.MILLISECONDS - ); } - } - - private void updateRightPaddle(GeyserSession session, Entity rower) { if (isPaddlingRight) { paddleTimeRight += ROWING_SPEED; sendAnimationPacket(session, rower, AnimatePacket.Action.ROW_RIGHT, paddleTimeRight); - - session.scheduleInEventLoop(() -> - updateRightPaddle(session, rower), - 100, - TimeUnit.MILLISECONDS - ); } } diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 95d5acb47..63022636c 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -1167,6 +1167,8 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { /** * Schedules a task and prints a stack trace if an error occurs. + *

+ * The task will not run if the session is closed. */ public ScheduledFuture scheduleInEventLoop(Runnable runnable, long duration, TimeUnit timeUnit) { return eventLoop.schedule(() -> { From 2471de100be3f229bfa415ec887e48a29002d2b2 Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Wed, 24 Apr 2024 06:56:15 -0700 Subject: [PATCH 068/272] Add system property Geyser.RakSendCookie to allow disabling cookie send (#4598) --- .../java/org/geysermc/geyser/network/netty/GeyserServer.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java b/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java index 652901f36..a67bd8a32 100644 --- a/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java +++ b/core/src/main/java/org/geysermc/geyser/network/netty/GeyserServer.java @@ -228,6 +228,9 @@ public final class GeyserServer { int rakGlobalPacketLimit = positivePropOrDefault("Geyser.RakGlobalPacketLimit", DEFAULT_GLOBAL_PACKET_LIMIT); this.geyser.getLogger().debug("Setting RakNet global packet limit to " + rakGlobalPacketLimit); + boolean rakSendCookie = Boolean.parseBoolean(System.getProperty("Geyser.RakSendCookie", "true")); + this.geyser.getLogger().debug("Setting RakNet send cookie to " + rakSendCookie); + return new ServerBootstrap() .channelFactory(RakChannelFactory.server(TRANSPORT.datagramChannel())) .group(group, childGroup) @@ -235,7 +238,7 @@ public final class GeyserServer { .option(RakChannelOption.RAK_MAX_MTU, this.geyser.getConfig().getMtu()) .option(RakChannelOption.RAK_PACKET_LIMIT, rakPacketLimit) .option(RakChannelOption.RAK_GLOBAL_PACKET_LIMIT, rakGlobalPacketLimit) - .option(RakChannelOption.RAK_SEND_COOKIE, true) + .option(RakChannelOption.RAK_SEND_COOKIE, rakSendCookie) .childHandler(serverInitializer); } From 099e968bde8e9981c7467b4f82c87a85cd0bc8e0 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Fri, 19 Apr 2024 19:21:44 -0400 Subject: [PATCH 069/272] Initial, incomplete pass at Java 1.20.5 --- .../geyser/entity/type/FireworkEntity.java | 2 +- .../geyser/entity/type/ItemEntity.java | 4 +- .../geyser/entity/type/ItemFrameEntity.java | 4 +- .../entity/type/ThrowableItemEntity.java | 2 +- .../entity/type/ThrownPotionEntity.java | 2 +- .../geyser/inventory/GeyserItemStack.java | 31 +++--- .../geysermc/geyser/inventory/Inventory.java | 2 +- .../geyser/inventory/click/ClickPlan.java | 2 +- .../inventory/recipe/GeyserShapedRecipe.java | 2 +- .../recipe/GeyserShapelessRecipe.java | 2 +- .../recipe/GeyserStonecutterData.java | 2 +- .../geysermc/geyser/item/type/ArmorItem.java | 6 +- .../geysermc/geyser/item/type/ArrowItem.java | 8 +- .../geyser/item/type/AxolotlBucketItem.java | 7 +- .../geysermc/geyser/item/type/BannerItem.java | 6 +- .../geysermc/geyser/item/type/ChestItem.java | 7 +- .../geyser/item/type/CompassItem.java | 8 +- .../geyser/item/type/CrossbowItem.java | 10 +- .../geyser/item/type/DecoratedPotItem.java | 6 +- .../geyser/item/type/DyeableArmorItem.java | 6 +- .../item/type/DyeableHorseArmorItem.java | 6 +- .../geyser/item/type/EnchantedBookItem.java | 6 +- .../geyser/item/type/FilledMapItem.java | 2 +- .../geyser/item/type/FireworkRocketItem.java | 6 +- .../geyser/item/type/FireworkStarItem.java | 6 +- .../geyser/item/type/FishingRodItem.java | 7 +- .../geyser/item/type/GoatHornItem.java | 2 +- .../org/geysermc/geyser/item/type/Item.java | 63 +++++++----- .../geysermc/geyser/item/type/MapItem.java | 6 +- .../geyser/item/type/PlayerHeadItem.java | 6 +- .../geysermc/geyser/item/type/PotionItem.java | 16 +-- .../geysermc/geyser/item/type/ShieldItem.java | 6 +- .../geyser/item/type/ShulkerBoxItem.java | 71 ++++++------- .../geyser/item/type/TippedArrowItem.java | 4 +- .../item/type/TropicalFishBucketItem.java | 6 +- .../geyser/item/type/WritableBookItem.java | 6 +- .../geyser/item/type/WrittenBookItem.java | 6 +- .../populator/RecipeRegistryPopulator.java | 4 +- .../geyser/registry/type/ItemMappings.java | 2 +- .../inventory/InventoryTranslator.java | 2 +- .../inventory/PlayerInventoryTranslator.java | 4 +- .../StonecutterInventoryTranslator.java | 2 +- .../item/CustomItemTranslator.java | 30 +++--- .../{inventory => }/item/ItemTranslator.java | 99 +++++++++---------- .../BedrockBlockPickRequestTranslator.java | 2 +- .../bedrock/BedrockBookEditTranslator.java | 2 +- ...BedrockInventoryTransactionTranslator.java | 4 +- .../player/BedrockActionTranslator.java | 2 +- .../java/JavaUpdateRecipesTranslator.java | 4 +- .../entity/JavaSetEquipmentTranslator.java | 4 +- .../JavaContainerSetSlotTranslator.java | 4 +- .../JavaMerchantOffersTranslator.java | 4 +- .../level/JavaLevelParticlesTranslator.java | 4 +- .../geysermc/geyser/util/InventoryUtils.java | 2 +- 54 files changed, 285 insertions(+), 234 deletions(-) rename core/src/main/java/org/geysermc/geyser/translator/{inventory => }/item/CustomItemTranslator.java (80%) rename core/src/main/java/org/geysermc/geyser/translator/{inventory => }/item/ItemTranslator.java (88%) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java index 7a544f23c..171849ce5 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.entity.type; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.Tag; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java index 69fb3faab..226ad7df8 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.entity.type; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; @@ -37,7 +37,7 @@ import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; import java.util.UUID; import java.util.concurrent.CompletableFuture; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java index ad1d4b928..453125945 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.entity.type; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.object.Direction; import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; @@ -42,7 +42,7 @@ import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; import lombok.Getter; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InventoryUtils; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableItemEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableItemEntity.java index 39c8386bd..3c080345e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableItemEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableItemEntity.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.entity.type; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java index 1b5c1d2d0..cea371963 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.entity.type; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.math.vector.Vector3f; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java b/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java index 4ff8db9f0..dd1aaea81 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java @@ -25,7 +25,8 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import lombok.AccessLevel; import lombok.Data; @@ -34,12 +35,13 @@ import lombok.Getter; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; +import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; @Data public class GeyserItemStack { @@ -47,26 +49,26 @@ public class GeyserItemStack { private final int javaId; private int amount; - private CompoundTag nbt; + private DataComponentPatch components; private int netId; @Getter(AccessLevel.NONE) @EqualsAndHashCode.Exclude private Item item; - private GeyserItemStack(int javaId, int amount, CompoundTag nbt) { - this(javaId, amount, nbt, 1); + private GeyserItemStack(int javaId, int amount, DataComponentPatch components) { + this(javaId, amount, components, 1); } - private GeyserItemStack(int javaId, int amount, CompoundTag nbt, int netId) { + private GeyserItemStack(int javaId, int amount, DataComponentPatch components, int netId) { this.javaId = javaId; this.amount = amount; - this.nbt = nbt; + this.components = components; this.netId = netId; } public static @NonNull GeyserItemStack from(@Nullable ItemStack itemStack) { - return itemStack == null ? EMPTY : new GeyserItemStack(itemStack.getId(), itemStack.getAmount(), itemStack.getNbt()); + return itemStack == null ? EMPTY : new GeyserItemStack(itemStack.getId(), itemStack.getAmount(), itemStack.getDataComponentPatch()); } public int getJavaId() { @@ -78,7 +80,12 @@ public class GeyserItemStack { } public @Nullable CompoundTag getNbt() { - return isEmpty() ? null : nbt; + Thread.dumpStack(); + return null; + } + + public @Nullable DataComponentPatch getComponents() { + return isEmpty() ? null : components; } public int getNetId() { @@ -98,14 +105,14 @@ public class GeyserItemStack { } public @Nullable ItemStack getItemStack(int newAmount) { - return isEmpty() ? null : new ItemStack(javaId, newAmount, nbt); + return isEmpty() ? null : new ItemStack(javaId, newAmount, components); } public ItemData getItemData(GeyserSession session) { if (isEmpty()) { return ItemData.AIR; } - ItemData.Builder itemData = ItemTranslator.translateToBedrock(session, javaId, amount, nbt); + ItemData.Builder itemData = ItemTranslator.translateToBedrock(session, javaId, amount, components); itemData.netId(getNetId()); itemData.usingNetId(true); return itemData.build(); @@ -131,6 +138,6 @@ public class GeyserItemStack { } public GeyserItemStack copy(int newAmount) { - return isEmpty() ? EMPTY : new GeyserItemStack(javaId, newAmount, nbt == null ? null : nbt.clone(), netId); + return isEmpty() ? EMPTY : new GeyserItemStack(javaId, newAmount, components == null ? null : components.clone(), netId); } } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java b/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java index 3376d6c26..b78bbe1b3 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java @@ -38,7 +38,7 @@ import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; import org.jetbrains.annotations.Range; import java.util.Arrays; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/click/ClickPlan.java b/core/src/main/java/org/geysermc/geyser/inventory/click/ClickPlan.java index f31f6d82f..a118670af 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/click/ClickPlan.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/click/ClickPlan.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.inventory.click; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.inventory.ContainerActionType; import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import com.github.steveice10.mc.protocol.data.game.inventory.MoveToHotbarAction; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapedRecipe.java b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapedRecipe.java index 05c17cf9f..d420170f4 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapedRecipe.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapedRecipe.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.inventory.recipe; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; import com.github.steveice10.mc.protocol.data.game.recipe.data.ShapedRecipeData; import org.checkerframework.checker.nullness.qual.Nullable; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapelessRecipe.java b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapelessRecipe.java index e300e3ec8..e6eabea2d 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapelessRecipe.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapelessRecipe.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.inventory.recipe; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; import com.github.steveice10.mc.protocol.data.game.recipe.data.ShapelessRecipeData; import org.checkerframework.checker.nullness.qual.Nullable; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserStonecutterData.java b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserStonecutterData.java index 22163eced..ce044e745 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserStonecutterData.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserStonecutterData.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.inventory.recipe; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import org.checkerframework.checker.nullness.qual.Nullable; /** diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java index b58f760d1..669791705 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java @@ -25,9 +25,11 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.item.ArmorMaterial; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; @@ -41,8 +43,8 @@ public class ArmorItem extends Item { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); if (tag.get("Trim") instanceof CompoundTag trim) { StringTag material = trim.remove("material"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java index 938d4a79a..2462f374c 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java @@ -25,7 +25,9 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.PotionContents; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; @@ -44,9 +46,9 @@ public class ArrowItem extends Item { TippedArrowPotion tippedArrowPotion = TippedArrowPotion.getByBedrockId(itemData.getDamage()); ItemStack itemStack = super.translateToJava(itemData, mapping, mappings); if (tippedArrowPotion != null) { - itemStack = Items.TIPPED_ARROW.newItemStack(itemStack.getAmount(), itemStack.getNbt()); + itemStack = Items.TIPPED_ARROW.newItemStack(itemStack.getAmount(), itemStack.getDataComponentPatch()); StringTag potionTag = new StringTag("Potion", tippedArrowPotion.getJavaIdentifier()); - itemStack.getNbt().put(potionTag); + itemStack.getDataComponentPatch().put(DataComponentType.POTION_CONTENTS, new PotionContents()); } return itemStack; } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java index 81d7bf116..6e4e6c6fc 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java @@ -25,10 +25,11 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.ByteTag; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.MinecraftLocale; @@ -38,8 +39,8 @@ public class AxolotlBucketItem extends Item { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); // Bedrock Edition displays the properties of the axolotl. Java does not. // To work around this, set the custom name to the Axolotl translation and it's displayed correctly diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index 344668836..9cd7aea42 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; @@ -32,6 +33,7 @@ import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtList; import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; @@ -120,8 +122,8 @@ public class BannerItem extends BlockItem { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); CompoundTag blockEntityTag = tag.remove("BlockEntityTag"); if (blockEntityTag != null && blockEntityTag.get("Patterns") instanceof ListTag patterns) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java index 99857006c..2611c8ff6 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java @@ -25,8 +25,9 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; public class ChestItem extends BlockItem { @@ -36,8 +37,8 @@ public class ChestItem extends BlockItem { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); // Strip the BlockEntityTag from the chests contents // sent to the client. The client does not parse this diff --git a/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java b/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java index 87da96447..f3933d83b 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java @@ -25,12 +25,14 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.ByteTag; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; @@ -58,8 +60,8 @@ public class CompassItem extends Item { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); Tag lodestoneTag = tag.get("LodestoneTracked"); if (lodestoneTag instanceof ByteTag) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java index e409dccfb..1ea468721 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java @@ -25,14 +25,16 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.*; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; public class CrossbowItem extends Item { public CrossbowItem(String javaIdentifier, Builder builder) { @@ -40,8 +42,8 @@ public class CrossbowItem extends Item { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); ListTag chargedProjectiles = tag.get("ChargedProjectiles"); if (chargedProjectiles != null) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java index 10d2a1bcc..bfa86d2ad 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java @@ -25,9 +25,11 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; public class DecoratedPotItem extends BlockItem { @@ -37,8 +39,8 @@ public class DecoratedPotItem extends BlockItem { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) { if (blockEntityTag.remove("sherds") instanceof ListTag sherds) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java index dbcff7d0b..f1b10474d 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java @@ -25,8 +25,10 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.item.ArmorMaterial; import org.geysermc.geyser.item.DyeableLeatherItem; import org.geysermc.geyser.registry.type.ItemMapping; @@ -38,8 +40,8 @@ public class DyeableArmorItem extends ArmorItem implements DyeableLeatherItem { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); DyeableLeatherItem.translateNbtToBedrock(tag); } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java index 0d37f5eab..39787ae2f 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java @@ -25,8 +25,10 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.item.DyeableLeatherItem; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; @@ -37,8 +39,8 @@ public class DyeableHorseArmorItem extends Item implements DyeableLeatherItem { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); DyeableLeatherItem.translateNbtToBedrock(tag); } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java index ac0751c73..c51278947 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java @@ -25,10 +25,12 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; import java.util.ArrayList; @@ -40,8 +42,8 @@ public class EnchantedBookItem extends Item { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); List newTags = new ArrayList<>(); Tag enchantmentTag = tag.remove("StoredEnchantments"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java index 963373523..8125ce101 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.nbt.NbtMap; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java index 3559cdf4d..6be1be15d 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java @@ -25,8 +25,10 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.*; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.FireworkColor; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; @@ -38,8 +40,8 @@ public class FireworkRocketItem extends Item { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); CompoundTag fireworks = tag.get("Fireworks"); if (fireworks == null) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java index 9c13d7793..6d4347e9e 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java @@ -25,11 +25,13 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntArrayTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; @@ -39,8 +41,8 @@ public class FireworkStarItem extends Item { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); Tag explosion = tag.remove("Explosion"); if (explosion instanceof CompoundTag) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java index f63a1ec5a..50a0bddbc 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java @@ -25,10 +25,11 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; public class FishingRodItem extends Item { @@ -37,8 +38,8 @@ public class FishingRodItem extends Item { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); // Fix damage inconsistency Tag damage = tag.get("Damage"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java index aacb906c9..60b201961 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/Item.java b/core/src/main/java/org/geysermc/geyser/item/type/Item.java index 3701b5189..df3c5effe 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/Item.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/Item.java @@ -26,10 +26,18 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.Identifier; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.ItemEnchantments; import com.github.steveice10.opennbt.tag.builtin.*; +import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; +import org.cloudburstmc.nbt.NbtList; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.item.Enchantment; @@ -38,7 +46,7 @@ import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.text.MinecraftLocale; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.util.InventoryUtils; @@ -107,7 +115,7 @@ public class Item { public @NonNull ItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { if (itemData.getTag() == null) { - return new ItemStack(javaId, itemData.getCount(), new CompoundTag("")); + return new ItemStack(javaId, itemData.getCount(), null); } return new ItemStack(javaId, itemData.getCount(), ItemTranslator.translateToJavaNBT("", itemData.getTag())); } @@ -117,22 +125,31 @@ public class Item { } /** - * Takes NBT from Java Edition and converts any value that Bedrock parses differently. + * Takes components from Java Edition and map them into Bedrock. */ - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - if (tag.get("display") instanceof CompoundTag displayTag) { - if (displayTag.get("Lore") instanceof ListTag listTag) { - List lore = new ArrayList<>(); - for (Tag subTag : listTag.getValue()) { - if (!(subTag instanceof StringTag)) continue; - lore.add(new StringTag("", MessageTranslator.convertMessageLenient(((StringTag) subTag).getValue(), session.locale()))); - } - displayTag.put(new ListTag("Lore", lore)); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { +// // Basing off of ItemStack#getHoverName as of 1.20.5. VERIFY?? +// Component customName = components.get(DataComponentType.CUSTOM_NAME); +// if (customName == null) { +// customName = components.get(DataComponentType.ITEM_NAME); +// } +// if (customName != null) { +// +// } + List loreComponents = components.get(DataComponentType.LORE); + if (loreComponents != null) { + List lore = new ArrayList<>(); + for (Component loreComponent : loreComponents) { + lore.add(MessageTranslator.convertMessage(loreComponent, session.locale())); } + builder.putList("Lore", NbtType.STRING, lore); } List newTags = new ArrayList<>(); - Tag enchantmentTag = tag.remove("Enchantments"); + ItemEnchantments enchantments = components.get(DataComponentType.ENCHANTMENTS); + if (enchantments != null) { + + } if (enchantmentTag instanceof ListTag listTag) { for (Tag subTag : listTag.getValue()) { if (!(subTag instanceof CompoundTag)) continue; @@ -211,10 +228,7 @@ public class Item { } } - protected final @Nullable CompoundTag remapEnchantment(GeyserSession session, CompoundTag tag, CompoundTag rootTag) { - Tag javaEnchId = tag.get("id"); - if (!(javaEnchId instanceof StringTag)) - return null; + protected final @Nullable NbtMap remapEnchantment(GeyserSession session, ItemEnchantments, NbtMapBuilder rootBuilder) { Enchantment enchantment = Enchantment.getByJavaIdentifier(((StringTag) javaEnchId).getValue()); if (enchantment == null) { @@ -231,11 +245,10 @@ public class Item { Tag javaEnchLvl = tag.get("lvl"); - CompoundTag bedrockTag = new CompoundTag(""); - bedrockTag.put(new ShortTag("id", (short) enchantment.ordinal())); - // If the tag cannot parse, Java Edition 1.18.2 sets to 0 - bedrockTag.put(new ShortTag("lvl", javaEnchLvl != null && javaEnchLvl.getValue() instanceof Number lvl ? lvl.shortValue() : (short) 0)); - return bedrockTag; + NbtMapBuilder builder = NbtMap.builder(); + builder.putShort("id", (short) enchantment.ordinal()); + builder.putShort("lvl", ); + return builder.build(); } private void addSweeping(GeyserSession session, CompoundTag itemTag, int level) { @@ -258,8 +271,8 @@ public class Item { /* Translation methods end */ - public ItemStack newItemStack(int count, CompoundTag tag) { - return new ItemStack(this.javaId, count, tag); + public ItemStack newItemStack(int count, DataComponentPatch components) { + return new ItemStack(this.javaId, count, components); } public void setJavaId(int javaId) { // TODO like this? diff --git a/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java b/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java index 4405b66ad..8dbeeb57f 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java @@ -25,8 +25,10 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.*; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; @@ -36,8 +38,8 @@ public class MapItem extends Item { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); Tag mapId = tag.remove("map"); if (mapId == null || !(mapId.getValue() instanceof Number number)) return; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java index 662448a52..4aefcf765 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java @@ -25,10 +25,12 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.text.MinecraftLocale; @@ -40,8 +42,8 @@ public class PlayerHeadItem extends Item { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); CompoundTag displayTag; if (tag.get("display") instanceof CompoundTag existingDisplayTag) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java index 24dd56ef2..26c468fb1 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java @@ -25,7 +25,9 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.PotionContents; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; @@ -35,8 +37,8 @@ import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.item.Potion; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; -import org.geysermc.geyser.translator.inventory.item.CustomItemTranslator; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.CustomItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; public class PotionItem extends Item { public PotionItem(String javaIdentifier, Builder builder) { @@ -45,10 +47,10 @@ public class PotionItem extends Item { @Override public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) { - if (itemStack.getNbt() == null) return super.translateToBedrock(itemStack, mapping, mappings); - Tag potionTag = itemStack.getNbt().get("Potion"); - if (potionTag instanceof StringTag) { - ItemDefinition customItemDefinition = CustomItemTranslator.getCustomItem(itemStack.getNbt(), mapping); + if (itemStack.getDataComponentPatch() == null) return super.translateToBedrock(itemStack, mapping, mappings); + PotionContents potionContents = itemStack.getDataComponentPatch().get(DataComponentType.POTION_CONTENTS); + if (potionContents != null) { + ItemDefinition customItemDefinition = CustomItemTranslator.getCustomItem(itemStack.getDataComponentPatch(), mapping); if (customItemDefinition == null) { Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue()); if (potion != null) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java index c13dd4fcf..cd940c87c 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java @@ -25,11 +25,13 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.item.components.ToolTier; import org.geysermc.geyser.session.GeyserSession; @@ -39,8 +41,8 @@ public class ShieldItem extends Item { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) { if (blockEntityTag.get("Patterns") instanceof ListTag patterns) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java index 717bad9a4..e2259eb5d 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java @@ -26,68 +26,61 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.Identifier; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.opennbt.tag.builtin.*; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.nbt.NbtType; +import org.geysermc.geyser.item.Items; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.util.MathUtils; +import java.util.ArrayList; +import java.util.List; + public class ShulkerBoxItem extends BlockItem { public ShulkerBoxItem(String javaIdentifier, Builder builder) { super(javaIdentifier, builder); } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); - CompoundTag blockEntityTag = tag.get("BlockEntityTag"); - if (blockEntityTag == null) { + List contents = components.get(DataComponentType.CONTAINER); + if (contents == null || contents.isEmpty()) { // Empty shulker box return; } - if (blockEntityTag.get("Items") == null) return; - ListTag itemsList = new ListTag("Items"); - for (Tag item : (ListTag) blockEntityTag.get("Items")) { - CompoundTag itemData = (CompoundTag) item; // Information about the item - CompoundTag boxItemTag = new CompoundTag(""); // Final item tag to add to the list - boxItemTag.put(new ByteTag("Slot", (byte) (MathUtils.getNbtByte(itemData.get("Slot").getValue()) & 255))); - boxItemTag.put(new ByteTag("WasPickedUp", (byte) 0)); // ??? - - ItemMapping boxMapping = session.getItemMappings().getMapping(Identifier.formalize(((StringTag) itemData.get("id")).getValue())); - - if (boxMapping == null) { - // If invalid ID + List itemsList = new ArrayList<>(); + for (int slot = 0; slot < contents.size(); slot++) { + ItemStack item = contents.get(slot); + if (item.getId() == Items.AIR_ID) { continue; } + NbtMapBuilder boxItemNbt = NbtMap.builder(); // Final item tag to add to the list + boxItemNbt.putByte("Slot", (byte) slot); + boxItemNbt.putByte("WasPickedUp", (byte) 0); // ??? - boxItemTag.put(new StringTag("Name", boxMapping.getBedrockIdentifier())); - boxItemTag.put(new ShortTag("Damage", (short) boxMapping.getBedrockData())); - boxItemTag.put(new ByteTag("Count", MathUtils.getNbtByte(itemData.get("Count").getValue()))); + ItemMapping boxMapping = session.getItemMappings().getMapping(item.getId()); + + boxItemNbt.putString("Name", boxMapping.getBedrockIdentifier()); + boxItemNbt.putShort("Damage", (short) boxMapping.getBedrockData()); + boxItemNbt.putByte("Count", (byte) item.getAmount()); // Only the display name is what we have interest in, so just translate that if relevant - CompoundTag displayTag = itemData.get("tag"); - if (displayTag == null && boxMapping.hasTranslation()) { - displayTag = new CompoundTag("tag"); - } - if (displayTag != null) { - boxItemTag.put(ItemTranslator.translateDisplayProperties(session, displayTag, boxMapping, '7')); + DataComponentPatch boxComponents = item.getDataComponentPatch(); + if (boxComponents != null) { + boxItemNbt.put(ItemTranslator.translateDisplayProperties(session, displayTag, boxMapping, '7')); } - itemsList.add(boxItemTag); + itemsList.add(boxItemNbt.build()); } - tag.put(itemsList); - - // Strip the BlockEntityTag from the chests contents - // sent to the client. The client does not parse this - // or use it for anything, as this tag is fully - // server-side, so we remove it to reduce bandwidth and - // solve potential issues with very large tags. - - // There was a problem in the past where this would strip - // NBT data in creative mode, however with the new server - // authoritative inventories, this is no longer a concern. - tag.remove("BlockEntityTag"); + builder.putList("Items", NbtType.COMPOUND, itemsList); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java index f78836d16..fcf562ba5 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; @@ -33,7 +33,7 @@ import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.item.TippedArrowPotion; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; public class TippedArrowItem extends ArrowItem { public TippedArrowItem(String javaIdentifier, Builder builder) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java index 8b4e35d1e..17f90ca12 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java @@ -25,12 +25,14 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.*; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.TextDecoration; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.entity.type.living.animal.TropicalFishEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.MinecraftLocale; @@ -47,8 +49,8 @@ public class TropicalFishBucketItem extends Item { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); // Prevent name from appearing as "Bucket of" tag.put(new ByteTag("AppendCustomName", (byte) 1)); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java index dfebecf7d..67221b1c6 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java @@ -25,11 +25,13 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.text.MessageTranslator; @@ -43,8 +45,8 @@ public class WritableBookItem extends Item { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { - super.translateNbtToBedrock(session, tag); + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); ListTag pagesTag = tag.remove("pages"); if (pagesTag == null) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java index 045aaa416..0198e73ff 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; @@ -32,6 +33,7 @@ import com.github.steveice10.opennbt.tag.builtin.Tag; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.text.MessageTranslator; @@ -48,13 +50,13 @@ public class WrittenBookItem extends WritableBookItem { } @Override - public void translateNbtToBedrock(@NonNull GeyserSession session, @NonNull CompoundTag tag) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { boolean isValid = isValidWrittenBook(tag); if (!isValid) { tag.remove("pages"); } - super.translateNbtToBedrock(session, tag); + super.translateComponentsToBedrock(session, components, builder); if (!isValid) { CompoundTag invalidTagPage = new CompoundTag(""); diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java index 5e4d5fc7a..34e855212 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.registry.populator; import com.fasterxml.jackson.databind.JsonNode; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; import com.github.steveice10.mc.protocol.data.game.recipe.RecipeType; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; @@ -48,7 +48,7 @@ import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.text.GeyserLocale; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; import java.io.ByteArrayInputStream; import java.io.IOException; diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java b/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java index 40359b437..33908a7e7 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java +++ b/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.registry.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2ObjectMap; import lombok.Builder; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java index 95ec99412..e6e0c6340 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; import com.github.steveice10.opennbt.tag.builtin.IntTag; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java index 1447f2b5b..429b577ce 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetCreativeModeSlotPacket; @@ -53,7 +53,7 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.skin.FakeHeadProvider; import org.geysermc.geyser.text.GeyserLocale; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.util.InventoryUtils; import java.util.Arrays; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java index 50c040a0b..d3d15680a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/CustomItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java similarity index 80% rename from core/src/main/java/org/geysermc/geyser/translator/inventory/item/CustomItemTranslator.java rename to core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java index 06d1e3aa6..d5f85dcc3 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/CustomItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,11 +23,10 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.geyser.translator.inventory.item; +package org.geysermc.geyser.translator.item; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.IntTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import it.unimi.dsi.fastutil.Pair; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; @@ -44,8 +43,8 @@ import java.util.OptionalInt; public final class CustomItemTranslator { @Nullable - public static ItemDefinition getCustomItem(CompoundTag nbt, ItemMapping mapping) { - if (nbt == null) { + public static ItemDefinition getCustomItem(DataComponentPatch components, ItemMapping mapping) { + if (components == null) { return null; } List> customMappings = mapping.getCustomItemOptions(); @@ -53,10 +52,11 @@ public final class CustomItemTranslator { return null; } - int customModelData = nbt.get("CustomModelData") instanceof IntTag customModelDataTag ? customModelDataTag.getValue() : 0; + // TODO getOrDefault + int customModelData = components.get(DataComponentType.CUSTOM_MODEL_DATA); boolean checkDamage = mapping.getJavaItem().maxDamage() > 0; - int damage = !checkDamage ? 0 : nbt.get("Damage") instanceof IntTag damageTag ? damageTag.getValue() : 0; - boolean unbreakable = checkDamage && !isDamaged(nbt, damage); + int damage = !checkDamage ? 0 : components.get(DataComponentType.DAMAGE); + boolean unbreakable = checkDamage && !isDamaged(components, damage); for (Pair mappingTypes : customMappings) { CustomItemOptions options = mappingTypes.key(); @@ -105,15 +105,15 @@ public final class CustomItemTranslator { /* These two functions are based off their Mojmap equivalents from 1.19.2 */ - private static boolean isDamaged(CompoundTag nbt, int damage) { - return isDamagableItem(nbt) && damage > 0; + private static boolean isDamaged(DataComponentPatch components, int damage) { + return isDamagableItem(components) && damage > 0; } - private static boolean isDamagableItem(CompoundTag nbt) { + private static boolean isDamagableItem(DataComponentPatch components) { // mapping.getMaxDamage > 0 should also be checked (return false if not true) but we already check prior to this function - Tag unbreakableTag = nbt.get("Unbreakable"); + Boolean unbreakable = components.get(DataComponentType.UNBREAKABLE); // Tag must either not be present or be set to false - return unbreakableTag == null || !(unbreakableTag.getValue() instanceof Number number) || number.byteValue() == 0; + return unbreakable == null || !unbreakable; } private CustomItemTranslator() { diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java similarity index 88% rename from core/src/main/java/org/geysermc/geyser/translator/inventory/item/ItemTranslator.java rename to core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index d1a256551..027c6b5ba 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,11 +23,15 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.geyser.translator.inventory.item; +package org.geysermc.geyser.translator.item; import com.github.steveice10.mc.protocol.data.game.Identifier; import com.github.steveice10.mc.protocol.data.game.entity.attribute.ModifierOperation; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.AdventureModePredicate; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.ItemAttributeModifiers; import com.github.steveice10.opennbt.tag.builtin.ByteArrayTag; import com.github.steveice10.opennbt.tag.builtin.ByteTag; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; @@ -133,20 +137,20 @@ public final class ItemTranslator { .build(); } - private static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, Item javaItem, ItemMapping bedrockItem, int count, CompoundTag tag) { - CompoundTag nbt = tag != null ? tag.clone() : null; + private static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, Item javaItem, ItemMapping bedrockItem, int count, DataComponentPatch components) { + NbtMapBuilder builder = NbtMap.builder(); - if (nbt != null) { - javaItem.translateNbtToBedrock(session, nbt); + if (components != null) { + javaItem.translateComponentsToBedrock(session, components, builder); } - nbt = translateDisplayProperties(session, nbt, bedrockItem); + translateDisplayProperties(session, components, bedrockItem); - if (nbt != null) { - Tag hideFlags = nbt.get("HideFlags"); - if (hideFlags == null || !hasFlagPresent(hideFlags, HIDE_ATTRIBUTES_FLAG)) { - // only add if the hide attribute modifiers flag is not present - addAttributeLore(nbt, session.locale()); + if (components != null) { + ItemAttributeModifiers attributeModifiers = components.get(DataComponentType.ATTRIBUTE_MODIFIERS); + if (attributeModifiers != null && attributeModifiers.isShowInTooltip()) { + // only add if attribute modifiers do not indicate to hide them + addAttributeLore(attributeModifiers, builder, session.locale()); } } @@ -173,10 +177,10 @@ public final class ItemTranslator { translateCustomItem(nbt, builder, bedrockItem); - if (nbt != null) { + if (components != null) { // Translate the canDestroy and canPlaceOn Java NBT - ListTag canDestroy = nbt.get("CanDestroy"); - ListTag canPlaceOn = nbt.get("CanPlaceOn"); + AdventureModePredicate canDestroy = components.get(DataComponentType.CAN_BREAK); + AdventureModePredicate canPlaceOn = components.get(DataComponentType.CAN_PLACE_ON); String[] canBreak = getCanModify(canDestroy); String[] canPlace = getCanModify(canPlaceOn); if (canBreak != null) { @@ -197,13 +201,8 @@ public final class ItemTranslator { * @param nbt the NBT of the ItemStack * @param language the locale of the player */ - private static void addAttributeLore(CompoundTag nbt, String language) { - ListTag attributeModifiers = nbt.get("AttributeModifiers"); - if (attributeModifiers == null) { - return; // nothing to convert to lore - } - - CompoundTag displayTag = nbt.get("display"); + private static void addAttributeLore(ItemAttributeModifiers modifiers, NbtMapBuilder builder, String language) { + CompoundTag displayTag = builder.get("display"); if (displayTag == null) { displayTag = new CompoundTag("display"); } @@ -214,25 +213,23 @@ public final class ItemTranslator { // maps each slot to the modifiers applied when in such slot Map> slotsToModifiers = new HashMap<>(); - for (Tag modifier : attributeModifiers) { - CompoundTag modifierTag = (CompoundTag) modifier; - + for (ItemAttributeModifiers.Entry entry : modifiers.getModifiers()) { // convert the modifier tag to a lore entry - String loreEntry = attributeToLore(modifierTag, language); + String loreEntry = attributeToLore(entry.getModifier(), language); if (loreEntry == null) { continue; // invalid or failed } StringTag loreTag = new StringTag("", loreEntry); - StringTag slotTag = modifierTag.get("Slot"); - if (slotTag == null) { + ItemAttributeModifiers.EquipmentSlotGroup slotGroup = entry.getSlot(); + if (slotGroup == ItemAttributeModifiers.EquipmentSlotGroup.ANY) { // modifier applies to all slots implicitly for (String slot : ALL_SLOTS) { slotsToModifiers.computeIfAbsent(slot, s -> new ArrayList<>()).add(loreTag); } } else { // modifier applies to only the specified slot - slotsToModifiers.computeIfAbsent(slotTag.getValue(), s -> new ArrayList<>()).add(loreTag); + slotsToModifiers.computeIfAbsent(slotGroup, s -> new ArrayList<>()).add(loreTag); } } @@ -262,31 +259,23 @@ public final class ItemTranslator { } @Nullable - private static String attributeToLore(CompoundTag modifier, String language) { - Tag amountTag = modifier.get("Amount"); - if (amountTag == null || !(amountTag.getValue() instanceof Number number)) { - return null; - } - double amount = number.doubleValue(); + private static String attributeToLore(ItemAttributeModifiers.AttributeModifier modifier, String language) { + double amount = modifier.getAmount(); if (amount == 0) { return null; } - if (!(modifier.get("AttributeName") instanceof StringTag nameTag)) { - return null; - } - String name = nameTag.getValue().replace("minecraft:", ""); - // the namespace does not need to be present, but if it is, the java client ignores it + String name = modifier.getName().replace("minecraft:", ""); + // the namespace does not need to be present, but if it is, the java client ignores it as of pre-1.20.5 String operationTotal; - Tag operationTag = modifier.get("Operation"); - ModifierOperation operation; - if (operationTag == null || (operation = ModifierOperation.from((int) operationTag.getValue())) == ModifierOperation.ADD) { + ModifierOperation operation = modifier.getOperation(); + if (operation == ModifierOperation.ADD) { if (name.equals("generic.knockback_resistance")) { amount *= 10; } operationTotal = ATTRIBUTE_FORMAT.format(amount); - } else if (operation == ModifierOperation.ADD_MULTIPLIED || operation == ModifierOperation.MULTIPLY) { + } else if (operation == ModifierOperation.ADD_MULTIPLIED_BASE || operation == ModifierOperation.ADD_MULTIPLIED_TOTAL) { operationTotal = ATTRIBUTE_FORMAT.format(amount * 100) + "%"; } else { GeyserImpl.getInstance().getLogger().warning("Unhandled ModifierOperation while adding item attributes: " + operation); @@ -363,12 +352,22 @@ public final class ItemTranslator { * @param canModifyJava the list of items in Java * @return the new list of items in Bedrock */ - private static String @Nullable [] getCanModify(ListTag canModifyJava) { - if (canModifyJava != null && canModifyJava.size() > 0) { - String[] canModifyBedrock = new String[canModifyJava.size()]; + // TODO this is now more complicated in 1.20.5. Yippee! + private static String @Nullable [] getCanModify(@Nullable AdventureModePredicate canModifyJava) { + if (canModifyJava == null) { + return null; + } + List predicates = canModifyJava.getPredicates(); + if (predicates.size() > 0) { + String[] canModifyBedrock = new String[predicates.size()]; for (int i = 0; i < canModifyBedrock.length; i++) { // Get the Java identifier of the block that can be placed - String block = Identifier.formalize(((StringTag) canModifyJava.get(i)).getValue()); + String location = predicates.get(i).getLocation(); + if (location == null) { + canModifyBedrock[i] = ""; // So it'll serialize + continue; // ??? + } + String block = Identifier.formalize(location); // Get the Bedrock identifier of the item and replace it. // This will unfortunately be limited - for example, beds and banners will be translated weirdly canModifyBedrock[i] = BlockRegistries.JAVA_TO_BEDROCK_IDENTIFIERS.getOrDefault(block, block).replace("minecraft:", ""); @@ -403,7 +402,7 @@ public final class ItemTranslator { } } - ItemDefinition definition = CustomItemTranslator.getCustomItem(itemStack.getNbt(), mapping); + ItemDefinition definition = CustomItemTranslator.getCustomItem(itemStack, mapping); if (definition == null) { // No custom item return itemDefinition; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java index 381adf2b7..59317fd7c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java index 6547044c3..ec1d62d16 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundEditBookPacket; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java index 4ac835268..8d005e515 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.entity.object.Direction; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; @@ -70,7 +70,7 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.SkullCache; import org.geysermc.geyser.skin.FakeHeadProvider; import org.geysermc.geyser.translator.inventory.InventoryTranslator; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.BlockUtils; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java index 33410f240..f5122b256 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java @@ -52,7 +52,7 @@ import org.geysermc.geyser.registry.type.BlockMapping; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.SkullCache; -import org.geysermc.geyser.translator.inventory.item.CustomItemTranslator; +import org.geysermc.geyser.translator.item.CustomItemTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.BlockUtils; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java index 94c69b780..aca02feab 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; import com.github.steveice10.mc.protocol.data.game.recipe.Recipe; import com.github.steveice10.mc.protocol.data.game.recipe.RecipeType; @@ -56,7 +56,7 @@ import org.geysermc.geyser.inventory.recipe.TrimRecipe; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.InventoryUtils; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java index 0c344bddc..c178f27d4 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Equipment; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundSetEquipmentPacket; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.entity.type.Entity; @@ -35,7 +35,7 @@ import org.geysermc.geyser.entity.type.player.PlayerEntity; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.skin.FakeHeadProvider; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java index 605a40d75..594c99291 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.inventory; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundContainerSetSlotPacket; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerId; @@ -41,7 +41,7 @@ import org.geysermc.geyser.inventory.recipe.GeyserShapedRecipe; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.geyser.translator.inventory.PlayerInventoryTranslator; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.InventoryUtils; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaMerchantOffersTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaMerchantOffersTranslator.java index 17a4314ec..68d2bcab3 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaMerchantOffersTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaMerchantOffersTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.inventory; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.inventory.VillagerTrade; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundMerchantOffersPacket; import org.cloudburstmc.nbt.NbtMap; @@ -41,7 +41,7 @@ import org.geysermc.geyser.inventory.MerchantContainer; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.InventoryUtils; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelParticlesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelParticlesTranslator.java index 11d9dbddf..78290f6bd 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelParticlesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelParticlesTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.level.particle.BlockParticleData; import com.github.steveice10.mc.protocol.data.game.level.particle.DustParticleData; import com.github.steveice10.mc.protocol.data.game.level.particle.FallingDustParticleData; @@ -49,7 +49,7 @@ import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.ParticleMapping; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.translator.inventory.item.ItemTranslator; +import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.DimensionUtils; diff --git a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java index 25976f0f5..e56aea8c9 100644 --- a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundPickItemPacket; From c1edf20734099c7d75933c25c2e388a6d2a9f5f8 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 20 Apr 2024 13:29:14 -0400 Subject: [PATCH 070/272] Here's the idea so far --- .../geyser/inventory/GeyserItemStack.java | 13 +- .../geysermc/geyser/item/type/ArmorItem.java | 4 +- .../geysermc/geyser/item/type/ArrowItem.java | 4 +- .../geyser/item/type/AxolotlBucketItem.java | 4 +- .../geysermc/geyser/item/type/BannerItem.java | 4 +- .../geysermc/geyser/item/type/ChestItem.java | 4 +- .../geyser/item/type/CompassItem.java | 4 +- .../geyser/item/type/CrossbowItem.java | 4 +- .../geyser/item/type/DecoratedPotItem.java | 4 +- .../geyser/item/type/DyeableArmorItem.java | 4 +- .../item/type/DyeableHorseArmorItem.java | 4 +- .../geyser/item/type/EnchantedBookItem.java | 4 +- .../geyser/item/type/FireworkRocketItem.java | 4 +- .../geyser/item/type/FireworkStarItem.java | 4 +- .../geyser/item/type/FishingRodItem.java | 4 +- .../org/geysermc/geyser/item/type/Item.java | 14 +- .../geysermc/geyser/item/type/MapItem.java | 4 +- .../geyser/item/type/PlayerHeadItem.java | 4 +- .../geysermc/geyser/item/type/PotionItem.java | 6 +- .../geysermc/geyser/item/type/ShieldItem.java | 4 +- .../geyser/item/type/ShulkerBoxItem.java | 19 +- .../item/type/TropicalFishBucketItem.java | 4 +- .../geyser/item/type/WritableBookItem.java | 4 +- .../geyser/item/type/WrittenBookItem.java | 4 +- .../translator/item/BedrockItemBuilder.java | 93 ++++++++ .../translator/item/CustomItemTranslator.java | 13 +- .../translator/item/ItemTranslator.java | 207 +++++++----------- 27 files changed, 241 insertions(+), 204 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java diff --git a/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java b/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java index dd1aaea81..7e621d3aa 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.inventory; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import lombok.AccessLevel; import lombok.Data; @@ -35,7 +35,6 @@ import lombok.Getter; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; -import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.registry.Registries; @@ -49,18 +48,18 @@ public class GeyserItemStack { private final int javaId; private int amount; - private DataComponentPatch components; + private DataComponents components; private int netId; @Getter(AccessLevel.NONE) @EqualsAndHashCode.Exclude private Item item; - private GeyserItemStack(int javaId, int amount, DataComponentPatch components) { + private GeyserItemStack(int javaId, int amount, DataComponents components) { this(javaId, amount, components, 1); } - private GeyserItemStack(int javaId, int amount, DataComponentPatch components, int netId) { + private GeyserItemStack(int javaId, int amount, DataComponents components, int netId) { this.javaId = javaId; this.amount = amount; this.components = components; @@ -68,7 +67,7 @@ public class GeyserItemStack { } public static @NonNull GeyserItemStack from(@Nullable ItemStack itemStack) { - return itemStack == null ? EMPTY : new GeyserItemStack(itemStack.getId(), itemStack.getAmount(), itemStack.getDataComponentPatch()); + return itemStack == null ? EMPTY : new GeyserItemStack(itemStack.getId(), itemStack.getAmount(), itemStack.getDataComponents()); } public int getJavaId() { @@ -84,7 +83,7 @@ public class GeyserItemStack { return null; } - public @Nullable DataComponentPatch getComponents() { + public @Nullable DataComponents getComponents() { return isEmpty() ? null : components; } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java index 669791705..eb5233b88 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; @@ -43,7 +43,7 @@ public class ArmorItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); if (tag.get("Trim") instanceof CompoundTag trim) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java index 2462f374c..cf66b036b 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java @@ -46,9 +46,9 @@ public class ArrowItem extends Item { TippedArrowPotion tippedArrowPotion = TippedArrowPotion.getByBedrockId(itemData.getDamage()); ItemStack itemStack = super.translateToJava(itemData, mapping, mappings); if (tippedArrowPotion != null) { - itemStack = Items.TIPPED_ARROW.newItemStack(itemStack.getAmount(), itemStack.getDataComponentPatch()); + itemStack = Items.TIPPED_ARROW.newItemStack(itemStack.getAmount(), itemStack.getDataComponents()); StringTag potionTag = new StringTag("Potion", tippedArrowPotion.getJavaIdentifier()); - itemStack.getDataComponentPatch().put(DataComponentType.POTION_CONTENTS, new PotionContents()); + itemStack.getDataComponents().put(DataComponentType.POTION_CONTENTS, new PotionContents()); } return itemStack; } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java index 6e4e6c6fc..d0aa1e901 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.ByteTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; @@ -39,7 +39,7 @@ public class AxolotlBucketItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); // Bedrock Edition displays the properties of the axolotl. Java does not. diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index 9cd7aea42..2a8ca9f15 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; @@ -122,7 +122,7 @@ public class BannerItem extends BlockItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); CompoundTag blockEntityTag = tag.remove("BlockEntityTag"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java index 2611c8ff6..8644ec8be 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; @@ -37,7 +37,7 @@ public class ChestItem extends BlockItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); // Strip the BlockEntityTag from the chests contents diff --git a/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java b/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java index f3933d83b..605d19852 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.ByteTag; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; @@ -60,7 +60,7 @@ public class CompassItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); Tag lodestoneTag = tag.get("LodestoneTracked"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java index 1ea468721..c38e2f2ba 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.*; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -42,7 +42,7 @@ public class CrossbowItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); ListTag chargedProjectiles = tag.get("ChargedProjectiles"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java index bfa86d2ad..74cabc3d9 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import org.checkerframework.checker.nullness.qual.NonNull; @@ -39,7 +39,7 @@ public class DecoratedPotItem extends BlockItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java index f1b10474d..fbe0222bc 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -40,7 +40,7 @@ public class DyeableArmorItem extends ArmorItem implements DyeableLeatherItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); DyeableLeatherItem.translateNbtToBedrock(tag); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java index 39787ae2f..09878e652 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -39,7 +39,7 @@ public class DyeableHorseArmorItem extends Item implements DyeableLeatherItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); DyeableLeatherItem.translateNbtToBedrock(tag); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java index c51278947..d3aa72cbc 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.Tag; @@ -42,7 +42,7 @@ public class EnchantedBookItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); List newTags = new ArrayList<>(); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java index 6be1be15d..b44dc08eb 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.*; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -40,7 +40,7 @@ public class FireworkRocketItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); CompoundTag fireworks = tag.get("Fireworks"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java index 6d4347e9e..80a32fc44 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntArrayTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; @@ -41,7 +41,7 @@ public class FireworkStarItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); Tag explosion = tag.remove("Explosion"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java index 50a0bddbc..0e1a4cc0e 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; @@ -38,7 +38,7 @@ public class FishingRodItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); // Fix damage inconsistency diff --git a/core/src/main/java/org/geysermc/geyser/item/type/Item.java b/core/src/main/java/org/geysermc/geyser/item/type/Item.java index df3c5effe..3ecf3be1b 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/Item.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/Item.java @@ -27,7 +27,7 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.Identifier; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.ItemEnchantments; import com.github.steveice10.opennbt.tag.builtin.*; @@ -103,12 +103,12 @@ public class Item { .definition(mapping.getBedrockDefinition()) .damage(mapping.getBedrockData()) .count(itemStack.getAmount()); - if (itemStack.getNbt() != null) { - builder.tag(ItemTranslator.translateNbtToBedrock(itemStack.getNbt())); + if (itemStack.getDataComponents() != null) { + builder.tag(ItemTranslator.translateNbtToBedrock(itemStack.getDataComponents())); } - CompoundTag nbt = itemStack.getNbt(); - ItemTranslator.translateCustomItem(nbt, builder, mapping); + DataComponents components = itemStack.getDataComponents(); + ItemTranslator.translateCustomItem(components, builder, mapping); return builder; } @@ -127,7 +127,7 @@ public class Item { /** * Takes components from Java Edition and map them into Bedrock. */ - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { // // Basing off of ItemStack#getHoverName as of 1.20.5. VERIFY?? // Component customName = components.get(DataComponentType.CUSTOM_NAME); // if (customName == null) { @@ -271,7 +271,7 @@ public class Item { /* Translation methods end */ - public ItemStack newItemStack(int count, DataComponentPatch components) { + public ItemStack newItemStack(int count, DataComponents components) { return new ItemStack(this.javaId, count, components); } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java b/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java index 8dbeeb57f..64e505800 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.*; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -38,7 +38,7 @@ public class MapItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); Tag mapId = tag.remove("map"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java index 4aefcf765..6ebc728cb 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; @@ -42,7 +42,7 @@ public class PlayerHeadItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); CompoundTag displayTag; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java index 26c468fb1..bed2945ba 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java @@ -47,10 +47,10 @@ public class PotionItem extends Item { @Override public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) { - if (itemStack.getDataComponentPatch() == null) return super.translateToBedrock(itemStack, mapping, mappings); - PotionContents potionContents = itemStack.getDataComponentPatch().get(DataComponentType.POTION_CONTENTS); + if (itemStack.getDataComponents() == null) return super.translateToBedrock(itemStack, mapping, mappings); + PotionContents potionContents = itemStack.getDataComponents().get(DataComponentType.POTION_CONTENTS); if (potionContents != null) { - ItemDefinition customItemDefinition = CustomItemTranslator.getCustomItem(itemStack.getDataComponentPatch(), mapping); + ItemDefinition customItemDefinition = CustomItemTranslator.getCustomItem(itemStack.getDataComponents(), mapping); if (customItemDefinition == null) { Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue()); if (potion != null) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java index cd940c87c..b3f9f57e3 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; @@ -41,7 +41,7 @@ public class ShieldItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java index e2259eb5d..3d5fa2444 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java @@ -25,11 +25,10 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.Identifier; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.opennbt.tag.builtin.*; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -38,7 +37,6 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.ItemTranslator; -import org.geysermc.geyser.util.MathUtils; import java.util.ArrayList; import java.util.List; @@ -49,7 +47,7 @@ public class ShulkerBoxItem extends BlockItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); List contents = components.get(DataComponentType.CONTAINER); @@ -73,9 +71,16 @@ public class ShulkerBoxItem extends BlockItem { boxItemNbt.putShort("Damage", (short) boxMapping.getBedrockData()); boxItemNbt.putByte("Count", (byte) item.getAmount()); // Only the display name is what we have interest in, so just translate that if relevant - DataComponentPatch boxComponents = item.getDataComponentPatch(); + DataComponents boxComponents = item.getDataComponents(); if (boxComponents != null) { - boxItemNbt.put(ItemTranslator.translateDisplayProperties(session, displayTag, boxMapping, '7')); + String customName = ItemTranslator.getCustomName(session, boxComponents, boxMapping, '7'); + if (customName != null) { + boxItemNbt.putCompound("tag", NbtMap.builder() + .putCompound("display", NbtMap.builder() + .putString("Name", customName) + .build()) + .build()); + } } itemsList.add(boxItemNbt.build()); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java index 17f90ca12..2ce0dd071 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.*; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; @@ -49,7 +49,7 @@ public class TropicalFishBucketItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); // Prevent name from appearing as "Bucket of" diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java index 67221b1c6..46b9b80ce 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; @@ -45,7 +45,7 @@ public class WritableBookItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { super.translateComponentsToBedrock(session, components, builder); ListTag pagesTag = tag.remove("pages"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java index 0198e73ff..46eceaa86 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; @@ -50,7 +50,7 @@ public class WrittenBookItem extends WritableBookItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponentPatch components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { boolean isValid = isValidWrittenBook(tag); if (!isValid) { tag.remove("pages"); diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java b/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java new file mode 100644 index 000000000..162d57120 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.translator.item; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.nbt.NbtType; + +import java.util.ArrayList; +import java.util.List; + +/** + * An intermediary class made to allow easy access to work-in-progress NBT, such as lore and display. + */ +public final class BedrockItemBuilder { + // All Bedrock-style + @Nullable + private String customName; + @Nullable + private List lore; + /** + * Miscellaneous NBT that will be put into the final item. + */ + @Nullable + private NbtMapBuilder builder; + + public BedrockItemBuilder setCustomName(String customName) { + this.customName = customName; + return this; + } + + @NonNull + public List getOrCreateLore() { + if (lore == null) { + lore = new ArrayList<>(); + } + return lore; + } + + @NonNull + public NbtMapBuilder getOrCreateNbt() { + if (builder == null) { + builder = NbtMap.builder(); + } + return builder; + } + + /** + * @return null if no NBT is needed on this item. + */ + @Nullable + public NbtMap build() { + if (customName != null || lore != null) { + NbtMapBuilder display = NbtMap.builder(); + if (customName != null) { + display.putString("Name", customName); + } + if (lore != null) { + display.putList("Lore", NbtType.STRING, lore); + } + getOrCreateNbt().put("display", display.build()); + } + if (builder == null) { + return null; + } + return builder.build(); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java index d5f85dcc3..8a541fb9b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.item; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import it.unimi.dsi.fastutil.Pair; import org.checkerframework.checker.nullness.qual.Nullable; @@ -43,7 +43,7 @@ import java.util.OptionalInt; public final class CustomItemTranslator { @Nullable - public static ItemDefinition getCustomItem(DataComponentPatch components, ItemMapping mapping) { + public static ItemDefinition getCustomItem(DataComponents components, ItemMapping mapping) { if (components == null) { return null; } @@ -52,10 +52,9 @@ public final class CustomItemTranslator { return null; } - // TODO getOrDefault - int customModelData = components.get(DataComponentType.CUSTOM_MODEL_DATA); + int customModelData = components.getOrDefault(DataComponentType.CUSTOM_MODEL_DATA, 0); boolean checkDamage = mapping.getJavaItem().maxDamage() > 0; - int damage = !checkDamage ? 0 : components.get(DataComponentType.DAMAGE); + int damage = !checkDamage ? 0 : components.getOrDefault(DataComponentType.DAMAGE, 0); boolean unbreakable = checkDamage && !isDamaged(components, damage); for (Pair mappingTypes : customMappings) { @@ -105,11 +104,11 @@ public final class CustomItemTranslator { /* These two functions are based off their Mojmap equivalents from 1.19.2 */ - private static boolean isDamaged(DataComponentPatch components, int damage) { + private static boolean isDamaged(DataComponents components, int damage) { return isDamagableItem(components) && damage > 0; } - private static boolean isDamagableItem(DataComponentPatch components) { + private static boolean isDamagableItem(DataComponents components) { // mapping.getMaxDamage > 0 should also be checked (return false if not true) but we already check prior to this function Boolean unbreakable = components.get(DataComponentType.UNBREAKABLE); // Tag must either not be present or be set to false diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index 027c6b5ba..b52861b35 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -25,11 +25,12 @@ package org.geysermc.geyser.translator.item; +import com.github.steveice10.mc.auth.data.GameProfile; import com.github.steveice10.mc.protocol.data.game.Identifier; import com.github.steveice10.mc.protocol.data.game.entity.attribute.ModifierOperation; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.item.component.AdventureModePredicate; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentPatch; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.ItemAttributeModifiers; import com.github.steveice10.opennbt.tag.builtin.ByteArrayTag; @@ -83,7 +84,6 @@ public final class ItemTranslator { */ private static final String[] ALL_SLOTS = new String[]{"mainhand", "offhand", "feet", "legs", "chest", "head"}; private static final DecimalFormat ATTRIBUTE_FORMAT = new DecimalFormat("0.#####"); - private static final byte HIDE_ATTRIBUTES_FLAG = 1 << 1; private ItemTranslator() { } @@ -102,23 +102,23 @@ public final class ItemTranslator { ItemStack itemStack = javaItem.translateToJava(data, bedrockItem, mappings); - if (itemStack.getNbt() != null) { - javaItem.translateNbtToJava(itemStack.getNbt(), bedrockItem); - if (itemStack.getNbt().isEmpty()) { - // Otherwise, seems to cause issues with villagers accepting books, and I don't see how this will break anything else. - Camotoy - itemStack = new ItemStack(itemStack.getId(), itemStack.getAmount(), null); - } - } +// if (itemStack.getNbt() != null) { +// javaItem.translateNbtToJava(itemStack.getNbt(), bedrockItem); +// if (itemStack.getNbt().isEmpty()) { +// // Otherwise, seems to cause issues with villagers accepting books, and I don't see how this will break anything else. - Camotoy +// itemStack = new ItemStack(itemStack.getId(), itemStack.getAmount(), null); +// } +// } return itemStack; } - public static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, int javaId, int count, CompoundTag tag) { + public static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, int javaId, int count, DataComponents components) { ItemMapping bedrockItem = session.getItemMappings().getMapping(javaId); if (bedrockItem == ItemMapping.AIR) { session.getGeyser().getLogger().debug("ItemMapping returned air: " + javaId); return ItemData.builder(); } - return translateToBedrock(session, Registries.JAVA_ITEMS.get().get(javaId), bedrockItem, count, tag); + return translateToBedrock(session, Registries.JAVA_ITEMS.get().get(javaId), bedrockItem, count, components); } @NonNull @@ -133,32 +133,35 @@ public final class ItemTranslator { return ItemData.AIR; } // Java item needs to be loaded separately. The mapping for tipped arrow would - return translateToBedrock(session, Registries.JAVA_ITEMS.get().get(stack.getId()), bedrockItem, stack.getAmount(), stack.getNbt()) + return translateToBedrock(session, Registries.JAVA_ITEMS.get().get(stack.getId()), bedrockItem, stack.getAmount(), stack.getDataComponents()) .build(); } - private static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, Item javaItem, ItemMapping bedrockItem, int count, DataComponentPatch components) { - NbtMapBuilder builder = NbtMap.builder(); + private static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, Item javaItem, ItemMapping bedrockItem, int count, DataComponents components) { + BedrockItemBuilder nbtBuilder = new BedrockItemBuilder(); if (components != null) { - javaItem.translateComponentsToBedrock(session, components, builder); + javaItem.translateComponentsToBedrock(session, components, nbtBuilder.getOrCreateNbt()); } - translateDisplayProperties(session, components, bedrockItem); + String customName = getCustomName(session, components, bedrockItem); + if (customName != null) { + nbtBuilder.setCustomName(customName); + } if (components != null) { ItemAttributeModifiers attributeModifiers = components.get(DataComponentType.ATTRIBUTE_MODIFIERS); if (attributeModifiers != null && attributeModifiers.isShowInTooltip()) { // only add if attribute modifiers do not indicate to hide them - addAttributeLore(attributeModifiers, builder, session.locale()); + addAttributeLore(attributeModifiers, nbtBuilder, session.locale()); } } if (session.isAdvancedTooltips()) { - nbt = addAdvancedTooltips(nbt, javaItem, session.locale()); + addAdvancedTooltips(components, nbtBuilder, javaItem, session.locale()); } - ItemStack itemStack = new ItemStack(javaItem.javaId(), count, nbt); + ItemStack itemStack = new ItemStack(javaItem.javaId(), count, components); ItemData.Builder builder = javaItem.translateToBedrock(itemStack, bedrockItem, session.getItemMappings()); if (bedrockItem.isBlock()) { @@ -172,10 +175,10 @@ public final class ItemTranslator { } if (bedrockItem.getJavaItem().equals(Items.PLAYER_HEAD)) { - translatePlayerHead(session, nbt, builder); + translatePlayerHead(session, components, builder); } - translateCustomItem(nbt, builder, bedrockItem); + translateCustomItem(components, builder, bedrockItem); if (components != null) { // Translate the canDestroy and canPlaceOn Java NBT @@ -198,21 +201,12 @@ public final class ItemTranslator { * Bedrock Edition does not see attribute modifiers like Java Edition does, * so we add them as lore instead. * - * @param nbt the NBT of the ItemStack + * @param modifiers the attribute modifiers of the ItemStack * @param language the locale of the player */ - private static void addAttributeLore(ItemAttributeModifiers modifiers, NbtMapBuilder builder, String language) { - CompoundTag displayTag = builder.get("display"); - if (displayTag == null) { - displayTag = new CompoundTag("display"); - } - ListTag lore = displayTag.get("Lore"); - if (lore == null) { - lore = new ListTag("Lore"); - } - + private static void addAttributeLore(ItemAttributeModifiers modifiers, BedrockItemBuilder builder, String language) { // maps each slot to the modifiers applied when in such slot - Map> slotsToModifiers = new HashMap<>(); + Map> slotsToModifiers = new HashMap<>(); for (ItemAttributeModifiers.Entry entry : modifiers.getModifiers()) { // convert the modifier tag to a lore entry String loreEntry = attributeToLore(entry.getModifier(), language); @@ -220,23 +214,22 @@ public final class ItemTranslator { continue; // invalid or failed } - StringTag loreTag = new StringTag("", loreEntry); ItemAttributeModifiers.EquipmentSlotGroup slotGroup = entry.getSlot(); if (slotGroup == ItemAttributeModifiers.EquipmentSlotGroup.ANY) { // modifier applies to all slots implicitly - for (String slot : ALL_SLOTS) { - slotsToModifiers.computeIfAbsent(slot, s -> new ArrayList<>()).add(loreTag); + for (String slot : ALL_SLOTS) { // TODO SOMEONE LOOK HERE PLZ + //slotsToModifiers.computeIfAbsent(slot, s -> new ArrayList<>()).add(loreEntry); } } else { // modifier applies to only the specified slot - slotsToModifiers.computeIfAbsent(slotGroup, s -> new ArrayList<>()).add(loreTag); + slotsToModifiers.computeIfAbsent(slotGroup, s -> new ArrayList<>()).add(loreEntry); } } // iterate through the small array, not the map, so that ordering matches Java Edition for (String slot : ALL_SLOTS) { - List modifiers = slotsToModifiers.get(slot); - if (modifiers == null || modifiers.isEmpty()) { + List modifierStrings = slotsToModifiers.get(slot); + if (modifierStrings == null || modifierStrings.isEmpty()) { continue; } @@ -246,16 +239,13 @@ public final class ItemTranslator { .color(NamedTextColor.GRAY) .append(Component.newline(), Component.translatable("item.modifiers." + slot)) .build(); - lore.add(new StringTag("", MessageTranslator.convertMessage(slotComponent, language))); + builder.getOrCreateLore().add(MessageTranslator.convertMessage(slotComponent, language)); // Then list all the modifiers when used in this slot - for (StringTag modifier : modifiers) { - lore.add(modifier); + for (String modifier : modifierStrings) { + builder.getOrCreateLore().add(modifier); } } - - displayTag.put(lore); - nbt.put(displayTag); } @Nullable @@ -294,29 +284,13 @@ public final class ItemTranslator { return MessageTranslator.convertMessage(attributeComponent, language); } - private static CompoundTag addAdvancedTooltips(CompoundTag nbt, Item item, String language) { - CompoundTag newNbt = nbt; - if (newNbt == null) { - newNbt = new CompoundTag("nbt"); - CompoundTag display = new CompoundTag("display"); - display.put(new ListTag("Lore")); - newNbt.put(display); - } - CompoundTag compoundTag = newNbt.get("display"); - if (compoundTag == null) { - compoundTag = new CompoundTag("display"); - } - ListTag listTag = compoundTag.get("Lore"); - - if (listTag == null) { - listTag = new ListTag("Lore"); - } + private static void addAdvancedTooltips(DataComponents components, BedrockItemBuilder builder, Item item, String language) { int maxDurability = item.maxDamage(); if (maxDurability != 0) { - Tag durabilityTag = newNbt.get("Damage"); - if (durabilityTag instanceof IntTag) { - int durability = maxDurability - ((IntTag) durabilityTag).getValue(); + Integer durabilityComponent = components.get(DataComponentType.DAMAGE); + if (durabilityComponent != null) { + int durability = maxDurability - durabilityComponent; if (durability != maxDurability) { Component component = Component.text() .resetStyle() @@ -325,24 +299,21 @@ public final class ItemTranslator { Component.text(durability), Component.text(maxDurability))) .build(); - listTag.add(new StringTag("", MessageTranslator.convertMessage(component, language))); + builder.getOrCreateLore().add(MessageTranslator.convertMessage(component, language)); } } } - listTag.add(new StringTag("", ChatColor.RESET + ChatColor.DARK_GRAY + item.javaIdentifier())); - if (nbt != null) { + builder.getOrCreateLore().add(ChatColor.RESET + ChatColor.DARK_GRAY + item.javaIdentifier()); + if (components != null) { Component component = Component.text() .resetStyle() .color(NamedTextColor.DARK_GRAY) - .append(Component.translatable("item.nbt_tags", - Component.text(nbt.size()))) + .append(Component.translatable("item.nbt_tags", // TODO + Component.text(components.getDataComponents().size()))) .build(); - listTag.add(new StringTag("", MessageTranslator.convertMessage(component, language))); + builder.getOrCreateLore().add(MessageTranslator.convertMessage(component, language)); } - compoundTag.put(listTag); - newNbt.put(compoundTag); - return newNbt; } /** @@ -396,13 +367,13 @@ public final class ItemTranslator { } if (mapping.getJavaItem().equals(Items.PLAYER_HEAD)) { - CustomSkull customSkull = getCustomSkull(session, itemStack.getNbt()); + CustomSkull customSkull = getCustomSkull(session, itemStack.getComponents()); if (customSkull != null) { itemDefinition = session.getItemMappings().getCustomBlockItemDefinitions().get(customSkull.getCustomBlockData()); } } - ItemDefinition definition = CustomItemTranslator.getCustomItem(itemStack, mapping); + ItemDefinition definition = CustomItemTranslator.getCustomItem(itemStack.getComponents(), mapping); if (definition == null) { // No custom item return itemDefinition; @@ -533,65 +504,45 @@ public final class ItemTranslator { /** * Translates the display name of the item * @param session the Bedrock client's session - * @param tag the tag to translate + * @param components the components to translate * @param mapping the item entry, in case it requires translation - * - * @return the new tag to use, should the current one be null */ - public static CompoundTag translateDisplayProperties(GeyserSession session, CompoundTag tag, ItemMapping mapping) { - return translateDisplayProperties(session, tag, mapping, 'f'); + public static String getCustomName(GeyserSession session, DataComponents components, ItemMapping mapping) { + return getCustomName(session, components, mapping, 'f'); } /** * @param translationColor if this item is not available on Java, the color that the new name should be. * Normally, this should just be white, but for shulker boxes this should be gray. */ - public static CompoundTag translateDisplayProperties(GeyserSession session, CompoundTag tag, ItemMapping mapping, char translationColor) { - boolean hasCustomName = false; - if (tag != null) { - if (tag.get("display") instanceof CompoundTag display && display.get("Name") instanceof StringTag tagName) { - String name = tagName.getValue(); - - // Get the translated name and prefix it with a reset char - name = MessageTranslator.convertMessageLenient(name, session.locale()); - - // Add the new name tag - display.put(new StringTag("Name", name)); - // Indicate that a custom name is present - hasCustomName = true; - - // Add to the new root tag - tag.put(display); + public static String getCustomName(GeyserSession session, DataComponents components, ItemMapping mapping, char translationColor) { + if (components != null) { + // ItemStack#getHoverName as of 1.20.5 + Component customName = components.get(DataComponentType.CUSTOM_NAME); + if (customName == null) { + customName = components.get(DataComponentType.ITEM_NAME); + } + if (customName != null) { + // Get the translated name and prefix it with a reset char TODO test + return MessageTranslator.convertMessage(customName, session.locale()); } } - if (!hasCustomName && mapping.hasTranslation()) { + if (mapping.hasTranslation()) { // No custom name, but we need to localize the item's name - if (tag == null) { - tag = new CompoundTag(""); - } - CompoundTag display; - if (tag.get("display") instanceof CompoundTag oldDisplay) { - display = oldDisplay; - } else { - display = new CompoundTag("display"); - // Add to the new root tag - tag.put(display); - } - String translationKey = mapping.getTranslationString(); // Reset formatting since Bedrock defaults to italics - display.put(new StringTag("Name", ChatColor.RESET + ChatColor.ESCAPE + translationColor + MinecraftLocale.getLocaleString(translationKey, session.locale()))); + return ChatColor.RESET + ChatColor.ESCAPE + translationColor + MinecraftLocale.getLocaleString(translationKey, session.locale()); } - - return tag; + // No custom name + return null; } /** * Translates the custom model data of an item */ - public static void translateCustomItem(CompoundTag nbt, ItemData.Builder builder, ItemMapping mapping) { - ItemDefinition definition = CustomItemTranslator.getCustomItem(nbt, mapping); + public static void translateCustomItem(DataComponents components, ItemData.Builder builder, ItemMapping mapping) { + ItemDefinition definition = CustomItemTranslator.getCustomItem(components, mapping); if (definition != null) { builder.definition(definition); builder.blockDefinition(null); @@ -608,8 +559,12 @@ public final class ItemTranslator { builder.blockDefinition(blockDefinition); } - private static @Nullable CustomSkull getCustomSkull(GeyserSession session, CompoundTag nbt) { - if (nbt != null && nbt.contains("SkullOwner")) { + private static @Nullable CustomSkull getCustomSkull(GeyserSession session, DataComponents components) { + if (components == null) { + return null; + } + GameProfile profile = components.get(DataComponentType.PROFILE); + if (profile != null) { if (!(nbt.get("SkullOwner") instanceof CompoundTag skullOwner)) { // It's a username give up d: return null; @@ -626,8 +581,8 @@ public final class ItemTranslator { return null; } - private static void translatePlayerHead(GeyserSession session, CompoundTag nbt, ItemData.Builder builder) { - CustomSkull customSkull = getCustomSkull(session, nbt); + private static void translatePlayerHead(GeyserSession session, DataComponents components, ItemData.Builder builder) { + CustomSkull customSkull = getCustomSkull(session, components); if (customSkull != null) { CustomBlockData customBlockData = customSkull.getCustomBlockData(); ItemDefinition itemDefinition = session.getItemMappings().getCustomBlockItemDefinitions().get(customBlockData); @@ -636,18 +591,4 @@ public final class ItemTranslator { builder.blockDefinition(blockDefinition); } } - - /** - * Checks if the NBT of a Java item stack has the given hide flag. - * - * @param hideFlags the "HideFlags", which may not be null - * @param flagMask the flag to check for, as a bit mask - * @return true if the flag is present, false if not or if the tag value is not a number - */ - private static boolean hasFlagPresent(Tag hideFlags, byte flagMask) { - if (hideFlags.getValue() instanceof Number flags) { - return (flags.byteValue() & flagMask) == flagMask; - } - return false; - } } From 909139326d3324eb6637c23f60a0f4516f09149c Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 20 Apr 2024 14:55:30 -0400 Subject: [PATCH 071/272] Keep chugging away --- .../geyser/item/DyeableLeatherItem.java | 15 +++--- .../geysermc/geyser/item/type/ArmorItem.java | 25 ++++++---- .../geyser/item/type/AxolotlBucketItem.java | 14 +++--- .../geysermc/geyser/item/type/BannerItem.java | 37 +++++++------- .../geysermc/geyser/item/type/ChestItem.java | 16 ++----- .../geyser/item/type/CompassItem.java | 34 +++++++------ .../geyser/item/type/CrossbowItem.java | 35 +++++++------- .../geyser/item/type/DecoratedPotItem.java | 20 ++++---- .../geyser/item/type/DyeableArmorItem.java | 6 +-- .../item/type/DyeableHorseArmorItem.java | 6 +-- .../geyser/item/type/EnchantedBookItem.java | 4 +- .../geyser/item/type/FilledMapItem.java | 18 +++---- .../geyser/item/type/FireworkRocketItem.java | 48 +++++++++---------- .../geyser/item/type/FireworkStarItem.java | 4 +- .../geyser/item/type/FishingRodItem.java | 4 +- .../org/geysermc/geyser/item/type/Item.java | 18 ++----- .../geysermc/geyser/item/type/MapItem.java | 4 +- .../geyser/item/type/PlayerHeadItem.java | 4 +- .../geysermc/geyser/item/type/ShieldItem.java | 4 +- .../geyser/item/type/ShulkerBoxItem.java | 16 +++---- .../item/type/TropicalFishBucketItem.java | 4 +- .../geyser/item/type/WritableBookItem.java | 4 +- .../geyser/item/type/WrittenBookItem.java | 4 +- .../geyser/session/cache/LodestoneCache.java | 3 +- .../translator/item/BedrockItemBuilder.java | 35 ++++++++++++++ .../translator/item/ItemTranslator.java | 2 +- 26 files changed, 200 insertions(+), 184 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java b/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java index e0eec767f..214b9d78c 100644 --- a/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java @@ -25,20 +25,21 @@ package org.geysermc.geyser.item; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; +import com.github.steveice10.mc.protocol.data.game.item.component.DyedItemColor; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; public interface DyeableLeatherItem { - static void translateNbtToBedrock(CompoundTag tag) { - CompoundTag displayTag = tag.get("display"); - if (displayTag == null) { + static void translateComponentsToBedrock(DataComponents components, BedrockItemBuilder builder) { + DyedItemColor dyedItemColor = components.get(DataComponentType.DYED_COLOR); + if (dyedItemColor == null) { return; } - IntTag color = displayTag.remove("color"); - if (color != null) { - tag.put(new IntTag("customColor", color.getValue())); - } + builder.putInt("customColor", dyedItemColor.getRgb()); } static void translateNbtToJava(CompoundTag tag) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java index eb5233b88..ba7f05205 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java @@ -25,14 +25,18 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.ArmorTrim; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.item.ArmorMaterial; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; public class ArmorItem extends Item { private final ArmorMaterial material; @@ -43,23 +47,26 @@ public class ArmorItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - if (tag.get("Trim") instanceof CompoundTag trim) { - StringTag material = trim.remove("material"); - StringTag pattern = trim.remove("pattern"); + ArmorTrim trim = components.get(DataComponentType.TRIM); + if (trim != null) { + // TODO material IDs + String material = trim.getMaterial().getAssetName(); + String pattern = trim.getPattern().getAssetId(); // discard custom trim patterns/materials to prevent visual glitches on bedrock - if (!material.getValue().startsWith("minecraft:") - || !pattern.getValue().startsWith("minecraft:")) { - tag.remove("Trim"); + if (!material.startsWith("minecraft:") + || !pattern.startsWith("minecraft:")) { return; } + NbtMapBuilder trimBuilder = NbtMap.builder(); // bedrock has an uppercase first letter key, and the value is not namespaced - trim.put(new StringTag("Material", stripNamespace(material.getValue()))); - trim.put(new StringTag("Pattern", stripNamespace(pattern.getValue()))); + trimBuilder.put("Material", stripNamespace(material)); + trimBuilder.put("Pattern", stripNamespace(pattern)); + builder.putCompound("Trim", trimBuilder.build()); } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java index d0aa1e901..99f649e87 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java @@ -26,12 +26,10 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.opennbt.tag.builtin.ByteTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.MinecraftLocale; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; public class AxolotlBucketItem extends Item { public AxolotlBucketItem(String javaIdentifier, Builder builder) { @@ -39,15 +37,15 @@ public class AxolotlBucketItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); // Bedrock Edition displays the properties of the axolotl. Java does not. // To work around this, set the custom name to the Axolotl translation and it's displayed correctly - tag.put(new ByteTag("AppendCustomName", (byte) 1)); - tag.put(new StringTag("CustomName", MinecraftLocale.getLocaleString("entity.minecraft.axolotl", session.locale()))); + builder.putByte("AppendCustomName", 1); + builder.putString("CustomName", MinecraftLocale.getLocaleString("entity.minecraft.axolotl", session.locale())); // Boilerplate required so the nametag does not appear as "Bucket of " - tag.put(new StringTag("ColorID", "")); - tag.put(new StringTag("BodyID", "")); + builder.putString("ColorID", ""); + builder.putString("BodyID", ""); } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index 2a8ca9f15..549809391 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -25,6 +25,8 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.BannerPatternLayer; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; @@ -33,16 +35,14 @@ import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtList; import org.cloudburstmc.nbt.NbtMap; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; import java.util.ArrayList; import java.util.List; -import static org.geysermc.erosion.util.BannerUtils.getJavaPatternTag; - public class BannerItem extends BlockItem { /** * Holds what a Java ominous banner pattern looks like. @@ -51,19 +51,20 @@ public class BannerItem extends BlockItem { * ominous banners that we set instead. This variable is used to detect Java ominous banner patterns, and apply * the correct ominous banner pattern if Bedrock pulls the item from creative. */ - public static final ListTag OMINOUS_BANNER_PATTERN; + public static final List OMINOUS_BANNER_PATTERN; static { - OMINOUS_BANNER_PATTERN = new ListTag("Patterns"); // Construct what an ominous banner is supposed to look like - OMINOUS_BANNER_PATTERN.add(getJavaPatternTag("mr", 9)); - OMINOUS_BANNER_PATTERN.add(getJavaPatternTag("bs", 8)); - OMINOUS_BANNER_PATTERN.add(getJavaPatternTag("cs", 7)); - OMINOUS_BANNER_PATTERN.add(getJavaPatternTag("bo", 8)); - OMINOUS_BANNER_PATTERN.add(getJavaPatternTag("ms", 15)); - OMINOUS_BANNER_PATTERN.add(getJavaPatternTag("hh", 8)); - OMINOUS_BANNER_PATTERN.add(getJavaPatternTag("mc", 8)); - OMINOUS_BANNER_PATTERN.add(getJavaPatternTag("bo", 15)); + OMINOUS_BANNER_PATTERN = List.of( + new BannerPatternLayer("mr", 9), + new BannerPatternLayer("bs", 8), + new BannerPatternLayer("cs", 7), + new BannerPatternLayer("bo", 8), + new BannerPatternLayer("ms", 15), + new BannerPatternLayer("hh", 8), + new BannerPatternLayer("mc", 8), + new BannerPatternLayer("bo", 15) + ); } /** @@ -102,7 +103,7 @@ public class BannerItem extends BlockItem { * @return The Java edition format pattern nbt */ public static CompoundTag getJavaBannerPattern(NbtMap pattern) { - return getJavaPatternTag(pattern.getString("Pattern"), 15 - pattern.getInt("Color")); + return new BannerPatternLayer(pattern.getString("Pattern"), 15 - pattern.getInt("Color")); } /** @@ -122,14 +123,14 @@ public class BannerItem extends BlockItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - CompoundTag blockEntityTag = tag.remove("BlockEntityTag"); - if (blockEntityTag != null && blockEntityTag.get("Patterns") instanceof ListTag patterns) { + List patterns = components.get(DataComponentType.BANNER_PATTERNS); + if (patterns != null) { if (patterns.equals(OMINOUS_BANNER_PATTERN)) { // Remove the current patterns and set the ominous banner type - tag.put(new IntTag("Type", 1)); + builder.putInt("Type", 1); } else { invertBannerColors(patterns); tag.put(patterns); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java index 8644ec8be..1f6ac6964 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java @@ -27,9 +27,10 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; +@Deprecated public class ChestItem extends BlockItem { public ChestItem(String javaIdentifier, Builder builder) { @@ -37,18 +38,7 @@ public class ChestItem extends BlockItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - - // Strip the BlockEntityTag from the chests contents - // sent to the client. The client does not parse this - // or use it for anything, as this tag is fully - // server-side, so we remove it to reduce bandwidth and - // solve potential issues with very large tags. - - // There was a problem in the past where this would strip - // NBT data in creative mode, however with the new server - // authoritative inventories, this is no longer a concern. - tag.remove("BlockEntityTag"); } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java b/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java index 605d19852..8d48d1307 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java @@ -26,17 +26,16 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.opennbt.tag.builtin.ByteTag; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.IntTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import com.github.steveice10.mc.protocol.data.game.item.component.LodestoneTracker; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; public class CompassItem extends Item { public CompassItem(String javaIdentifier, Builder builder) { @@ -45,36 +44,35 @@ public class CompassItem extends Item { @Override public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) { - if (isLodestoneCompass(itemStack.getNbt())) { + if (isLodestoneCompass(itemStack.getDataComponents())) { return super.translateToBedrock(itemStack, mappings.getLodestoneCompass(), mappings); } return super.translateToBedrock(itemStack, mapping, mappings); } @Override - public ItemMapping toBedrockDefinition(CompoundTag nbt, ItemMappings mappings) { - if (isLodestoneCompass(nbt)) { + public ItemMapping toBedrockDefinition(DataComponents components, ItemMappings mappings) { + if (isLodestoneCompass(components)) { return mappings.getLodestoneCompass(); } - return super.toBedrockDefinition(nbt, mappings); + return super.toBedrockDefinition(components, mappings); } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - Tag lodestoneTag = tag.get("LodestoneTracked"); - if (lodestoneTag instanceof ByteTag) { - int trackId = session.getLodestoneCache().store(tag); + LodestoneTracker tracker = components.get(DataComponentType.LODESTONE_TRACKER); + if (tracker != null) { + int trackId = session.getLodestoneCache().store(tracker); // Set the bedrock tracking id - will return 0 if invalid - tag.put(new IntTag("trackingHandle", trackId)); + builder.putInt("trackingHandle", trackId); } } - private boolean isLodestoneCompass(CompoundTag nbt) { - if (nbt != null) { - Tag lodestoneTag = nbt.get("LodestoneTracked"); - return lodestoneTag instanceof ByteTag; + private boolean isLodestoneCompass(@Nullable DataComponents components) { + if (components != null) { + return components.getDataComponents().containsKey(DataComponentType.LODESTONE_TRACKER); } return false; } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java index c38e2f2ba..5b92ba303 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java @@ -26,44 +26,41 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.opennbt.tag.builtin.*; +import com.github.steveice10.opennbt.tag.builtin.ByteTag; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.ListTag; +import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.ItemTranslator; +import java.util.List; + public class CrossbowItem extends Item { public CrossbowItem(String javaIdentifier, Builder builder) { super(javaIdentifier, builder); } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - ListTag chargedProjectiles = tag.get("ChargedProjectiles"); - if (chargedProjectiles != null) { - if (!chargedProjectiles.getValue().isEmpty()) { - CompoundTag javaProjectileAsNbt = (CompoundTag) chargedProjectiles.getValue().get(0); + List chargedProjectiles = components.get(DataComponentType.CHARGED_PROJECTILES); + if (chargedProjectiles != null && !chargedProjectiles.isEmpty()) { + ItemStack javaProjectile = chargedProjectiles.get(0); - ItemMapping projectileMapping = session.getItemMappings().getMapping((String) javaProjectileAsNbt.get("id").getValue()); - if (projectileMapping == null) return; - @Nullable CompoundTag projectileTag = javaProjectileAsNbt.get("tag"); - ItemStack itemStack = new ItemStack(projectileMapping.getJavaItem().javaId(), (byte) javaProjectileAsNbt.get("Count").getValue(), projectileTag); - ItemData itemData = ItemTranslator.translateToBedrock(session, itemStack); + ItemMapping projectileMapping = session.getItemMappings().getMapping(javaProjectile.getId()); + ItemData itemData = ItemTranslator.translateToBedrock(session, javaProjectile); - CompoundTag newProjectile = new CompoundTag("chargedItem"); - newProjectile.put(new ByteTag("Count", (byte) itemData.getCount())); - newProjectile.put(new StringTag("Name", projectileMapping.getBedrockIdentifier())); + NbtMapBuilder newProjectile = BedrockItemBuilder.createItemNbt(projectileMapping, itemData.getCount(), itemData.getDamage()); - newProjectile.put(new ShortTag("Damage", (short) itemData.getDamage())); - - tag.put(newProjectile); - } + builder.putCompound("chargedItem", newProjectile.build()); } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java index 74cabc3d9..792ec0f0b 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java @@ -25,12 +25,11 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; public class DecoratedPotItem extends BlockItem { @@ -39,14 +38,15 @@ public class DecoratedPotItem extends BlockItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) { - if (blockEntityTag.remove("sherds") instanceof ListTag sherds) { - // bedrock wants it on the root level - tag.put(sherds); - } - } + components.get(DataComponentType.POT_DECORATIONS); // TODO +// if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) { +// if (blockEntityTag.remove("sherds") instanceof ListTag sherds) { +// // bedrock wants it on the root level +// tag.put(sherds); +// } +// } } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java index fbe0222bc..117e70b9a 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java @@ -28,11 +28,11 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.item.ArmorMaterial; import org.geysermc.geyser.item.DyeableLeatherItem; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; public class DyeableArmorItem extends ArmorItem implements DyeableLeatherItem { public DyeableArmorItem(String javaIdentifier, ArmorMaterial material, Builder builder) { @@ -40,10 +40,10 @@ public class DyeableArmorItem extends ArmorItem implements DyeableLeatherItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - DyeableLeatherItem.translateNbtToBedrock(tag); + DyeableLeatherItem.translateComponentsToBedrock(components, builder); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java index 09878e652..cb6dd869b 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java @@ -28,10 +28,10 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.item.DyeableLeatherItem; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; public class DyeableHorseArmorItem extends Item implements DyeableLeatherItem { public DyeableHorseArmorItem(String javaIdentifier, Builder builder) { @@ -39,10 +39,10 @@ public class DyeableHorseArmorItem extends Item implements DyeableLeatherItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - DyeableLeatherItem.translateNbtToBedrock(tag); + DyeableLeatherItem.translateComponentsToBedrock(components, builder); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java index d3aa72cbc..3851813ae 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java @@ -30,8 +30,8 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; import java.util.ArrayList; import java.util.List; @@ -42,7 +42,7 @@ public class EnchantedBookItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); List newTags = new ArrayList<>(); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java index 8125ce101..78a175f8d 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java @@ -26,8 +26,8 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.registry.type.ItemMapping; @@ -41,16 +41,16 @@ public class FilledMapItem extends MapItem { @Override public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) { ItemData.Builder builder = super.translateToBedrock(itemStack, mapping, mappings); - CompoundTag nbt = itemStack.getNbt(); - if (nbt == null) { + DataComponents components = itemStack.getDataComponents(); + if (components == null) { // This is a fallback for maps with no nbt (Change added back in June 2020; is it needed in 2023?) return builder.tag(NbtMap.builder().putInt("map", 0).build()); - } else if (nbt.get("display") instanceof CompoundTag display) { - // Note: damage 5 treasure map, 6 ??? - Tag mapColor = display.get("MapColor"); - if (mapColor != null && mapColor.getValue() instanceof Number color) { + } else { + Integer mapColor = components.get(DataComponentType.MAP_COLOR); + if (mapColor != null) { + // Note: damage 5 treasure map, 6 ??? // Java Edition allows any color; Bedrock only allows some. So let's take what colors we can get - switch (color.intValue()) { + switch (mapColor) { case 3830373 -> builder.damage(3); // Ocean Monument case 5393476 -> builder.damage(4); // Woodland explorer } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java index b44dc08eb..d688e59f6 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java @@ -25,44 +25,47 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; +import com.github.steveice10.mc.protocol.data.game.item.component.Fireworks; import com.github.steveice10.opennbt.tag.builtin.*; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.FireworkColor; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.util.MathUtils; +import java.util.ArrayList; +import java.util.List; + public class FireworkRocketItem extends Item { public FireworkRocketItem(String javaIdentifier, Builder builder) { super(javaIdentifier, builder); } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - CompoundTag fireworks = tag.get("Fireworks"); + Fireworks fireworks = components.get(DataComponentType.FIREWORKS); if (fireworks == null) { return; } + NbtMapBuilder fireworksNbt = NbtMap.builder(); + fireworksNbt.putByte("Flight", (byte) fireworks.getFlightDuration()); - if (fireworks.get("Flight") != null) { - fireworks.put(new ByteTag("Flight", MathUtils.getNbtByte(fireworks.get("Flight").getValue()))); - } - - ListTag explosions = fireworks.get("Explosions"); - if (explosions == null) { + List explosions = fireworks.getExplosions(); + if (explosions.isEmpty()) { return; } - for (Tag effect : explosions.getValue()) { - CompoundTag effectData = (CompoundTag) effect; - CompoundTag newEffectData = translateExplosionToBedrock(effectData, ""); - - explosions.remove(effectData); - explosions.add(newEffectData); + List explosionNbt = new ArrayList<>(); + for (Fireworks.FireworkExplosion explosion : explosions) { + explosionNbt.add(translateExplosionToBedrock(explosion, "")); } + } @Override @@ -70,13 +73,15 @@ public class FireworkRocketItem extends Item { super.translateNbtToJava(tag, mapping); } - static CompoundTag translateExplosionToBedrock(CompoundTag explosion, String newName) { - CompoundTag newExplosionData = new CompoundTag(newName); + static NbtMap translateExplosionToBedrock(Fireworks.FireworkExplosion explosion, String newName) { + NbtMapBuilder newExplosionData = NbtMap.builder(); if (explosion.get("Type") != null) { newExplosionData.put(new ByteTag("FireworkType", MathUtils.getNbtByte(explosion.get("Type").getValue()))); } + //newExplosionData.putByte("FireworkType", explosion.get) //TODO??? + // TODO do we need length checks if (explosion.get("Colors") != null) { int[] oldColors = (int[]) explosion.get("Colors").getValue(); byte[] colors = new byte[oldColors.length]; @@ -101,15 +106,10 @@ public class FireworkRocketItem extends Item { newExplosionData.put(new ByteArrayTag("FireworkFade", colors)); } - if (explosion.get("Trail") != null) { - newExplosionData.put(new ByteTag("FireworkTrail", MathUtils.getNbtByte(explosion.get("Trail").getValue()))); - } + newExplosionData.putBoolean("FireworkTrail", explosion.isHasTrail()); + newExplosionData.putBoolean("FireworkFlicker", explosion.isHasTwinkle()); // TODO verify - if (explosion.get("Flicker") != null) { - newExplosionData.put(new ByteTag("FireworkFlicker", MathUtils.getNbtByte(explosion.get("Flicker").getValue()))); - } - - return newExplosionData; + return newExplosionData.build(); } static CompoundTag translateExplosionToJava(CompoundTag explosion, String newName) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java index 80a32fc44..4ae9c8b13 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java @@ -31,9 +31,9 @@ import com.github.steveice10.opennbt.tag.builtin.IntArrayTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; public class FireworkStarItem extends Item { public FireworkStarItem(String javaIdentifier, Builder builder) { @@ -41,7 +41,7 @@ public class FireworkStarItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); Tag explosion = tag.remove("Explosion"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java index 0e1a4cc0e..4538689da 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java @@ -29,8 +29,8 @@ import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; public class FishingRodItem extends Item { public FishingRodItem(String javaIdentifier, Builder builder) { @@ -38,7 +38,7 @@ public class FishingRodItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); // Fix damage inconsistency diff --git a/core/src/main/java/org/geysermc/geyser/item/type/Item.java b/core/src/main/java/org/geysermc/geyser/item/type/Item.java index 3ecf3be1b..decc60da8 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/Item.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/Item.java @@ -34,10 +34,8 @@ import com.github.steveice10.opennbt.tag.builtin.*; import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; -import org.cloudburstmc.nbt.NbtList; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; -import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.item.Enchantment; @@ -46,6 +44,7 @@ import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.text.MinecraftLocale; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.util.InventoryUtils; @@ -120,29 +119,20 @@ public class Item { return new ItemStack(javaId, itemData.getCount(), ItemTranslator.translateToJavaNBT("", itemData.getTag())); } - public ItemMapping toBedrockDefinition(CompoundTag nbt, ItemMappings mappings) { + public ItemMapping toBedrockDefinition(DataComponents components, ItemMappings mappings) { return mappings.getMapping(javaId); } /** * Takes components from Java Edition and map them into Bedrock. */ - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { -// // Basing off of ItemStack#getHoverName as of 1.20.5. VERIFY?? -// Component customName = components.get(DataComponentType.CUSTOM_NAME); -// if (customName == null) { -// customName = components.get(DataComponentType.ITEM_NAME); -// } -// if (customName != null) { -// -// } + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { List loreComponents = components.get(DataComponentType.LORE); if (loreComponents != null) { - List lore = new ArrayList<>(); + List lore = builder.getOrCreateLore(); for (Component loreComponent : loreComponents) { lore.add(MessageTranslator.convertMessage(loreComponent, session.locale())); } - builder.putList("Lore", NbtType.STRING, lore); } List newTags = new ArrayList<>(); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java b/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java index 64e505800..b015862c5 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java @@ -28,9 +28,9 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.*; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; public class MapItem extends Item { public MapItem(String javaIdentifier, Builder builder) { @@ -38,7 +38,7 @@ public class MapItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); Tag mapId = tag.remove("map"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java index 6ebc728cb..dae444775 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java @@ -30,10 +30,10 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.text.MinecraftLocale; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.text.MessageTranslator; public class PlayerHeadItem extends Item { @@ -42,7 +42,7 @@ public class PlayerHeadItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); CompoundTag displayTag; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java index b3f9f57e3..30b50b436 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java @@ -31,9 +31,9 @@ import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.item.components.ToolTier; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; public class ShieldItem extends Item { public ShieldItem(String javaIdentifier, Builder builder) { @@ -41,7 +41,7 @@ public class ShieldItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java index 3d5fa2444..395563fe3 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java @@ -36,6 +36,7 @@ import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.ItemTranslator; import java.util.ArrayList; @@ -47,7 +48,7 @@ public class ShulkerBoxItem extends BlockItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); List contents = components.get(DataComponentType.CONTAINER); @@ -61,15 +62,12 @@ public class ShulkerBoxItem extends BlockItem { if (item.getId() == Items.AIR_ID) { continue; } - NbtMapBuilder boxItemNbt = NbtMap.builder(); // Final item tag to add to the list - boxItemNbt.putByte("Slot", (byte) slot); - boxItemNbt.putByte("WasPickedUp", (byte) 0); // ??? - ItemMapping boxMapping = session.getItemMappings().getMapping(item.getId()); - boxItemNbt.putString("Name", boxMapping.getBedrockIdentifier()); - boxItemNbt.putShort("Damage", (short) boxMapping.getBedrockData()); - boxItemNbt.putByte("Count", (byte) item.getAmount()); + NbtMapBuilder boxItemNbt = BedrockItemBuilder.createItemNbt(boxMapping, item.getAmount(), boxMapping.getBedrockData()); // Final item tag to add to the list + boxItemNbt.putByte("Slot", (byte) slot); + boxItemNbt.putByte("WasPickedUp", (byte) 0); // ??? TODO might not be needed + // Only the display name is what we have interest in, so just translate that if relevant DataComponents boxComponents = item.getDataComponents(); if (boxComponents != null) { @@ -85,7 +83,7 @@ public class ShulkerBoxItem extends BlockItem { itemsList.add(boxItemNbt.build()); } - builder.putList("Items", NbtType.COMPOUND, itemsList); + builder.getOrCreateNbt().putList("Items", NbtType.COMPOUND, itemsList); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java index 2ce0dd071..3ece87745 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java @@ -32,10 +32,10 @@ import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.TextDecoration; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.entity.type.living.animal.TropicalFishEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.MinecraftLocale; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.text.MessageTranslator; import java.util.ArrayList; @@ -49,7 +49,7 @@ public class TropicalFishBucketItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); // Prevent name from appearing as "Bucket of" diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java index 46b9b80ce..68cdf99d4 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java @@ -31,9 +31,9 @@ import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.text.MessageTranslator; import java.util.ArrayList; @@ -45,7 +45,7 @@ public class WritableBookItem extends Item { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); ListTag pagesTag = tag.remove("pages"); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java index 46eceaa86..ae6b81f6e 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java @@ -33,8 +33,8 @@ import com.github.steveice10.opennbt.tag.builtin.Tag; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.text.MessageTranslator; import java.util.List; @@ -50,7 +50,7 @@ public class WrittenBookItem extends WritableBookItem { } @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) { + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { boolean isValid = isValidWrittenBook(tag); if (!isValid) { tag.remove("pages"); diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java index f118195b9..4bd2244ab 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.session.cache; +import com.github.steveice10.mc.protocol.data.game.item.component.LodestoneTracker; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; @@ -88,7 +89,7 @@ public final class LodestoneCache { this.activeLodestones.put(itemStack, new LodestonePos(id++, x, y, z, dim)); } - public int store(CompoundTag tag) { + public int store(LodestoneTracker tracker) { CompoundTag lodestonePos = tag.get("LodestonePos"); if (lodestonePos == null) { // invalid diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java b/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java index 162d57120..83293d4ee 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java @@ -30,6 +30,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; +import org.geysermc.geyser.registry.type.ItemMapping; import java.util.ArrayList; import java.util.List; @@ -70,6 +71,28 @@ public final class BedrockItemBuilder { return builder; } + // NBT convenience methods. Returns NbtMapBuilder since that's what's used the most + + public NbtMapBuilder putByte(String name, byte value) { + return getOrCreateNbt().putByte(name, value); + } + + public NbtMapBuilder putByte(String name, int value) { + return getOrCreateNbt().putByte(name, (byte) value); + } + + public NbtMapBuilder putInt(String name, int value) { + return getOrCreateNbt().putInt(name, value); + } + + public NbtMapBuilder putString(String name, String value) { + return getOrCreateNbt().putString(name, value); + } + + public NbtMapBuilder putCompound(String name, NbtMap value) { + return getOrCreateNbt().putCompound(name, value); + } + /** * @return null if no NBT is needed on this item. */ @@ -90,4 +113,16 @@ public final class BedrockItemBuilder { } return builder.build(); } + + /** + * Creates item NBT with count, name, and damage set. + */ + public static NbtMapBuilder createItemNbt(ItemMapping mapping, int count, int damage) { + NbtMapBuilder builder = NbtMap.builder(); + builder.putByte("Count", (byte) count); + builder.putString("Name", mapping.getBedrockIdentifier()); + + builder.putShort("Damage", (short) damage); + return builder; + } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index b52861b35..6459aa9ec 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -141,7 +141,7 @@ public final class ItemTranslator { BedrockItemBuilder nbtBuilder = new BedrockItemBuilder(); if (components != null) { - javaItem.translateComponentsToBedrock(session, components, nbtBuilder.getOrCreateNbt()); + javaItem.translateComponentsToBedrock(session, components, nbtBuilder); } String customName = getCustomName(session, components, bedrockItem); From 6d8021f155765de2cd668d24985f19f03943c15e Mon Sep 17 00:00:00 2001 From: basaigh <53559772+basaigh@users.noreply.github.com> Date: Sun, 21 Apr 2024 00:12:53 +0100 Subject: [PATCH 072/272] Update the non-item parts (#4586) * Update the non-item parts * Add MaceItem * Fix registry data loading --- .../geyser/inventory/item/Enchantment.java | 5 +- .../updater/AnvilInventoryUpdater.java | 2 +- .../geysermc/geyser/item/ArmorMaterial.java | 7 +- .../java/org/geysermc/geyser/item/Items.java | 106 ++++++++++-------- .../geysermc/geyser/item/type/MaceItem.java | 39 +++++++ .../geysermc/geyser/level/JavaDimension.java | 22 ++-- .../geyser/network/netty/LocalSession.java | 2 +- .../loader/EnchantmentRegistryLoader.java | 8 +- .../registry/populator/Conversion649_630.java | 4 +- .../registry/populator/Conversion662_649.java | 24 +++- .../registry/populator/Conversion671_662.java | 25 ++++- .../geyser/session/GeyserSession.java | 5 +- .../inventory/PlayerInventoryTranslator.java | 8 +- .../translator/level/BiomeTranslator.java | 20 ++-- .../protocol/java/JavaCommandsTranslator.java | 2 +- .../protocol/java/JavaLoginTranslator.java | 8 +- .../java/JavaRegistryDataTranslator.java | 46 ++++---- .../protocol/java/JavaRespawnTranslator.java | 6 +- .../level/JavaLevelParticlesTranslator.java | 3 +- .../geysermc/geyser/util/AttributeUtils.java | 4 +- .../geysermc/geyser/util/DimensionUtils.java | 34 ++++-- .../geysermc/geyser/util/InventoryUtils.java | 8 +- .../geysermc/geyser/util/JavaCodecUtil.java | 64 ----------- gradle/libs.versions.toml | 4 +- 24 files changed, 255 insertions(+), 201 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/item/type/MaceItem.java delete mode 100644 core/src/main/java/org/geysermc/geyser/util/JavaCodecUtil.java diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/Enchantment.java b/core/src/main/java/org/geysermc/geyser/inventory/item/Enchantment.java index 5fa2a5784..773de29b1 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/Enchantment.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/Enchantment.java @@ -118,7 +118,7 @@ public enum Enchantment { KNOCKBACK, FIRE_ASPECT, LOOTING, - SWEEPING, + SWEEPING_EDGE, EFFICIENCY, SILK_TOUCH, UNBREAKING, @@ -136,6 +136,9 @@ public enum Enchantment { MULTISHOT, QUICK_CHARGE, PIERCING, + DENSITY, + BREACH, + WIND_BURST, MENDING, VANISHING_CURSE; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java b/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java index 5adee0c20..96ef12861 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java @@ -350,7 +350,7 @@ public class AnvilInventoryUpdater extends InventoryUpdater { if (enchantment == JavaEnchantment.IMPALING) { // Multiplier is halved on Bedrock for some reason rarityMultiplier /= 2; - } else if (enchantment == JavaEnchantment.SWEEPING) { + } else if (enchantment == JavaEnchantment.SWEEPING_EDGE) { // Doesn't exist on Bedrock rarityMultiplier = 0; } diff --git a/core/src/main/java/org/geysermc/geyser/item/ArmorMaterial.java b/core/src/main/java/org/geysermc/geyser/item/ArmorMaterial.java index 315a8cd4d..348c0af8c 100644 --- a/core/src/main/java/org/geysermc/geyser/item/ArmorMaterial.java +++ b/core/src/main/java/org/geysermc/geyser/item/ArmorMaterial.java @@ -31,12 +31,13 @@ import java.util.function.Supplier; public enum ArmorMaterial { LEATHER(() -> Items.LEATHER), - CHAIN(() -> Items.IRON_INGOT), + CHAINMAIL(() -> Items.IRON_INGOT), IRON(() -> Items.IRON_INGOT), GOLD(() -> Items.GOLD_INGOT), DIAMOND(() -> Items.DIAMOND), - TURTLE(() -> Items.SCUTE), - NETHERITE(() -> Items.NETHERITE_INGOT); + TURTLE(() -> Items.TURTLE_SCUTE), + NETHERITE(() -> Items.NETHERITE_INGOT), + ARMADILLO(() -> Items.ARMADILLO_SCUTE); private final Supplier repairIngredient; diff --git a/core/src/main/java/org/geysermc/geyser/item/Items.java b/core/src/main/java/org/geysermc/geyser/item/Items.java index 2147ebb2c..42a087acf 100644 --- a/core/src/main/java/org/geysermc/geyser/item/Items.java +++ b/core/src/main/java/org/geysermc/geyser/item/Items.java @@ -123,6 +123,7 @@ public final class Items { public static final Item RAW_IRON_BLOCK = register(new BlockItem("raw_iron_block", builder())); public static final Item RAW_COPPER_BLOCK = register(new BlockItem("raw_copper_block", builder())); public static final Item RAW_GOLD_BLOCK = register(new BlockItem("raw_gold_block", builder())); + public static final Item HEAVY_CORE = register(new BlockItem("heavy_core", builder())); public static final Item AMETHYST_BLOCK = register(new BlockItem("amethyst_block", builder())); public static final Item BUDDING_AMETHYST = register(new BlockItem("budding_amethyst", builder())); public static final Item IRON_BLOCK = register(new BlockItem("iron_block", builder())); @@ -832,7 +833,9 @@ public final class Items { public static final Item STRUCTURE_BLOCK = register(new BlockItem("structure_block", builder())); public static final Item JIGSAW = register(new BlockItem("jigsaw", builder())); public static final Item TURTLE_HELMET = register(new ArmorItem("turtle_helmet", ArmorMaterial.TURTLE, builder().stackSize(1).maxDamage(275))); - public static final Item SCUTE = register(new Item("scute", builder())); + public static final Item TURTLE_SCUTE = register(new Item("turtle_scute", builder())); + public static final Item ARMADILLO_SCUTE = register(new Item("armadillo_scute", builder())); + public static final Item WOLF_ARMOR = register(new ArmorItem("wolf_armor", ArmorMaterial.ARMADILLO, builder().stackSize(1).maxDamage(64))); public static final Item FLINT_AND_STEEL = register(new Item("flint_and_steel", builder().stackSize(1).maxDamage(64))); public static final Item APPLE = register(new Item("apple", builder())); public static final Item BOW = register(new Item("bow", builder().stackSize(1).maxDamage(384))); @@ -852,36 +855,36 @@ public final class Items { public static final Item GOLD_INGOT = register(new Item("gold_ingot", builder())); public static final Item NETHERITE_INGOT = register(new Item("netherite_ingot", builder())); public static final Item NETHERITE_SCRAP = register(new Item("netherite_scrap", builder())); - public static final Item WOODEN_SWORD = register(new TieredItem("wooden_sword", ToolTier.WOODEN, builder().stackSize(1).attackDamage(4).maxDamage(59))); - public static final Item WOODEN_SHOVEL = register(new TieredItem("wooden_shovel", ToolTier.WOODEN, builder().stackSize(1).attackDamage(2.5).maxDamage(59))); - public static final Item WOODEN_PICKAXE = register(new TieredItem("wooden_pickaxe", ToolTier.WOODEN, builder().stackSize(1).attackDamage(2).maxDamage(59))); - public static final Item WOODEN_AXE = register(new TieredItem("wooden_axe", ToolTier.WOODEN, builder().stackSize(1).attackDamage(7).maxDamage(59))); - public static final Item WOODEN_HOE = register(new TieredItem("wooden_hoe", ToolTier.WOODEN, builder().stackSize(1).attackDamage(1).maxDamage(59))); - public static final Item STONE_SWORD = register(new TieredItem("stone_sword", ToolTier.STONE, builder().stackSize(1).attackDamage(5).maxDamage(131))); - public static final Item STONE_SHOVEL = register(new TieredItem("stone_shovel", ToolTier.STONE, builder().stackSize(1).attackDamage(3.5).maxDamage(131))); - public static final Item STONE_PICKAXE = register(new TieredItem("stone_pickaxe", ToolTier.STONE, builder().stackSize(1).attackDamage(3).maxDamage(131))); - public static final Item STONE_AXE = register(new TieredItem("stone_axe", ToolTier.STONE, builder().stackSize(1).attackDamage(9).maxDamage(131))); - public static final Item STONE_HOE = register(new TieredItem("stone_hoe", ToolTier.STONE, builder().stackSize(1).attackDamage(1).maxDamage(131))); - public static final Item GOLDEN_SWORD = register(new TieredItem("golden_sword", ToolTier.GOLDEN, builder().stackSize(1).attackDamage(4).maxDamage(32))); - public static final Item GOLDEN_SHOVEL = register(new TieredItem("golden_shovel", ToolTier.GOLDEN, builder().stackSize(1).attackDamage(2.5).maxDamage(32))); - public static final Item GOLDEN_PICKAXE = register(new TieredItem("golden_pickaxe", ToolTier.GOLDEN, builder().stackSize(1).attackDamage(2).maxDamage(32))); - public static final Item GOLDEN_AXE = register(new TieredItem("golden_axe", ToolTier.GOLDEN, builder().stackSize(1).attackDamage(7).maxDamage(32))); - public static final Item GOLDEN_HOE = register(new TieredItem("golden_hoe", ToolTier.GOLDEN, builder().stackSize(1).attackDamage(1).maxDamage(32))); - public static final Item IRON_SWORD = register(new TieredItem("iron_sword", ToolTier.IRON, builder().stackSize(1).attackDamage(6).maxDamage(250))); - public static final Item IRON_SHOVEL = register(new TieredItem("iron_shovel", ToolTier.IRON, builder().stackSize(1).attackDamage(4.5).maxDamage(250))); - public static final Item IRON_PICKAXE = register(new TieredItem("iron_pickaxe", ToolTier.IRON, builder().stackSize(1).attackDamage(4).maxDamage(250))); - public static final Item IRON_AXE = register(new TieredItem("iron_axe", ToolTier.IRON, builder().stackSize(1).attackDamage(9).maxDamage(250))); - public static final Item IRON_HOE = register(new TieredItem("iron_hoe", ToolTier.IRON, builder().stackSize(1).attackDamage(1).maxDamage(250))); - public static final Item DIAMOND_SWORD = register(new TieredItem("diamond_sword", ToolTier.DIAMOND, builder().stackSize(1).attackDamage(7).maxDamage(1561))); - public static final Item DIAMOND_SHOVEL = register(new TieredItem("diamond_shovel", ToolTier.DIAMOND, builder().stackSize(1).attackDamage(5.5).maxDamage(1561))); - public static final Item DIAMOND_PICKAXE = register(new TieredItem("diamond_pickaxe", ToolTier.DIAMOND, builder().stackSize(1).attackDamage(5).maxDamage(1561))); - public static final Item DIAMOND_AXE = register(new TieredItem("diamond_axe", ToolTier.DIAMOND, builder().stackSize(1).attackDamage(9).maxDamage(1561))); - public static final Item DIAMOND_HOE = register(new TieredItem("diamond_hoe", ToolTier.DIAMOND, builder().stackSize(1).attackDamage(1).maxDamage(1561))); - public static final Item NETHERITE_SWORD = register(new TieredItem("netherite_sword", ToolTier.NETHERITE, builder().stackSize(1).attackDamage(8).maxDamage(2031))); - public static final Item NETHERITE_SHOVEL = register(new TieredItem("netherite_shovel", ToolTier.NETHERITE, builder().stackSize(1).attackDamage(6.5).maxDamage(2031))); - public static final Item NETHERITE_PICKAXE = register(new TieredItem("netherite_pickaxe", ToolTier.NETHERITE, builder().stackSize(1).attackDamage(6).maxDamage(2031))); - public static final Item NETHERITE_AXE = register(new TieredItem("netherite_axe", ToolTier.NETHERITE, builder().stackSize(1).attackDamage(10).maxDamage(2031))); - public static final Item NETHERITE_HOE = register(new TieredItem("netherite_hoe", ToolTier.NETHERITE, builder().stackSize(1).attackDamage(1).maxDamage(2031))); + public static final Item WOODEN_SWORD = register(new TieredItem("wooden_sword", ToolTier.WOODEN, builder().stackSize(1).maxDamage(59).attackDamage(4.0))); + public static final Item WOODEN_SHOVEL = register(new TieredItem("wooden_shovel", ToolTier.WOODEN, builder().stackSize(1).maxDamage(59).attackDamage(2.5))); + public static final Item WOODEN_PICKAXE = register(new TieredItem("wooden_pickaxe", ToolTier.WOODEN, builder().stackSize(1).maxDamage(59).attackDamage(2.0))); + public static final Item WOODEN_AXE = register(new TieredItem("wooden_axe", ToolTier.WOODEN, builder().stackSize(1).maxDamage(59).attackDamage(7.0))); + public static final Item WOODEN_HOE = register(new TieredItem("wooden_hoe", ToolTier.WOODEN, builder().stackSize(1).maxDamage(59).attackDamage(1.0))); + public static final Item STONE_SWORD = register(new TieredItem("stone_sword", ToolTier.STONE, builder().stackSize(1).maxDamage(131).attackDamage(5.0))); + public static final Item STONE_SHOVEL = register(new TieredItem("stone_shovel", ToolTier.STONE, builder().stackSize(1).maxDamage(131).attackDamage(3.5))); + public static final Item STONE_PICKAXE = register(new TieredItem("stone_pickaxe", ToolTier.STONE, builder().stackSize(1).maxDamage(131).attackDamage(3.0))); + public static final Item STONE_AXE = register(new TieredItem("stone_axe", ToolTier.STONE, builder().stackSize(1).maxDamage(131).attackDamage(9.0))); + public static final Item STONE_HOE = register(new TieredItem("stone_hoe", ToolTier.STONE, builder().stackSize(1).maxDamage(131).attackDamage(1.0))); + public static final Item GOLDEN_SWORD = register(new TieredItem("golden_sword", ToolTier.GOLDEN, builder().stackSize(1).maxDamage(32).attackDamage(4.0))); + public static final Item GOLDEN_SHOVEL = register(new TieredItem("golden_shovel", ToolTier.GOLDEN, builder().stackSize(1).maxDamage(32).attackDamage(2.5))); + public static final Item GOLDEN_PICKAXE = register(new TieredItem("golden_pickaxe", ToolTier.GOLDEN, builder().stackSize(1).maxDamage(32).attackDamage(2.0))); + public static final Item GOLDEN_AXE = register(new TieredItem("golden_axe", ToolTier.GOLDEN, builder().stackSize(1).maxDamage(32).attackDamage(7.0))); + public static final Item GOLDEN_HOE = register(new TieredItem("golden_hoe", ToolTier.GOLDEN, builder().stackSize(1).maxDamage(32).attackDamage(1.0))); + public static final Item IRON_SWORD = register(new TieredItem("iron_sword", ToolTier.IRON, builder().stackSize(1).maxDamage(250).attackDamage(6.0))); + public static final Item IRON_SHOVEL = register(new TieredItem("iron_shovel", ToolTier.IRON, builder().stackSize(1).maxDamage(250).attackDamage(4.5))); + public static final Item IRON_PICKAXE = register(new TieredItem("iron_pickaxe", ToolTier.IRON, builder().stackSize(1).maxDamage(250).attackDamage(4.0))); + public static final Item IRON_AXE = register(new TieredItem("iron_axe", ToolTier.IRON, builder().stackSize(1).maxDamage(250).attackDamage(9.0))); + public static final Item IRON_HOE = register(new TieredItem("iron_hoe", ToolTier.IRON, builder().stackSize(1).maxDamage(250).attackDamage(1.0))); + public static final Item DIAMOND_SWORD = register(new TieredItem("diamond_sword", ToolTier.DIAMOND, builder().stackSize(1).maxDamage(1561).attackDamage(7.0))); + public static final Item DIAMOND_SHOVEL = register(new TieredItem("diamond_shovel", ToolTier.DIAMOND, builder().stackSize(1).maxDamage(1561).attackDamage(5.5))); + public static final Item DIAMOND_PICKAXE = register(new TieredItem("diamond_pickaxe", ToolTier.DIAMOND, builder().stackSize(1).maxDamage(1561).attackDamage(5.0))); + public static final Item DIAMOND_AXE = register(new TieredItem("diamond_axe", ToolTier.DIAMOND, builder().stackSize(1).maxDamage(1561).attackDamage(9.0))); + public static final Item DIAMOND_HOE = register(new TieredItem("diamond_hoe", ToolTier.DIAMOND, builder().stackSize(1).maxDamage(1561).attackDamage(1.0))); + public static final Item NETHERITE_SWORD = register(new TieredItem("netherite_sword", ToolTier.NETHERITE, builder().stackSize(1).maxDamage(2031).attackDamage(8.0))); + public static final Item NETHERITE_SHOVEL = register(new TieredItem("netherite_shovel", ToolTier.NETHERITE, builder().stackSize(1).maxDamage(2031).attackDamage(6.5))); + public static final Item NETHERITE_PICKAXE = register(new TieredItem("netherite_pickaxe", ToolTier.NETHERITE, builder().stackSize(1).maxDamage(2031).attackDamage(6.0))); + public static final Item NETHERITE_AXE = register(new TieredItem("netherite_axe", ToolTier.NETHERITE, builder().stackSize(1).maxDamage(2031).attackDamage(10.0))); + public static final Item NETHERITE_HOE = register(new TieredItem("netherite_hoe", ToolTier.NETHERITE, builder().stackSize(1).maxDamage(2031).attackDamage(1.0))); public static final Item STICK = register(new Item("stick", builder())); public static final Item BOWL = register(new Item("bowl", builder())); public static final Item MUSHROOM_STEW = register(new Item("mushroom_stew", builder().stackSize(1))); @@ -891,14 +894,14 @@ public final class Items { public static final Item WHEAT_SEEDS = register(new BlockItem("wheat_seeds", builder())); public static final Item WHEAT = register(new Item("wheat", builder())); public static final Item BREAD = register(new Item("bread", builder())); - public static final Item LEATHER_HELMET = register(new DyeableArmorItem("leather_helmet", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(55))); - public static final Item LEATHER_CHESTPLATE = register(new DyeableArmorItem("leather_chestplate", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(80))); - public static final Item LEATHER_LEGGINGS = register(new DyeableArmorItem("leather_leggings", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(75))); - public static final Item LEATHER_BOOTS = register(new DyeableArmorItem("leather_boots", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(65))); - public static final Item CHAINMAIL_HELMET = register(new ArmorItem("chainmail_helmet", ArmorMaterial.CHAIN, builder().stackSize(1).maxDamage(165))); - public static final Item CHAINMAIL_CHESTPLATE = register(new ArmorItem("chainmail_chestplate", ArmorMaterial.CHAIN, builder().stackSize(1).maxDamage(240))); - public static final Item CHAINMAIL_LEGGINGS = register(new ArmorItem("chainmail_leggings", ArmorMaterial.CHAIN, builder().stackSize(1).maxDamage(225))); - public static final Item CHAINMAIL_BOOTS = register(new ArmorItem("chainmail_boots", ArmorMaterial.CHAIN, builder().stackSize(1).maxDamage(195))); + public static final Item LEATHER_HELMET = register(new ArmorItem("leather_helmet", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(55))); + public static final Item LEATHER_CHESTPLATE = register(new ArmorItem("leather_chestplate", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(80))); + public static final Item LEATHER_LEGGINGS = register(new ArmorItem("leather_leggings", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(75))); + public static final Item LEATHER_BOOTS = register(new ArmorItem("leather_boots", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(65))); + public static final Item CHAINMAIL_HELMET = register(new ArmorItem("chainmail_helmet", ArmorMaterial.CHAINMAIL, builder().stackSize(1).maxDamage(165))); + public static final Item CHAINMAIL_CHESTPLATE = register(new ArmorItem("chainmail_chestplate", ArmorMaterial.CHAINMAIL, builder().stackSize(1).maxDamage(240))); + public static final Item CHAINMAIL_LEGGINGS = register(new ArmorItem("chainmail_leggings", ArmorMaterial.CHAINMAIL, builder().stackSize(1).maxDamage(225))); + public static final Item CHAINMAIL_BOOTS = register(new ArmorItem("chainmail_boots", ArmorMaterial.CHAINMAIL, builder().stackSize(1).maxDamage(195))); public static final Item IRON_HELMET = register(new ArmorItem("iron_helmet", ArmorMaterial.IRON, builder().stackSize(1).maxDamage(165))); public static final Item IRON_CHESTPLATE = register(new ArmorItem("iron_chestplate", ArmorMaterial.IRON, builder().stackSize(1).maxDamage(240))); public static final Item IRON_LEGGINGS = register(new ArmorItem("iron_leggings", ArmorMaterial.IRON, builder().stackSize(1).maxDamage(225))); @@ -1043,11 +1046,13 @@ public final class Items { public static final Item CAULDRON = register(new BlockItem("cauldron", builder())); public static final Item ENDER_EYE = register(new Item("ender_eye", builder())); public static final Item GLISTERING_MELON_SLICE = register(new Item("glistering_melon_slice", builder())); + public static final Item ARMADILLO_SPAWN_EGG = register(new SpawnEggItem("armadillo_spawn_egg", builder())); public static final Item ALLAY_SPAWN_EGG = register(new SpawnEggItem("allay_spawn_egg", builder())); public static final Item AXOLOTL_SPAWN_EGG = register(new SpawnEggItem("axolotl_spawn_egg", builder())); public static final Item BAT_SPAWN_EGG = register(new SpawnEggItem("bat_spawn_egg", builder())); public static final Item BEE_SPAWN_EGG = register(new SpawnEggItem("bee_spawn_egg", builder())); public static final Item BLAZE_SPAWN_EGG = register(new SpawnEggItem("blaze_spawn_egg", builder())); + public static final Item BOGGED_SPAWN_EGG = register(new SpawnEggItem("bogged_spawn_egg", builder())); public static final Item BREEZE_SPAWN_EGG = register(new SpawnEggItem("breeze_spawn_egg", builder())); public static final Item CAT_SPAWN_EGG = register(new SpawnEggItem("cat_spawn_egg", builder())); public static final Item CAMEL_SPAWN_EGG = register(new SpawnEggItem("camel_spawn_egg", builder())); @@ -1123,8 +1128,10 @@ public final class Items { public static final Item ZOMBIFIED_PIGLIN_SPAWN_EGG = register(new SpawnEggItem("zombified_piglin_spawn_egg", builder())); public static final Item EXPERIENCE_BOTTLE = register(new Item("experience_bottle", builder())); public static final Item FIRE_CHARGE = register(new Item("fire_charge", builder())); + public static final Item WIND_CHARGE = register(new Item("wind_charge", builder())); public static final Item WRITABLE_BOOK = register(new WritableBookItem("writable_book", builder().stackSize(1))); public static final Item WRITTEN_BOOK = register(new WrittenBookItem("written_book", builder().stackSize(16))); + public static final Item MACE = register(new MaceItem("mace", builder().stackSize(1).maxDamage(250))); public static final Item ITEM_FRAME = register(new Item("item_frame", builder())); public static final Item GLOW_ITEM_FRAME = register(new Item("glow_item_frame", builder())); public static final Item FLOWER_POT = register(new BlockItem("flower_pot", builder())); @@ -1155,10 +1162,10 @@ public final class Items { public static final Item RABBIT_FOOT = register(new Item("rabbit_foot", builder())); public static final Item RABBIT_HIDE = register(new Item("rabbit_hide", builder())); public static final Item ARMOR_STAND = register(new Item("armor_stand", builder().stackSize(16))); - public static final Item IRON_HORSE_ARMOR = register(new Item("iron_horse_armor", builder().stackSize(1))); - public static final Item GOLDEN_HORSE_ARMOR = register(new Item("golden_horse_armor", builder().stackSize(1))); - public static final Item DIAMOND_HORSE_ARMOR = register(new Item("diamond_horse_armor", builder().stackSize(1))); - public static final Item LEATHER_HORSE_ARMOR = register(new DyeableHorseArmorItem("leather_horse_armor", builder().stackSize(1))); + public static final Item IRON_HORSE_ARMOR = register(new ArmorItem("iron_horse_armor", ArmorMaterial.IRON, builder().stackSize(1))); + public static final Item GOLDEN_HORSE_ARMOR = register(new ArmorItem("golden_horse_armor", ArmorMaterial.GOLD, builder().stackSize(1))); + public static final Item DIAMOND_HORSE_ARMOR = register(new ArmorItem("diamond_horse_armor", ArmorMaterial.DIAMOND, builder().stackSize(1))); + public static final Item LEATHER_HORSE_ARMOR = register(new ArmorItem("leather_horse_armor", ArmorMaterial.LEATHER, builder().stackSize(1))); public static final Item LEAD = register(new Item("lead", builder())); public static final Item NAME_TAG = register(new Item("name_tag", builder())); public static final Item COMMAND_BLOCK_MINECART = register(new Item("command_block_minecart", builder().stackSize(1))); @@ -1216,7 +1223,7 @@ public final class Items { public static final Item MUSIC_DISC_5 = register(new Item("music_disc_5", builder().stackSize(1))); public static final Item MUSIC_DISC_PIGSTEP = register(new Item("music_disc_pigstep", builder().stackSize(1))); public static final Item DISC_FRAGMENT_5 = register(new Item("disc_fragment_5", builder())); - public static final Item TRIDENT = register(new Item("trident", builder().stackSize(1).attackDamage(9).maxDamage(250))); + public static final Item TRIDENT = register(new Item("trident", builder().stackSize(1).maxDamage(250).attackDamage(9.0))); public static final Item PHANTOM_MEMBRANE = register(new Item("phantom_membrane", builder())); public static final Item NAUTILUS_SHELL = register(new Item("nautilus_shell", builder())); public static final Item HEART_OF_THE_SEA = register(new Item("heart_of_the_sea", builder())); @@ -1229,6 +1236,8 @@ public final class Items { public static final Item MOJANG_BANNER_PATTERN = register(new Item("mojang_banner_pattern", builder().stackSize(1))); public static final Item GLOBE_BANNER_PATTERN = register(new Item("globe_banner_pattern", builder().stackSize(1))); public static final Item PIGLIN_BANNER_PATTERN = register(new Item("piglin_banner_pattern", builder().stackSize(1))); + public static final Item FLOW_BANNER_PATTERN = register(new Item("flow_banner_pattern", builder().stackSize(1))); + public static final Item GUSTER_BANNER_PATTERN = register(new Item("guster_banner_pattern", builder().stackSize(1))); public static final Item GOAT_HORN = register(new GoatHornItem("goat_horn", builder().stackSize(1))); public static final Item COMPOSTER = register(new BlockItem("composter", builder())); public static final Item BARREL = register(new ChestItem("barrel", builder())); @@ -1312,6 +1321,8 @@ public final class Items { public static final Item SILENCE_ARMOR_TRIM_SMITHING_TEMPLATE = register(new Item("silence_armor_trim_smithing_template", builder())); public static final Item RAISER_ARMOR_TRIM_SMITHING_TEMPLATE = register(new Item("raiser_armor_trim_smithing_template", builder())); public static final Item HOST_ARMOR_TRIM_SMITHING_TEMPLATE = register(new Item("host_armor_trim_smithing_template", builder())); + public static final Item FLOW_ARMOR_TRIM_SMITHING_TEMPLATE = register(new Item("flow_armor_trim_smithing_template", builder())); + public static final Item BOLT_ARMOR_TRIM_SMITHING_TEMPLATE = register(new Item("bolt_armor_trim_smithing_template", builder())); public static final Item ANGLER_POTTERY_SHERD = register(new Item("angler_pottery_sherd", builder())); public static final Item ARCHER_POTTERY_SHERD = register(new Item("archer_pottery_sherd", builder())); public static final Item ARMS_UP_POTTERY_SHERD = register(new Item("arms_up_pottery_sherd", builder())); @@ -1320,7 +1331,9 @@ public final class Items { public static final Item BURN_POTTERY_SHERD = register(new Item("burn_pottery_sherd", builder())); public static final Item DANGER_POTTERY_SHERD = register(new Item("danger_pottery_sherd", builder())); public static final Item EXPLORER_POTTERY_SHERD = register(new Item("explorer_pottery_sherd", builder())); + public static final Item FLOW_POTTERY_SHERD = register(new Item("flow_pottery_sherd", builder())); public static final Item FRIEND_POTTERY_SHERD = register(new Item("friend_pottery_sherd", builder())); + public static final Item GUSTER_POTTERY_SHERD = register(new Item("guster_pottery_sherd", builder())); public static final Item HEART_POTTERY_SHERD = register(new Item("heart_pottery_sherd", builder())); public static final Item HEARTBREAK_POTTERY_SHERD = register(new Item("heartbreak_pottery_sherd", builder())); public static final Item HOWL_POTTERY_SHERD = register(new Item("howl_pottery_sherd", builder())); @@ -1328,6 +1341,7 @@ public final class Items { public static final Item MOURNER_POTTERY_SHERD = register(new Item("mourner_pottery_sherd", builder())); public static final Item PLENTY_POTTERY_SHERD = register(new Item("plenty_pottery_sherd", builder())); public static final Item PRIZE_POTTERY_SHERD = register(new Item("prize_pottery_sherd", builder())); + public static final Item SCRAPE_POTTERY_SHERD = register(new Item("scrape_pottery_sherd", builder())); public static final Item SHEAF_POTTERY_SHERD = register(new Item("sheaf_pottery_sherd", builder())); public static final Item SHELTER_POTTERY_SHERD = register(new Item("shelter_pottery_sherd", builder())); public static final Item SKULL_POTTERY_SHERD = register(new Item("skull_pottery_sherd", builder())); @@ -1350,6 +1364,10 @@ public final class Items { public static final Item WAXED_OXIDIZED_COPPER_BULB = register(new BlockItem("waxed_oxidized_copper_bulb", builder())); public static final Item TRIAL_SPAWNER = register(new BlockItem("trial_spawner", builder())); public static final Item TRIAL_KEY = register(new Item("trial_key", builder())); + public static final Item OMINOUS_TRIAL_KEY = register(new Item("ominous_trial_key", builder())); + public static final Item VAULT = register(new BlockItem("vault", builder())); + public static final Item OMINOUS_BOTTLE = register(new Item("ominous_bottle", builder())); + public static final Item BREEZE_ROD = register(new Item("breeze_rod", builder())); public static final int AIR_ID = AIR.javaId(); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/MaceItem.java b/core/src/main/java/org/geysermc/geyser/item/type/MaceItem.java new file mode 100644 index 000000000..e7b9a8684 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/item/type/MaceItem.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.item.type; + +import org.geysermc.geyser.item.Items; + +public class MaceItem extends Item { + public MaceItem(String javaIdentifier, Builder builder) { + super(javaIdentifier, builder); + } + + @Override + public boolean isValidRepairItem(Item other) { + return other == Items.BREEZE_ROD; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java b/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java index a3f6b55e4..6e7223da0 100644 --- a/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java +++ b/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java @@ -25,11 +25,12 @@ package org.geysermc.geyser.level; +import com.github.steveice10.mc.protocol.data.game.RegistryEntry; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; -import org.geysermc.geyser.util.JavaCodecUtil; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import java.util.Map; +import java.util.List; /** * Represents the information we store from the current Java dimension @@ -38,19 +39,20 @@ import java.util.Map; */ public record JavaDimension(int minY, int maxY, boolean piglinSafe, double worldCoordinateScale) { - public static void load(CompoundTag tag, Map map) { - for (CompoundTag dimension : JavaCodecUtil.iterateAsTag(tag.get("minecraft:dimension_type"))) { - CompoundTag elements = dimension.get("element"); - int minY = ((IntTag) elements.get("min_y")).getValue(); - int maxY = ((IntTag) elements.get("height")).getValue(); + public static void load(List entries, Int2ObjectMap map) { + for (int i = 0; i < entries.size(); i++) { + RegistryEntry entry = entries.get(i); + CompoundTag dimension = entry.getData(); + int minY = ((IntTag) dimension.get("min_y")).getValue(); + int maxY = ((IntTag) dimension.get("height")).getValue(); // Logical height can be ignored probably - seems to be for artificial limits like the Nether. // Set if piglins/hoglins should shake - boolean piglinSafe = ((Number) elements.get("piglin_safe").getValue()).byteValue() != (byte) 0; + boolean piglinSafe = ((Number) dimension.get("piglin_safe").getValue()).byteValue() != (byte) 0; // Load world coordinate scale for the world border - double coordinateScale = ((Number) elements.get("coordinate_scale").getValue()).doubleValue(); + double coordinateScale = ((Number) dimension.get("coordinate_scale").getValue()).doubleValue(); - map.put((String) dimension.get("name").getValue(), new JavaDimension(minY, maxY, piglinSafe, coordinateScale)); + map.put(i, new JavaDimension(minY, maxY, piglinSafe, coordinateScale)); } } } diff --git a/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java b/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java index a2951116f..121c70f90 100644 --- a/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java +++ b/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java @@ -79,7 +79,7 @@ public final class LocalSession extends TcpSession { public void initChannel(@NonNull LocalChannelWithRemoteAddress channel) { channel.spoofedRemoteAddress(new InetSocketAddress(clientIp, 0)); PacketProtocol protocol = getPacketProtocol(); - protocol.newClientSession(LocalSession.this); + protocol.newClientSession(LocalSession.this, false); refreshReadTimeoutHandler(channel); refreshWriteTimeoutHandler(channel); diff --git a/core/src/main/java/org/geysermc/geyser/registry/loader/EnchantmentRegistryLoader.java b/core/src/main/java/org/geysermc/geyser/registry/loader/EnchantmentRegistryLoader.java index 185eca694..8a0fb1f40 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/loader/EnchantmentRegistryLoader.java +++ b/core/src/main/java/org/geysermc/geyser/registry/loader/EnchantmentRegistryLoader.java @@ -56,13 +56,7 @@ public class EnchantmentRegistryLoader implements RegistryLoader entry = it.next(); JavaEnchantment key = JavaEnchantment.getByJavaIdentifier(entry.getKey()); JsonNode node = entry.getValue(); - int rarityMultiplier = switch (node.get("rarity").textValue()) { - case "common" -> 1; - case "uncommon" -> 2; - case "rare" -> 4; - case "very_rare" -> 8; - default -> throw new IllegalStateException("Unexpected value: " + node.get("rarity").textValue()); - }; + int rarityMultiplier = node.get("anvil_cost").asInt(); int maxLevel = node.get("max_level").asInt(); EnumSet incompatibleEnchantments = EnumSet.noneOf(JavaEnchantment.class); diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion649_630.java b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion649_630.java index 56de1081e..70a5e1ad9 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion649_630.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion649_630.java @@ -37,9 +37,11 @@ public class Conversion649_630 { String identifer = mapping.getBedrockIdentifier(); switch (identifer) { - case "minecraft:turtle_scute" -> { return mapping.withBedrockIdentifier("minecraft:scute"); } + case "minecraft:armadillo_scute", "minecraft:turtle_scute" -> { return mapping.withBedrockIdentifier("minecraft:scute"); } + case "minecraft:armadillo_spawn_egg" -> { return mapping.withBedrockIdentifier("minecraft:rabbit_spawn_egg"); } case "minecraft:trial_spawner" -> { return mapping.withBedrockIdentifier("minecraft:mob_spawner"); } case "minecraft:trial_key" -> { return mapping.withBedrockIdentifier("minecraft:echo_shard"); } + case "minecraft:wolf_armor" -> { return mapping.withBedrockIdentifier("minecraft:leather_horse_armor"); } default -> { return mapping; } } } diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java index 0fe1610f2..041afdbc8 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java @@ -35,7 +35,7 @@ import java.util.stream.Stream; public class Conversion662_649 { - private static final List NEW_MISC = List.of("minecraft:grass_block", "minecraft:trial_spawner"); + private static final List NEW_MISC = List.of("minecraft:grass_block", "minecraft:vault"); private static final List NEW_WOODS = List.of("minecraft:oak_wood", "minecraft:spruce_wood", "minecraft:birch_wood", "minecraft:jungle_wood", "minecraft:acacia_wood", "minecraft:dark_oak_wood", "minecraft:stripped_oak_wood", "minecraft:stripped_spruce_wood", "minecraft:stripped_birch_wood", "minecraft:stripped_jungle_wood", "minecraft:stripped_acacia_wood", "minecraft:stripped_dark_oak_wood"); private static final List NEW_LEAVES = List.of("minecraft:oak_leaves", "minecraft:spruce_leaves", "minecraft:birch_leaves", "minecraft:jungle_leaves"); private static final List NEW_LEAVES2 = List.of("minecraft:acacia_leaves", "minecraft:dark_oak_leaves"); @@ -48,9 +48,12 @@ public class Conversion662_649 { String identifer = mapping.getBedrockIdentifier(); - if (identifer.equals("minecraft:grass_block")) { - return mapping.withBedrockIdentifier("minecraft:grass"); - } + switch (identifer) { + case "minecraft:bogged_spawn_egg" -> { return mapping.withBedrockIdentifier("minecraft:creeper_spawn_egg"); } + case "minecraft:grass_block" -> { return mapping.withBedrockIdentifier("minecraft:grass"); } + case "minecraft:vault" -> { return mapping.withBedrockIdentifier("minecraft:trial_spawner"); } + case "minecraft:wind_charge" -> { return mapping.withBedrockIdentifier("minecraft:snowball"); } + }; if (NEW_WOODS.contains(identifer)) { switch (identifer) { @@ -114,6 +117,19 @@ public class Conversion662_649 { return builder.build(); } + if (name.equals("minecraft:vault")) { + replacement = "minecraft:trial_spawner"; + + NbtMapBuilder statesBuilder = NbtMap.builder() + .putInt("trial_spawner_state", 0); + + NbtMapBuilder builder = tag.toBuilder(); + builder.putString("name", replacement); + builder.putCompound("states", statesBuilder.build()); + + return builder.build(); + } + if (NEW_WOODS.contains(name)) { replacement = "minecraft:wood"; diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion671_662.java b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion671_662.java index 2c6db7567..29ab3f2e5 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion671_662.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion671_662.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.registry.populator; import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.registry.type.GeyserMappingItem; @@ -33,11 +34,12 @@ import java.util.List; import java.util.stream.Stream; public class Conversion671_662 { + private static final List NEW_MISC = List.of("minecraft:heavy_core", "minecraft:mace", "minecraft:flow_banner_pattern", "minecraft:guster_banner_pattern", "minecraft:flow_armor_trim_smithing_template", "minecraft:bolt_armor_trim_smithing_template", "minecraft:flow_pottery_sherd", "minecraft:guster_pottery_sherd", "minecraft:scrape_pottery_sherd", "minecraft:breeze_rod"); private static final List NEW_CORAL_FANS = List.of("minecraft:tube_coral_fan", "minecraft:brain_coral_fan", "minecraft:bubble_coral_fan", "minecraft:fire_coral_fan", "minecraft:horn_coral_fan"); private static final List NEW_DEAD_CORAL_FANS = List.of("minecraft:dead_tube_coral_fan", "minecraft:dead_brain_coral_fan", "minecraft:dead_bubble_coral_fan", "minecraft:dead_fire_coral_fan", "minecraft:dead_horn_coral_fan"); private static final List NEW_FLOWERS = List.of("minecraft:poppy", "minecraft:blue_orchid", "minecraft:allium", "minecraft:azure_bluet", "minecraft:red_tulip", "minecraft:orange_tulip", "minecraft:white_tulip", "minecraft:pink_tulip", "minecraft:oxeye_daisy", "minecraft:cornflower", "minecraft:lily_of_the_valley"); private static final List NEW_SAPLINGS = List.of("minecraft:oak_sapling", "minecraft:spruce_sapling", "minecraft:birch_sapling", "minecraft:jungle_sapling", "minecraft:acacia_sapling", "minecraft:dark_oak_sapling", "minecraft:bamboo_sapling"); - private static final List NEW_BLOCKS = Stream.of(NEW_CORAL_FANS, NEW_DEAD_CORAL_FANS, NEW_FLOWERS, NEW_SAPLINGS).flatMap(List::stream).toList(); + private static final List NEW_BLOCKS = Stream.of(NEW_MISC, NEW_CORAL_FANS, NEW_DEAD_CORAL_FANS, NEW_FLOWERS, NEW_SAPLINGS).flatMap(List::stream).toList(); static GeyserMappingItem remapItem(@SuppressWarnings("unused") Item item, GeyserMappingItem mapping) { String identifer = mapping.getBedrockIdentifier(); @@ -46,6 +48,18 @@ public class Conversion671_662 { return mapping; } + switch (identifer) { + case "minecraft:bolt_armor_trim_smithing_template" -> { return mapping.withBedrockIdentifier("minecraft:wayfinder_armor_trim_smithing_template"); } + case "minecraft:breeze_rod" -> { return mapping.withBedrockIdentifier("minecraft:blaze_rod"); } + case "minecraft:flow_armor_trim_smithing_template" -> { return mapping.withBedrockIdentifier("minecraft:spire_armor_trim_smithing_template"); } + case "minecraft:flow_banner_pattern", "minecraft:guster_banner_pattern" -> { return mapping.withBedrockIdentifier("minecraft:globe_banner_pattern"); } + case "minecraft:flow_pottery_sherd" -> { return mapping.withBedrockIdentifier("minecraft:skull_pottery_sherd"); } + case "minecraft:guster_pottery_sherd" -> { return mapping.withBedrockIdentifier("minecraft:shelter_pottery_sherd"); } + case "minecraft:scrape_pottery_sherd" -> { return mapping.withBedrockIdentifier("minecraft:heartbreak_pottery_sherd"); } + case "minecraft:heavy_core" -> { return mapping.withBedrockIdentifier("minecraft:conduit"); } + case "minecraft:mace" -> { return mapping.withBedrockIdentifier("minecraft:netherite_axe"); } + } + if (NEW_FLOWERS.contains(identifer)) { switch (identifer) { case "minecraft:poppy" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(0); } @@ -114,6 +128,15 @@ public class Conversion671_662 { String replacement; + if (name.equals("minecraft:heavy_core")) { + replacement = "minecraft:conduit"; + + NbtMapBuilder builder = tag.toBuilder(); + builder.putString("name", replacement); + + return builder.build(); + } + if (NEW_SAPLINGS.contains(name)) { replacement = "minecraft:sapling"; String saplingType = name.replaceAll("minecraft:|_sapling", "");; diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 63022636c..936fc932d 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -45,6 +45,7 @@ import com.github.steveice10.mc.protocol.data.game.statistic.Statistic; import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundClientInformationPacket; import com.github.steveice10.mc.protocol.packet.handshake.serverbound.ClientIntentionPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatCommandPacket; +import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatCommandSignedPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerAbilitiesPacket; @@ -360,7 +361,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { * As all entities are in the same world, this can be safely applied to all other entities. */ @Setter - private String dimension = DimensionUtils.OVERWORLD; + private int dimension = DimensionUtils.OVERWORLD; @MonotonicNonNull @Setter private JavaDimension dimensionType = null; @@ -1464,7 +1465,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { * Sends a command to the Java server. */ public void sendCommand(String command) { - sendDownstreamGamePacket(new ServerboundChatCommandPacket(command, Instant.now().toEpochMilli(), 0L, Collections.emptyList(), 0, new BitSet())); + sendDownstreamGamePacket(new ServerboundChatCommandSignedPacket(command, Instant.now().toEpochMilli(), 0L, Collections.emptyList(), 0, new BitSet())); } public void setServerRenderDistance(int renderDistance) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java index 429b577ce..b461c7afc 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java @@ -360,7 +360,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator { return rejectRequest(request); } - ServerboundSetCreativeModeSlotPacket creativeDropPacket = new ServerboundSetCreativeModeSlotPacket(-1, sourceItem.getItemStack(dropAction.getCount())); + ServerboundSetCreativeModeSlotPacket creativeDropPacket = new ServerboundSetCreativeModeSlotPacket((short)-1, sourceItem.getItemStack(dropAction.getCount())); session.sendDownstreamGamePacket(creativeDropPacket); sourceItem.sub(dropAction.getCount()); @@ -493,9 +493,9 @@ public class PlayerInventoryTranslator extends InventoryTranslator { dropStack = javaCreativeItem; } else { // Specify custom count - dropStack = new ItemStack(javaCreativeItem.getId(), dropAction.getCount(), javaCreativeItem.getNbt()); + dropStack = new ItemStack(javaCreativeItem.getId(), dropAction.getCount(), javaCreativeItem.getDataComponents()); } - ServerboundSetCreativeModeSlotPacket creativeDropPacket = new ServerboundSetCreativeModeSlotPacket(-1, dropStack); + ServerboundSetCreativeModeSlotPacket creativeDropPacket = new ServerboundSetCreativeModeSlotPacket((short)-1, dropStack); session.sendDownstreamGamePacket(creativeDropPacket); break; } @@ -516,7 +516,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator { GeyserItemStack item = inventory.getItem(slot); ItemStack itemStack = item.isEmpty() ? new ItemStack(-1, 0, null) : item.getItemStack(); - ServerboundSetCreativeModeSlotPacket creativePacket = new ServerboundSetCreativeModeSlotPacket(slot, itemStack); + ServerboundSetCreativeModeSlotPacket creativePacket = new ServerboundSetCreativeModeSlotPacket((short)slot, itemStack); session.sendDownstreamGamePacket(creativePacket); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java index 90ac1cc5e..d4288c5a7 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java @@ -25,15 +25,13 @@ package org.geysermc.geyser.translator.level; +import com.github.steveice10.mc.protocol.data.game.RegistryEntry; import com.github.steveice10.mc.protocol.data.game.chunk.BitStorage; import com.github.steveice10.mc.protocol.data.game.chunk.DataPalette; import com.github.steveice10.mc.protocol.data.game.chunk.palette.GlobalPalette; import com.github.steveice10.mc.protocol.data.game.chunk.palette.Palette; import com.github.steveice10.mc.protocol.data.game.chunk.palette.SingletonPalette; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.IntTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; import it.unimi.dsi.fastutil.ints.*; import org.geysermc.geyser.level.chunk.BlockStorage; import org.geysermc.geyser.level.chunk.bitarray.BitArray; @@ -41,24 +39,24 @@ import org.geysermc.geyser.level.chunk.bitarray.BitArrayVersion; import org.geysermc.geyser.level.chunk.bitarray.SingletonBitArray; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.util.JavaCodecUtil; import org.geysermc.geyser.util.MathUtils; +import java.util.List; + // Array index formula by https://wiki.vg/Chunk_Format public class BiomeTranslator { - public static void loadServerBiomes(GeyserSession session, CompoundTag codec) { + public static void loadServerBiomes(GeyserSession session, List entries) { Int2IntMap biomeTranslations = new Int2IntOpenHashMap(); - CompoundTag worldGen = codec.get("minecraft:worldgen/biome"); - ListTag serverBiomes = worldGen.get("value"); - session.setBiomeGlobalPalette(MathUtils.getGlobalPaletteForSize(serverBiomes.size())); + session.setBiomeGlobalPalette(MathUtils.getGlobalPaletteForSize(entries.size())); int greatestBiomeId = 0; - for (CompoundTag biomeTag : JavaCodecUtil.iterateAsTag(worldGen)) { - String javaIdentifier = ((StringTag) biomeTag.get("name")).getValue(); + for (int i = 0; i < entries.size(); i++) { + RegistryEntry entry = entries.get(i); + String javaIdentifier = entry.getId(); int bedrockId = Registries.BIOME_IDENTIFIERS.get().getOrDefault(javaIdentifier, 0); - int javaId = ((IntTag) biomeTag.get("id")).getValue(); + int javaId = i; if (javaId > greatestBiomeId) { greatestBiomeId = javaId; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java index 0d7f45c7d..9d3351217 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java @@ -60,7 +60,7 @@ import java.util.*; public class JavaCommandsTranslator extends PacketTranslator { private static final String[] ALL_EFFECT_IDENTIFIERS = EntityUtils.getAllEffectIdentifiers(); - private static final String[] ATTRIBUTES = AttributeType.Builtin.BUILTIN.keySet().toArray(new String[0]); + private static final String[] ATTRIBUTES = AttributeType.Builtin.BUILTIN.values().stream().map(AttributeType::getIdentifier).toList().toArray(new String[0]); private static final String[] ENUM_BOOLEAN = {"true", "false"}; private static final String[] VALID_COLORS; private static final String[] VALID_SCOREBOARD_SLOTS; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java index 4a15157f9..ebf99fb65 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java @@ -63,7 +63,7 @@ public class JavaLoginTranslator extends PacketTranslator { @Override public void translate(GeyserSession session, ClientboundRegistryDataPacket packet) { - Map dimensions = session.getDimensions(); - dimensions.clear(); - JavaDimension.load(packet.getRegistry(), dimensions); - - Int2ObjectMap chatTypes = session.getChatTypes(); - chatTypes.clear(); - for (CompoundTag tag : JavaCodecUtil.iterateAsTag(packet.getRegistry().get("minecraft:chat_type"))) { - // The ID is NOT ALWAYS THE SAME! ViaVersion as of 1.19 adds two registry entries that do NOT match vanilla. - int id = ((IntTag) tag.get("id")).getValue(); - CompoundTag element = tag.get("element"); - CompoundTag chat = element.get("chat"); - TextDecoration textDecoration = null; - if (chat != null) { - textDecoration = new TextDecoration(chat); - } - chatTypes.put(id, textDecoration); + if (packet.getRegistry().equals("minecraft:dimension_type")) { + Int2ObjectMap dimensions = session.getDimensions(); + dimensions.clear(); + JavaDimension.load(packet.getEntries(), dimensions); } - BiomeTranslator.loadServerBiomes(session, packet.getRegistry()); + if (packet.getRegistry().equals("minecraft:chat_type")) { + Int2ObjectMap chatTypes = session.getChatTypes(); + chatTypes.clear(); + List entries = packet.getEntries(); + for (int i = 0; i < entries.size(); i++) { + // The ID is NOT ALWAYS THE SAME! ViaVersion as of 1.19 adds two registry entries that do NOT match vanilla. + RegistryEntry entry = entries.get(i); + CompoundTag tag = entry.getData(); + CompoundTag chat = tag.get("chat"); + TextDecoration textDecoration = null; + if (chat != null) { + textDecoration = new TextDecoration(chat); + } + chatTypes.put(i, textDecoration); + } + } + + if (packet.getRegistry().equals("minecraft:worldgen/biome")) { + BiomeTranslator.loadServerBiomes(session, packet.getEntries()); + } } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java index d69077dcb..bfb590247 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java @@ -92,11 +92,11 @@ public class JavaRespawnTranslator extends PacketTranslator { - int blockState = session.getBlockMappings().getBedrockBlockId(((FallingDustParticleData) particle.getData()).getBlockState()); + int blockState = session.getBlockMappings().getBedrockBlockId(((BlockParticleData) particle.getData()).getBlockState()); return (position) -> { LevelEventPacket packet = new LevelEventPacket(); // In fact, FallingDustParticle should have data like DustParticle, diff --git a/core/src/main/java/org/geysermc/geyser/util/AttributeUtils.java b/core/src/main/java/org/geysermc/geyser/util/AttributeUtils.java index e1fe6e6f2..d79d606b4 100644 --- a/core/src/main/java/org/geysermc/geyser/util/AttributeUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/AttributeUtils.java @@ -45,12 +45,12 @@ public class AttributeUtils { } double value = base; for (AttributeModifier modifier : attribute.getModifiers()) { - if (modifier.getOperation() == ModifierOperation.ADD_MULTIPLIED) { + if (modifier.getOperation() == ModifierOperation.ADD_MULTIPLIED_BASE) { value += base * modifier.getAmount(); } } for (AttributeModifier modifier : attribute.getModifiers()) { - if (modifier.getOperation() == ModifierOperation.MULTIPLY) { + if (modifier.getOperation() == ModifierOperation.ADD_MULTIPLIED_TOTAL) { value *= 1.0D + modifier.getAmount(); } } diff --git a/core/src/main/java/org/geysermc/geyser/util/DimensionUtils.java b/core/src/main/java/org/geysermc/geyser/util/DimensionUtils.java index eaa7b5084..469accd40 100644 --- a/core/src/main/java/org/geysermc/geyser/util/DimensionUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/DimensionUtils.java @@ -50,19 +50,19 @@ public class DimensionUtils { /** * String reference to vanilla Java overworld dimension identifier */ - public static final String OVERWORLD = "minecraft:overworld"; + public static final int OVERWORLD = 0; /** * String reference to vanilla Java nether dimension identifier */ - public static final String NETHER = "minecraft:the_nether"; + public static final int NETHER = 3; /** * String reference to vanilla Java end dimension identifier */ - public static final String THE_END = "minecraft:the_end"; + public static final int THE_END = 2; - public static void switchDimension(GeyserSession session, String javaDimension) { + public static void switchDimension(GeyserSession session, int javaDimension) { int bedrockDimension = javaToBedrock(javaDimension); // new bedrock dimension - String previousDimension = session.getDimension(); // previous java dimension + int previousDimension = session.getDimension(); // previous java dimension Entity player = session.getPlayerEntity(); @@ -142,15 +142,15 @@ public class DimensionUtils { // we check if the player is entering the nether and apply the nether fog to fake the fact that the client // thinks they are in the end dimension. if (isCustomBedrockNetherId()) { - if (NETHER.equals(javaDimension)) { + if (NETHER == javaDimension) { session.camera().sendFog(BEDROCK_FOG_HELL); - } else if (NETHER.equals(previousDimension)) { + } else if (NETHER == previousDimension) { session.camera().removeFog(BEDROCK_FOG_HELL); } } } - public static void setBedrockDimension(GeyserSession session, String javaDimension) { + public static void setBedrockDimension(GeyserSession session, int javaDimension) { session.getChunkCache().setBedrockDimension(switch (javaDimension) { case DimensionUtils.THE_END -> BedrockDimension.THE_END; case DimensionUtils.NETHER -> DimensionUtils.isCustomBedrockNetherId() ? BedrockDimension.THE_END : BedrockDimension.THE_NETHER; @@ -174,7 +174,7 @@ public class DimensionUtils { * @param javaDimension Dimension ID to convert * @return Converted Bedrock edition dimension ID */ - public static int javaToBedrock(String javaDimension) { + public static int javaToBedrock(int javaDimension) { return switch (javaDimension) { case NETHER -> BEDROCK_NETHER_ID; case THE_END -> 2; @@ -182,6 +182,20 @@ public class DimensionUtils { }; } + /** + * Map the Java edition dimension IDs to Bedrock edition + * + * @param javaDimension Dimension ID to convert + * @return Converted Bedrock edition dimension ID + */ + public static int javaToBedrock(String javaDimension) { + return switch (javaDimension) { + case "minecraft:the_nether" -> BEDROCK_NETHER_ID; + case "minecraft:the_end" -> 2; + default -> 0; + }; + } + /** * The Nether dimension in Bedrock does not permit building above Y128 - the Bedrock above the dimension. * This workaround sets the Nether as the End dimension to ignore this limit. @@ -201,7 +215,7 @@ public class DimensionUtils { * @param newDimension the new dimension that the player will be transferred to * @return the fake dimension to transfer to */ - public static String getTemporaryDimension(String currentDimension, String newDimension) { + public static int getTemporaryDimension(int currentDimension, int newDimension) { if (isCustomBedrockNetherId()) { // Prevents rare instances of Bedrock locking up return javaToBedrock(newDimension) == 2 ? OVERWORLD : NETHER; diff --git a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java index e56aea8c9..7f3a02df6 100644 --- a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java @@ -27,6 +27,7 @@ package org.geysermc.geyser.util; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundPickItemPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetCreativeModeSlotPacket; @@ -66,6 +67,7 @@ import org.jetbrains.annotations.Contract; import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.Objects; import java.util.concurrent.TimeUnit; import java.util.function.IntFunction; @@ -77,7 +79,7 @@ public class InventoryUtils { */ public static int LAST_RECIPE_NET_ID; - public static final ItemStack REFRESH_ITEM = new ItemStack(1, 127, new CompoundTag("")); + public static final ItemStack REFRESH_ITEM = new ItemStack(1, 127, new DataComponents(new HashMap<>())); public static void openInventory(GeyserSession session, Inventory inventory) { session.setOpenInventory(inventory); @@ -279,7 +281,7 @@ public class InventoryUtils { if (session.getGameMode() == GameMode.CREATIVE) { int slot = findEmptyHotbarSlot(inventory); - ServerboundSetCreativeModeSlotPacket actionPacket = new ServerboundSetCreativeModeSlotPacket(slot, + ServerboundSetCreativeModeSlotPacket actionPacket = new ServerboundSetCreativeModeSlotPacket((short) slot, itemStack); if ((slot - 36) != inventory.getHeldItemSlot()) { setHotbarItem(session, slot); @@ -345,7 +347,7 @@ public class InventoryUtils { ItemMapping mapping = session.getItemMappings().getMapping(itemName); // TODO if (mapping != null) { - ServerboundSetCreativeModeSlotPacket actionPacket = new ServerboundSetCreativeModeSlotPacket(slot, + ServerboundSetCreativeModeSlotPacket actionPacket = new ServerboundSetCreativeModeSlotPacket((short)slot, new ItemStack(mapping.getJavaItem().javaId())); if ((slot - 36) != inventory.getHeldItemSlot()) { setHotbarItem(session, slot); diff --git a/core/src/main/java/org/geysermc/geyser/util/JavaCodecUtil.java b/core/src/main/java/org/geysermc/geyser/util/JavaCodecUtil.java deleted file mode 100644 index 795d45490..000000000 --- a/core/src/main/java/org/geysermc/geyser/util/JavaCodecUtil.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.geyser.util; - -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; -import org.checkerframework.checker.nullness.qual.NonNull; - -import java.util.Iterator; - -public final class JavaCodecUtil { - - /** - * Iterate over a Java Edition codec and return each entry as a CompoundTag - */ - public static Iterable iterateAsTag(CompoundTag tag) { - ListTag value = tag.get("value"); - Iterator originalIterator = value.iterator(); - return new Iterable<>() { - @NonNull - @Override - public Iterator iterator() { - return new Iterator<>() { - @Override - public boolean hasNext() { - return originalIterator.hasNext(); - } - - @Override - public CompoundTag next() { - return (CompoundTag) originalIterator.next(); - } - }; - } - }; - } - - private JavaCodecUtil() { - } -} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2d32159f0..e9fadb577 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "1.20.4-2-20240116.220521-7" +mcprotocollib = "b2e93c520a" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" @@ -107,7 +107,7 @@ guava = { group = "com.google.guava", name = "guava", version.ref = "guava" } gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" } junit = { group = "org.junit.jupiter", name = "junit-jupiter", version.ref = "junit" } mcauthlib = { group = "com.github.GeyserMC", name = "MCAuthLib", version.ref = "mcauthlib" } -mcprotocollib = { group = "com.github.steveice10", name = "mcprotocollib", version.ref = "mcprotocollib" } +mcprotocollib = { group = "com.github.geysermc", name = "mcprotocollib", version.ref = "mcprotocollib" } raknet = { group = "org.cloudburstmc.netty", name = "netty-transport-raknet", version.ref = "raknet" } terminalconsoleappender = { group = "net.minecrell", name = "terminalconsoleappender", version.ref = "terminalconsoleappender" } velocity-api = { group = "com.velocitypowered", name = "velocity-api", version.ref = "velocity" } From aed7f1bed73b6eab4e7c70be597c4c15a5767db8 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 20 Apr 2024 19:20:00 -0400 Subject: [PATCH 073/272] Update the item parts --- .../geyser/item/type/CompassItem.java | 8 +-- .../geyser/item/type/FilledMapItem.java | 10 ++-- .../geyser/item/type/FireworkRocketItem.java | 45 ++++++++--------- .../geyser/item/type/FireworkStarItem.java | 23 ++++----- .../geyser/item/type/FishingRodItem.java | 8 +-- .../geyser/item/type/GoatHornItem.java | 15 ++++-- .../org/geysermc/geyser/item/type/Item.java | 16 +++--- .../geysermc/geyser/item/type/MapItem.java | 15 +++--- .../geyser/item/type/PlayerHeadItem.java | 49 +++++++------------ .../geysermc/geyser/item/type/PotionItem.java | 18 +++---- .../geyser/item/type/ShulkerBoxItem.java | 2 +- .../geyser/item/type/TippedArrowItem.java | 9 ++-- .../item/type/TropicalFishBucketItem.java | 7 +-- .../geyser/item/type/WritableBookItem.java | 26 +++++----- .../geyser/item/type/WrittenBookItem.java | 41 +++++++++------- .../translator/item/BedrockItemBuilder.java | 27 ++++++++++ .../translator/item/ItemTranslator.java | 6 +-- 17 files changed, 171 insertions(+), 154 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java b/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java index 8d48d1307..10c574d5d 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java @@ -43,11 +43,11 @@ public class CompassItem extends Item { } @Override - public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) { - if (isLodestoneCompass(itemStack.getDataComponents())) { - return super.translateToBedrock(itemStack, mappings.getLodestoneCompass(), mappings); + public ItemData.Builder translateToBedrock(int count, DataComponents components, ItemMapping mapping, ItemMappings mappings) { + if (isLodestoneCompass(components)) { + return super.translateToBedrock(count, components, mappings.getLodestoneCompass(), mappings); } - return super.translateToBedrock(itemStack, mapping, mappings); + return super.translateToBedrock(count, components, mapping, mappings); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java index 78a175f8d..af0b84308 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java @@ -25,10 +25,8 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; @@ -39,12 +37,12 @@ public class FilledMapItem extends MapItem { } @Override - public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) { - ItemData.Builder builder = super.translateToBedrock(itemStack, mapping, mappings); - DataComponents components = itemStack.getDataComponents(); + public ItemData.Builder translateToBedrock(int count, DataComponents components, ItemMapping mapping, ItemMappings mappings) { + ItemData.Builder builder = super.translateToBedrock(count, components, mapping, mappings); if (components == null) { // This is a fallback for maps with no nbt (Change added back in June 2020; is it needed in 2023?) - return builder.tag(NbtMap.builder().putInt("map", 0).build()); + //return builder.tag(NbtMap.builder().putInt("map", 0).build()); TODO if this is *still* broken, let's move it to translateComponentsToBedrock + return builder; } else { Integer mapColor = components.get(DataComponentType.MAP_COLOR); if (mapColor != null) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java index d688e59f6..afb848e2d 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java @@ -32,6 +32,7 @@ import com.github.steveice10.opennbt.tag.builtin.*; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.level.FireworkColor; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; @@ -63,9 +64,10 @@ public class FireworkRocketItem extends Item { } List explosionNbt = new ArrayList<>(); for (Fireworks.FireworkExplosion explosion : explosions) { - explosionNbt.add(translateExplosionToBedrock(explosion, "")); + explosionNbt.add(translateExplosionToBedrock(explosion)); } - + fireworksNbt.putList("Explosions", NbtType.COMPOUND, explosionNbt); + builder.putCompound("Fireworks", fireworksNbt.build()); } @Override @@ -73,39 +75,34 @@ public class FireworkRocketItem extends Item { super.translateNbtToJava(tag, mapping); } - static NbtMap translateExplosionToBedrock(Fireworks.FireworkExplosion explosion, String newName) { + static NbtMap translateExplosionToBedrock(Fireworks.FireworkExplosion explosion) { NbtMapBuilder newExplosionData = NbtMap.builder(); - if (explosion.get("Type") != null) { - newExplosionData.put(new ByteTag("FireworkType", MathUtils.getNbtByte(explosion.get("Type").getValue()))); - } +// if (explosion.get("Type") != null) { +// newExplosionData.put(new ByteTag("FireworkType", MathUtils.getNbtByte(explosion.get("Type").getValue()))); +// } //newExplosionData.putByte("FireworkType", explosion.get) //TODO??? - // TODO do we need length checks - if (explosion.get("Colors") != null) { - int[] oldColors = (int[]) explosion.get("Colors").getValue(); - byte[] colors = new byte[oldColors.length]; + int[] oldColors = explosion.getColors(); + byte[] colors = new byte[oldColors.length]; - int i = 0; - for (int color : oldColors) { - colors[i++] = FireworkColor.fromJavaRGB(color); - } - - newExplosionData.put(new ByteArrayTag("FireworkColor", colors)); + int i = 0; + for (int color : oldColors) { + colors[i++] = FireworkColor.fromJavaRGB(color); } - if (explosion.get("FadeColors") != null) { - int[] oldColors = (int[]) explosion.get("FadeColors").getValue(); - byte[] colors = new byte[oldColors.length]; + newExplosionData.putByteArray("FireworkColor", colors); - int i = 0; - for (int color : oldColors) { - colors[i++] = FireworkColor.fromJavaRGB(color); - } + oldColors = explosion.getFadeColors(); + colors = new byte[oldColors.length]; - newExplosionData.put(new ByteArrayTag("FireworkFade", colors)); + i = 0; + for (int color : oldColors) { + colors[i++] = FireworkColor.fromJavaRGB(color); } + newExplosionData.putByteArray("FireworkFade", colors); + newExplosionData.putBoolean("FireworkTrail", explosion.isHasTrail()); newExplosionData.putBoolean("FireworkFlicker", explosion.isHasTwinkle()); // TODO verify diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java index 4ae9c8b13..505296418 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java @@ -25,12 +25,13 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; +import com.github.steveice10.mc.protocol.data.game.item.component.Fireworks; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.IntArrayTag; -import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMap; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; @@ -44,19 +45,15 @@ public class FireworkStarItem extends Item { public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - Tag explosion = tag.remove("Explosion"); - if (explosion instanceof CompoundTag) { - CompoundTag newExplosion = FireworkRocketItem.translateExplosionToBedrock((CompoundTag) explosion, "FireworksItem"); - tag.put(newExplosion); - Tag color = ((CompoundTag) explosion).get("Colors"); - if (color instanceof IntArrayTag) { + Fireworks.FireworkExplosion explosion = components.get(DataComponentType.FIREWORK_EXPLOSION); + if (explosion != null) { + NbtMap newExplosion = FireworkRocketItem.translateExplosionToBedrock(explosion); + builder.putCompound("FireworksItem", newExplosion); + int[] colors = explosion.getColors(); + if (colors.length != 0) { // Determine the custom color, if any. // Mostly replicates Java's own rendering code, as Java determines the final firework star color client-side // while Bedrock determines it server-side. - int[] colors = ((IntArrayTag) color).getValue(); - if (colors.length == 0) { - return; - } int finalColor; if (colors.length == 1) { finalColor = colors[0]; @@ -77,7 +74,7 @@ public class FireworkStarItem extends Item { finalColor = r << 16 | g << 8 | b; } - tag.put(new IntTag("customColor", finalColor)); + builder.putInt("customColor", finalColor); } } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java index 4538689da..743928482 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java @@ -26,8 +26,6 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.opennbt.tag.builtin.IntTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; @@ -42,11 +40,7 @@ public class FishingRodItem extends Item { super.translateComponentsToBedrock(session, components, builder); // Fix damage inconsistency - Tag damage = tag.get("Damage"); - if (damage instanceof IntTag) { - int originalDurability = ((IntTag) damage).getValue(); - tag.put(new IntTag("Damage", getBedrockDamage(originalDurability))); - } + builder.getDamage().ifPresent(damage -> builder.setDamage(getBedrockDamage(damage))); } public static int getBedrockDamage(int javaDamage) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java index 60b201961..20f9782df 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java @@ -26,6 +26,9 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; +import com.github.steveice10.mc.protocol.data.game.item.component.Instrument; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; @@ -52,10 +55,14 @@ public class GoatHornItem extends Item { } @Override - public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) { - ItemData.Builder builder = super.translateToBedrock(itemStack, mapping, mappings); - if (itemStack.getNbt() != null && itemStack.getNbt().get("instrument") instanceof StringTag instrumentTag) { - String instrument = instrumentTag.getValue(); + public ItemData.Builder translateToBedrock(int count, DataComponents components, ItemMapping mapping, ItemMappings mappings) { + ItemData.Builder builder = super.translateToBedrock(count, components, mapping, mappings); + if (components == null) { + return builder; + } + Instrument instrument = components.get(DataComponentType.INSTRUMENT); + // TODO registry + if (instrument != null) { // Drop the Minecraft namespace if applicable if (instrument.startsWith("minecraft:")) { instrument = instrument.substring("minecraft:".length()); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/Item.java b/core/src/main/java/org/geysermc/geyser/item/type/Item.java index decc60da8..e2822ea7a 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/Item.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/Item.java @@ -39,6 +39,7 @@ import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.item.Enchantment; +import org.geysermc.geyser.item.Items; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.session.GeyserSession; @@ -93,20 +94,16 @@ public class Item { /* Translation methods to Bedrock and back */ - public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) { - if (InventoryUtils.isEmpty(itemStack)) { + public ItemData.Builder translateToBedrock(int count, DataComponents components, ItemMapping mapping, ItemMappings mappings) { + if (this == Items.AIR || count <= 0) { // Return, essentially, air return ItemData.builder(); } ItemData.Builder builder = ItemData.builder() .definition(mapping.getBedrockDefinition()) .damage(mapping.getBedrockData()) - .count(itemStack.getAmount()); - if (itemStack.getDataComponents() != null) { - builder.tag(ItemTranslator.translateNbtToBedrock(itemStack.getDataComponents())); - } + .count(count); - DataComponents components = itemStack.getDataComponents(); ItemTranslator.translateCustomItem(components, builder, mapping); return builder; @@ -135,6 +132,11 @@ public class Item { } } + Integer damage = components.get(DataComponentType.DAMAGE); + if (damage != null) { + builder.setDamage(damage); + } + List newTags = new ArrayList<>(); ItemEnchantments enchantments = components.get(DataComponentType.ENCHANTMENTS); if (enchantments != null) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java b/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java index b015862c5..72014e15e 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.*; import org.checkerframework.checker.nullness.qual.NonNull; @@ -41,14 +42,14 @@ public class MapItem extends Item { public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - Tag mapId = tag.remove("map"); - if (mapId == null || !(mapId.getValue() instanceof Number number)) return; + Integer mapValue = components.get(DataComponentType.MAP_ID); + if (mapValue == null) { + return; + } - int mapValue = number.intValue(); - - tag.put(new LongTag("map_uuid", mapValue)); - tag.put(new IntTag("map_name_index", mapValue)); - tag.put(new ByteTag("map_display_players", (byte) 1)); + builder.putLong("map_uuid", mapValue); + builder.putInt("map_name_index", mapValue); + builder.putByte("map_display_players", (byte) 1); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java index dae444775..82219d7d9 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java @@ -25,16 +25,14 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.auth.data.GameProfile; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.item.BedrockItemBuilder; -import org.geysermc.geyser.translator.text.MessageTranslator; public class PlayerHeadItem extends Item { public PlayerHeadItem(String javaIdentifier, Builder builder) { @@ -45,35 +43,24 @@ public class PlayerHeadItem extends Item { public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - CompoundTag displayTag; - if (tag.get("display") instanceof CompoundTag existingDisplayTag) { - displayTag = existingDisplayTag; - } else { - displayTag = new CompoundTag("display"); - tag.put(displayTag); - } - - if (displayTag.get("Name") instanceof StringTag nameTag) { - // Custom names are always yellow and italic - displayTag.put(new StringTag("Name", ChatColor.YELLOW + ChatColor.ITALIC + MessageTranslator.convertMessageLenient(nameTag.getValue(), session.locale()))); - } else { - if (tag.contains("SkullOwner")) { - StringTag name; - Tag skullOwner = tag.get("SkullOwner"); - if (skullOwner instanceof StringTag skullName) { - name = skullName; + // TODO verify + // Also - ChatColor.YELLOW + ChatColor.ITALIC + MessageTranslator.convertMessageLenient(nameTag.getValue(), session.locale())) this code existed if a custom name was already present. + // But I think we would always overwrite that because translateDisplayProperties runs after this method. + String customName = builder.getCustomName(); + if (customName == null) { + GameProfile profile = components.get(DataComponentType.PROFILE); + if (profile != null) { + String name = profile.getName(); + if (name != null) { + // Add correct name of player skull + String displayName = ChatColor.RESET + ChatColor.YELLOW + + MinecraftLocale.getLocaleString("block.minecraft.player_head.named", session.locale()).replace("%s", name); + builder.setCustomName(displayName); } else { - if (skullOwner instanceof CompoundTag && ((CompoundTag) skullOwner).get("Name") instanceof StringTag skullName) { - name = skullName; - } else { - // No name found so default to "Player Head" - displayTag.put(new StringTag("Name", ChatColor.RESET + ChatColor.YELLOW + MinecraftLocale.getLocaleString("block.minecraft.player_head", session.locale()))); - return; - } + // No name found so default to "Player Head" + builder.setCustomName(ChatColor.RESET + ChatColor.YELLOW + + MinecraftLocale.getLocaleString("block.minecraft.player_head", session.locale())); } - // Add correct name of player skull - String displayName = ChatColor.RESET + ChatColor.YELLOW + MinecraftLocale.getLocaleString("block.minecraft.player_head.named", session.locale()).replace("%s", name.getValue()); - displayTag.put(new StringTag("Name", displayName)); } } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java index bed2945ba..6aac28c05 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java @@ -27,9 +27,9 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.item.component.PotionContents; import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; @@ -46,29 +46,27 @@ public class PotionItem extends Item { } @Override - public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) { - if (itemStack.getDataComponents() == null) return super.translateToBedrock(itemStack, mapping, mappings); - PotionContents potionContents = itemStack.getDataComponents().get(DataComponentType.POTION_CONTENTS); + public ItemData.Builder translateToBedrock(int count, DataComponents components, ItemMapping mapping, ItemMappings mappings) { + if (components == null) return super.translateToBedrock(count, components, mapping, mappings); + PotionContents potionContents = components.get(DataComponentType.POTION_CONTENTS); if (potionContents != null) { - ItemDefinition customItemDefinition = CustomItemTranslator.getCustomItem(itemStack.getDataComponents(), mapping); + ItemDefinition customItemDefinition = CustomItemTranslator.getCustomItem(components, mapping); if (customItemDefinition == null) { Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue()); if (potion != null) { return ItemData.builder() .definition(mapping.getBedrockDefinition()) .damage(potion.getBedrockId()) - .count(itemStack.getAmount()) - .tag(ItemTranslator.translateNbtToBedrock(itemStack.getNbt())); + .count(count); } GeyserImpl.getInstance().getLogger().debug("Unknown Java potion: " + potionTag.getValue()); } else { return ItemData.builder() .definition(customItemDefinition) - .count(itemStack.getAmount()) - .tag(ItemTranslator.translateNbtToBedrock(itemStack.getNbt())); + .count(count); } } - return super.translateToBedrock(itemStack, mapping, mappings); + return super.translateToBedrock(count, components, mapping, mappings); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java index 395563fe3..267946442 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java @@ -83,7 +83,7 @@ public class ShulkerBoxItem extends BlockItem { itemsList.add(boxItemNbt.build()); } - builder.getOrCreateNbt().putList("Items", NbtType.COMPOUND, itemsList); + builder.putList("Items", NbtType.COMPOUND, itemsList); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java index fcf562ba5..e4bad2f32 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; @@ -41,7 +41,7 @@ public class TippedArrowItem extends ArrowItem { } @Override - public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) { + public ItemData.Builder translateToBedrock(int count, DataComponents components, ItemMapping mapping, ItemMappings mappings) { Tag potionTag = itemStack.getNbt().get("Potion"); if (potionTag instanceof StringTag) { TippedArrowPotion tippedArrowPotion = TippedArrowPotion.getByJavaIdentifier(((StringTag) potionTag).getValue()); @@ -49,11 +49,10 @@ public class TippedArrowItem extends ArrowItem { return ItemData.builder() .definition(mapping.getBedrockDefinition()) .damage(tippedArrowPotion.getBedrockId()) - .count(itemStack.getAmount()) - .tag(ItemTranslator.translateNbtToBedrock(itemStack.getNbt())); + .count(count); } GeyserImpl.getInstance().getLogger().debug("Unknown Java potion (tipped arrow): " + potionTag.getValue()); } - return super.translateToBedrock(itemStack, mapping, mappings); + return super.translateToBedrock(count, components, mapping, mappings); } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java index 3ece87745..c0407e697 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.*; import net.kyori.adventure.text.Component; @@ -53,10 +54,10 @@ public class TropicalFishBucketItem extends Item { super.translateComponentsToBedrock(session, components, builder); // Prevent name from appearing as "Bucket of" - tag.put(new ByteTag("AppendCustomName", (byte) 1)); - tag.put(new StringTag("CustomName", MinecraftLocale.getLocaleString("entity.minecraft.tropical_fish", session.locale()))); + builder.putByte("AppendCustomName", (byte) 1); + builder.putString("CustomName", MinecraftLocale.getLocaleString("entity.minecraft.tropical_fish", session.locale())); // Add Java's client side lore tag - Tag bucketVariantTag = tag.get("BucketVariantTag"); + components.get(DataComponentType) if (bucketVariantTag instanceof IntTag) { CompoundTag displayTag = tag.get("display"); if (displayTag == null) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java index 68cdf99d4..d925d2b8a 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java @@ -25,12 +25,18 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; +import com.github.steveice10.mc.protocol.data.game.item.component.Filterable; +import com.github.steveice10.mc.protocol.data.game.item.component.WritableBookContent; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; @@ -48,22 +54,20 @@ public class WritableBookItem extends Item { public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - ListTag pagesTag = tag.remove("pages"); - if (pagesTag == null) { + WritableBookContent bookContent = components.get(DataComponentType.WRITABLE_BOOK_CONTENT); + if (bookContent == null) { return; } - List pages = new ArrayList<>(); - for (Tag subTag : pagesTag.getValue()) { - if (!(subTag instanceof StringTag textTag)) - continue; - CompoundTag pageTag = new CompoundTag(""); - pageTag.put(new StringTag("photoname", "")); - pageTag.put(new StringTag("text", MessageTranslator.convertMessageLenient(textTag.getValue()))); - pages.add(pageTag); + List bedrockPages = new ArrayList<>(); + for (Filterable page : bookContent.getPages()) { + NbtMapBuilder pageBuilder = NbtMap.builder(); + pageBuilder.putString("photoname", ""); + pageBuilder.putString("text", MessageTranslator.convertMessageLenient(page.getRaw())); + bedrockPages.add(pageBuilder.build()); } - tag.put(new ListTag("pages", pages)); + builder.putList("pages", NbtType.COMPOUND, bedrockPages); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java index ae6b81f6e..6ca52aca4 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java @@ -25,21 +25,27 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; +import com.github.steveice10.mc.protocol.data.game.item.component.Filterable; +import com.github.steveice10.mc.protocol.data.game.item.component.WrittenBookContent; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.text.MessageTranslator; +import java.util.ArrayList; import java.util.List; -public class WrittenBookItem extends WritableBookItem { +public class WrittenBookItem extends Item { public static final int MAXIMUM_PAGE_EDIT_LENGTH = 1024; public static final int MAXIMUM_PAGE_LENGTH = 32768; public static final int MAXIMUM_PAGE_COUNT = 100; // Java edition limit. Bedrock edition has a limit of 50 pages. @@ -51,25 +57,24 @@ public class WrittenBookItem extends WritableBookItem { @Override public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { - boolean isValid = isValidWrittenBook(tag); - if (!isValid) { - tag.remove("pages"); - } - super.translateComponentsToBedrock(session, components, builder); - if (!isValid) { - CompoundTag invalidTagPage = new CompoundTag(""); - invalidTagPage.put(new StringTag("photoname", "")); - invalidTagPage.put(new StringTag( - "text", - MessageTranslator.convertMessage( - Component.translatable("book.invalid.tag", NamedTextColor.DARK_RED), - session.locale() - ) - )); - tag.put(new ListTag("pages", List.of(invalidTagPage))); + WrittenBookContent bookContent = components.get(DataComponentType.WRITTEN_BOOK_CONTENT); + if (bookContent == null) { + return; } + List bedrockPages = new ArrayList<>(); + for (Filterable page : bookContent.getPages()) { + NbtMapBuilder pageBuilder = NbtMap.builder(); + pageBuilder.putString("photoname", ""); + pageBuilder.putString("text", MessageTranslator.convertMessage(page.getRaw())); + bedrockPages.add(pageBuilder.build()); + } + builder.putList("pages", NbtType.COMPOUND, bedrockPages); + + builder.putString("title", bookContent.getTitle().getRaw()) + .putString("author", bookContent.getAuthor()); + // TODO isResolved } private boolean isValidWrittenBook(CompoundTag tag) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java b/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java index 83293d4ee..c1f7184f2 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java @@ -34,6 +34,7 @@ import org.geysermc.geyser.registry.type.ItemMapping; import java.util.ArrayList; import java.util.List; +import java.util.OptionalInt; /** * An intermediary class made to allow easy access to work-in-progress NBT, such as lore and display. @@ -44,12 +45,18 @@ public final class BedrockItemBuilder { private String customName; @Nullable private List lore; + private OptionalInt damage = OptionalInt.empty(); /** * Miscellaneous NBT that will be put into the final item. */ @Nullable private NbtMapBuilder builder; + @Nullable + public String getCustomName() { + return customName; + } + public BedrockItemBuilder setCustomName(String customName) { this.customName = customName; return this; @@ -63,6 +70,15 @@ public final class BedrockItemBuilder { return lore; } + public OptionalInt getDamage() { + return damage; + } + + public BedrockItemBuilder setDamage(int damage) { + this.damage = OptionalInt.of(damage); + return this; + } + @NonNull public NbtMapBuilder getOrCreateNbt() { if (builder == null) { @@ -85,6 +101,14 @@ public final class BedrockItemBuilder { return getOrCreateNbt().putInt(name, value); } + public NbtMapBuilder putList(String name, NbtType type, List value) { + return getOrCreateNbt().putList(name, type, value); + } + + public NbtMapBuilder putLong(String name, long value) { + return getOrCreateNbt().putLong(name, value); + } + public NbtMapBuilder putString(String name, String value) { return getOrCreateNbt().putString(name, value); } @@ -108,6 +132,9 @@ public final class BedrockItemBuilder { } getOrCreateNbt().put("display", display.build()); } + if (damage.isPresent()) { + getOrCreateNbt().putInt("Damage", damage.getAsInt()); + } if (builder == null) { return null; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index 6459aa9ec..65ceb3497 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -161,9 +161,9 @@ public final class ItemTranslator { addAdvancedTooltips(components, nbtBuilder, javaItem, session.locale()); } - ItemStack itemStack = new ItemStack(javaItem.javaId(), count, components); - - ItemData.Builder builder = javaItem.translateToBedrock(itemStack, bedrockItem, session.getItemMappings()); + ItemData.Builder builder = javaItem.translateToBedrock(count, components, bedrockItem, session.getItemMappings()); + // Finalize the Bedrock NBT + builder.tag(nbtBuilder.build()); if (bedrockItem.isBlock()) { CustomBlockData customBlockData = BlockRegistries.CUSTOM_BLOCK_ITEM_OVERRIDES.getOrDefault( bedrockItem.getJavaItem().javaIdentifier(), null); From 94e533ea7ce5d87e8cbcf23a3f3d8b66bc633448 Mon Sep 17 00:00:00 2001 From: basaigh <53559772+basaigh@users.noreply.github.com> Date: Sun, 21 Apr 2024 01:33:07 +0100 Subject: [PATCH 074/272] Fix tags and attributes --- .../org/geysermc/geyser/entity/type/LivingEntity.java | 2 +- .../entity/type/living/animal/AxolotlEntity.java | 2 +- .../org/geysermc/geyser/session/GeyserSession.java | 2 +- .../org/geysermc/geyser/session/cache/TagCache.java | 10 +++++----- gradle/libs.versions.toml | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java index 245b99cef..b070bdfff 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java @@ -299,7 +299,7 @@ public class LivingEntity extends Entity { case GENERIC_MOVEMENT_SPEED -> newAttributes.add(calculateAttribute(javaAttribute, GeyserAttributeType.MOVEMENT_SPEED)); case GENERIC_FOLLOW_RANGE -> newAttributes.add(calculateAttribute(javaAttribute, GeyserAttributeType.FOLLOW_RANGE)); case GENERIC_KNOCKBACK_RESISTANCE -> newAttributes.add(calculateAttribute(javaAttribute, GeyserAttributeType.KNOCKBACK_RESISTANCE)); - case HORSE_JUMP_STRENGTH -> newAttributes.add(calculateAttribute(javaAttribute, GeyserAttributeType.HORSE_JUMP_STRENGTH)); + case GENERIC_JUMP_STRENGTH -> newAttributes.add(calculateAttribute(javaAttribute, GeyserAttributeType.HORSE_JUMP_STRENGTH)); } } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java index 85b2afc14..97753f63f 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java @@ -61,7 +61,7 @@ public class AxolotlEntity extends AnimalEntity { @Override public boolean canEat(Item item) { - return session.getTagCache().isAxolotlTemptItem(item); + return session.getTagCache().isAxolotlFood(item); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 936fc932d..8e1ed2e51 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -368,7 +368,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { /** * All dimensions that the client could possibly connect to. */ - private final Map dimensions = new Object2ObjectOpenHashMap<>(3); + private final Int2ObjectMap dimensions = new Int2ObjectOpenHashMap<>(4); private final Int2ObjectMap chatTypes = new Int2ObjectOpenHashMap<>(7); diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java index 5acfc1f09..57000bf8b 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java @@ -58,7 +58,7 @@ public class TagCache { private IntList requiresDiamondTool; /* Items */ - private IntList axolotlTemptItems; + private IntList axolotlFood; private IntList creeperIgniters; private IntList fishes; private IntList flowers; @@ -96,7 +96,7 @@ public class TagCache { } Map itemTags = packet.getTags().get("minecraft:item"); - this.axolotlTemptItems = IntList.of(itemTags.get("minecraft:axolotl_tempt_items")); + this.axolotlFood = IntList.of(itemTags.get("minecraft:axolotl_food")); this.creeperIgniters = load(itemTags.get("minecraft:creeper_igniters")); this.fishes = IntList.of(itemTags.get("minecraft:fishes")); this.flowers = IntList.of(itemTags.get("minecraft:flowers")); @@ -133,7 +133,7 @@ public class TagCache { this.requiresIronTool = IntLists.emptyList(); this.requiresDiamondTool = IntLists.emptyList(); - this.axolotlTemptItems = IntLists.emptyList(); + this.axolotlFood = IntLists.emptyList(); this.creeperIgniters = IntLists.emptyList(); this.fishes = IntLists.emptyList(); this.flowers = IntLists.emptyList(); @@ -143,8 +143,8 @@ public class TagCache { this.snifferFood = IntLists.emptyList(); } - public boolean isAxolotlTemptItem(Item item) { - return axolotlTemptItems.contains(item.javaId()); + public boolean isAxolotlFood(Item item) { + return axolotlFood.contains(item.javaId()); } public boolean isCreeperIgniter(Item item) { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e9fadb577..08c04a84a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "b2e93c520a" # Revert from jitpack after release +mcprotocollib = "897eb241b6" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From 8bd2df0828a581de8019e4e08aeb46a46458296f Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 20 Apr 2024 22:42:25 -0400 Subject: [PATCH 075/272] Trying to get more compiled but brain is officially fried for the day! --- .../geyser/entity/type/FireworkEntity.java | 92 ++----------------- .../entity/type/ThrownPotionEntity.java | 16 ++-- .../inventory/item/TippedArrowPotion.java | 5 + .../geysermc/geyser/item/type/ArrowItem.java | 4 +- .../geysermc/geyser/item/type/BannerItem.java | 35 +++---- .../geyser/item/type/DecoratedPotItem.java | 2 +- .../geyser/item/type/EnchantedBookItem.java | 25 ++--- .../geyser/item/type/GoatHornItem.java | 22 ++--- .../org/geysermc/geyser/item/type/Item.java | 70 +++++--------- .../geysermc/geyser/item/type/PotionItem.java | 7 +- .../geysermc/geyser/item/type/ShieldItem.java | 35 ++++--- .../geyser/item/type/TippedArrowItem.java | 13 ++- .../item/type/TropicalFishBucketItem.java | 34 +++---- .../geyser/session/cache/LodestoneCache.java | 52 ++++++----- .../inventory/LoomInventoryTranslator.java | 7 +- .../translator/item/BedrockItemBuilder.java | 5 +- .../translator/item/ItemTranslator.java | 55 +++++------ .../bedrock/BedrockBookEditTranslator.java | 12 +-- .../entity/JavaSetEquipmentTranslator.java | 20 ++-- .../geysermc/geyser/util/InventoryUtils.java | 13 +-- 20 files changed, 210 insertions(+), 314 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java index 171849ce5..04317e6d6 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java @@ -27,24 +27,16 @@ package org.geysermc.geyser.entity.type; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.cloudburstmc.math.vector.Vector3f; -import org.cloudburstmc.nbt.NbtMap; -import org.cloudburstmc.nbt.NbtMapBuilder; -import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.packet.SetEntityMotionPacket; -import org.geysermc.floodgate.util.DeviceOs; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.player.PlayerEntity; -import org.geysermc.geyser.level.FireworkColor; +import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.util.MathUtils; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; -import java.util.ArrayList; -import java.util.List; import java.util.OptionalInt; import java.util.UUID; @@ -59,80 +51,16 @@ public class FireworkEntity extends Entity { if (item == null) { return; } - CompoundTag tag = item.getNbt(); - - if (tag == null) { + DataComponents components = item.getDataComponents(); + if (components == null) { return; } - // TODO: Remove once Mojang fixes bugs with fireworks crashing clients on these specific devices. - // https://bugs.mojang.com/browse/MCPE-89115 - if (session.getClientData().getDeviceOs() == DeviceOs.XBOX - || session.getClientData().getDeviceOs() == DeviceOs.PS4) { - return; - } - - CompoundTag fireworks = tag.get("Fireworks"); - if (fireworks == null) { - // Thank you Mineplex very cool - return; - } - - NbtMapBuilder fireworksBuilder = NbtMap.builder(); - if (fireworks.get("Flight") != null) { - fireworksBuilder.putByte("Flight", MathUtils.getNbtByte(fireworks.get("Flight").getValue())); - } - - List explosions = new ArrayList<>(); - if (fireworks.get("Explosions") != null) { - for (Tag effect : ((ListTag) fireworks.get("Explosions")).getValue()) { - CompoundTag effectData = (CompoundTag) effect; - NbtMapBuilder effectBuilder = NbtMap.builder(); - - if (effectData.get("Type") != null) { - effectBuilder.putByte("FireworkType", MathUtils.getNbtByte(effectData.get("Type").getValue())); - } - - if (effectData.get("Colors") != null) { - int[] oldColors = (int[]) effectData.get("Colors").getValue(); - byte[] colors = new byte[oldColors.length]; - - int i = 0; - for (int color : oldColors) { - colors[i++] = FireworkColor.fromJavaRGB(color); - } - - effectBuilder.putByteArray("FireworkColor", colors); - } - - if (effectData.get("FadeColors") != null) { - int[] oldColors = (int[]) effectData.get("FadeColors").getValue(); - byte[] colors = new byte[oldColors.length]; - - int i = 0; - for (int color : oldColors) { - colors[i++] = FireworkColor.fromJavaRGB(color); - } - - effectBuilder.putByteArray("FireworkFade", colors); - } - - if (effectData.get("Trail") != null) { - effectBuilder.putByte("FireworkTrail", MathUtils.getNbtByte(effectData.get("Trail").getValue())); - } - - if (effectData.get("Flicker") != null) { - effectBuilder.putByte("FireworkFlicker", MathUtils.getNbtByte(effectData.get("Flicker").getValue())); - } - - explosions.add(effectBuilder.build()); - } - } - - fireworksBuilder.putList("Explosions", NbtType.COMPOUND, explosions); - - NbtMapBuilder builder = NbtMap.builder(); - builder.put("Fireworks", fireworksBuilder.build()); + // TODO this looked the same, so I'm going to assume it is and (keep below comment if true) + // Translate using item methods to get firework NBT for Bedrock + BedrockItemBuilder builder = new BedrockItemBuilder(); + Items.FIREWORK_ROCKET.translateComponentsToBedrock(session, components, builder); + dirtyMetadata.put(EntityDataTypes.DISPLAY_FIREWORK, builder.build()); } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java index cea371963..31428477a 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java @@ -27,8 +27,9 @@ package org.geysermc.geyser.entity.type; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; +import com.github.steveice10.mc.protocol.data.game.item.component.PotionContents; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -58,16 +59,17 @@ public class ThrownPotionEntity extends ThrowableItemEntity { setFlag(EntityFlag.LINGERING, false); } else { // As of Java 1.19.3, the server/client doesn't seem to care of the item is actually a potion? - if (itemStack.getNbt() != null) { - Tag potionTag = itemStack.getNbt().get("Potion"); - if (potionTag instanceof StringTag) { - Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue()); + DataComponents components = itemStack.getDataComponents(); + if (components != null) { + PotionContents potionContents = components.get(DataComponentType.POTION_CONTENTS); + if (potionContents != null) { + Potion potion = Potion.VALUES[potionContents.getPotionId()]; if (potion != null) { dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, (int) potion.getBedrockId()); setFlag(EntityFlag.ENCHANTED, !NON_ENCHANTED_POTIONS.contains(potion)); } else { dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, 0); - GeyserImpl.getInstance().getLogger().debug("Unknown java potion: " + potionTag.getValue()); + GeyserImpl.getInstance().getLogger().debug("Unknown java potion: " + potionContents.getPotionId()); } } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java b/core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java index 3ba0ad56f..5c33fec67 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java @@ -36,6 +36,7 @@ import java.util.Locale; */ @Getter public enum TippedArrowPotion { + WATER(-1, ArrowParticleColors.NONE), // Guessing this based off of the Potion enum. TODO merge? MUNDANE(2, ArrowParticleColors.NONE), // 3 is extended? THICK(4, ArrowParticleColors.NONE), AWKWARD(5, ArrowParticleColors.NONE), @@ -94,6 +95,10 @@ public enum TippedArrowPotion { this.javaColor = arrowParticleColor.getColor(); } + public static TippedArrowPotion of(int id) { + return VALUES[id]; + } + public static @Nullable TippedArrowPotion getByJavaIdentifier(String javaIdentifier) { for (TippedArrowPotion potion : VALUES) { if (potion.javaIdentifier.equals(javaIdentifier)) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java index cf66b036b..16d5fd482 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java @@ -26,8 +26,6 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.PotionContents; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; @@ -48,7 +46,7 @@ public class ArrowItem extends Item { if (tippedArrowPotion != null) { itemStack = Items.TIPPED_ARROW.newItemStack(itemStack.getAmount(), itemStack.getDataComponents()); StringTag potionTag = new StringTag("Potion", tippedArrowPotion.getJavaIdentifier()); - itemStack.getDataComponents().put(DataComponentType.POTION_CONTENTS, new PotionContents()); + //itemStack.getDataComponents().put(DataComponentType.POTION_CONTENTS, new PotionContents()); } return itemStack; } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index 549809391..32806c3c2 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -56,14 +56,14 @@ public class BannerItem extends BlockItem { static { // Construct what an ominous banner is supposed to look like OMINOUS_BANNER_PATTERN = List.of( - new BannerPatternLayer("mr", 9), - new BannerPatternLayer("bs", 8), - new BannerPatternLayer("cs", 7), - new BannerPatternLayer("bo", 8), - new BannerPatternLayer("ms", 15), - new BannerPatternLayer("hh", 8), - new BannerPatternLayer("mc", 8), - new BannerPatternLayer("bo", 15) +// new BannerPatternLayer("mr", 9), +// new BannerPatternLayer("bs", 8), +// new BannerPatternLayer("cs", 7), +// new BannerPatternLayer("bo", 8), +// new BannerPatternLayer("ms", 15), +// new BannerPatternLayer("hh", 8), +// new BannerPatternLayer("mc", 8), +// new BannerPatternLayer("bo", 15) ); } @@ -103,7 +103,8 @@ public class BannerItem extends BlockItem { * @return The Java edition format pattern nbt */ public static CompoundTag getJavaBannerPattern(NbtMap pattern) { - return new BannerPatternLayer(pattern.getString("Pattern"), 15 - pattern.getInt("Color")); + //return new BannerPatternLayer(0/*pattern.getString("Pattern")*/, 15 - pattern.getInt("Color")); + return null; } /** @@ -128,13 +129,13 @@ public class BannerItem extends BlockItem { List patterns = components.get(DataComponentType.BANNER_PATTERNS); if (patterns != null) { - if (patterns.equals(OMINOUS_BANNER_PATTERN)) { - // Remove the current patterns and set the ominous banner type - builder.putInt("Type", 1); - } else { - invertBannerColors(patterns); - tag.put(patterns); - } +// if (patterns.equals(OMINOUS_BANNER_PATTERN)) { +// // Remove the current patterns and set the ominous banner type +// builder.putInt("Type", 1); +// } else { +// invertBannerColors(patterns); +// tag.put(patterns); +// } } } @@ -146,7 +147,7 @@ public class BannerItem extends BlockItem { // Ominous banner pattern tag.remove("Type"); CompoundTag blockEntityTag = new CompoundTag("BlockEntityTag"); - blockEntityTag.put(OMINOUS_BANNER_PATTERN); + //blockEntityTag.put(OMINOUS_BANNER_PATTERN); tag.put(blockEntityTag); } else if (tag.get("Patterns") instanceof ListTag patterns) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java index 792ec0f0b..8d9be4db2 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java @@ -41,7 +41,7 @@ public class DecoratedPotItem extends BlockItem { public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - components.get(DataComponentType.POT_DECORATIONS); // TODO + components.get(DataComponentType.POT_DECORATIONS); // TODO what does this look like on Bedrock? // if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) { // if (blockEntityTag.remove("sherds") instanceof ListTag sherds) { // // bedrock wants it on the root level diff --git a/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java index 3851813ae..095537a09 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java @@ -25,16 +25,18 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import com.github.steveice10.mc.protocol.data.game.item.component.ItemEnchantments; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import java.util.ArrayList; import java.util.List; +import java.util.Map; public class EnchantedBookItem extends Item { public EnchantedBookItem(String javaIdentifier, Builder builder) { @@ -45,20 +47,19 @@ public class EnchantedBookItem extends Item { public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - List newTags = new ArrayList<>(); - Tag enchantmentTag = tag.remove("StoredEnchantments"); - if (enchantmentTag instanceof ListTag listTag) { - for (Tag subTag : listTag.getValue()) { - if (!(subTag instanceof CompoundTag)) continue; - CompoundTag bedrockTag = remapEnchantment(session, (CompoundTag) subTag, tag); + List bedrockEnchants = new ArrayList<>(); + ItemEnchantments enchantments = components.get(DataComponentType.STORED_ENCHANTMENTS); + if (enchantments != null) { // TODO don't duplicate code? + for (Map.Entry enchantment : enchantments.getEnchantments().entrySet()) { + NbtMap bedrockTag = remapEnchantment(session, enchantment.getKey(), enchantment.getValue(), builder); if (bedrockTag != null) { - newTags.add(bedrockTag); + bedrockEnchants.add(bedrockTag); } } } - if (!newTags.isEmpty()) { - tag.put(new ListTag("ench", newTags)); + if (!bedrockEnchants.isEmpty()) { + builder.putList("ench", NbtType.COMPOUND, bedrockEnchants); } } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java index 20f9782df..48e75dc79 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java @@ -64,16 +64,16 @@ public class GoatHornItem extends Item { // TODO registry if (instrument != null) { // Drop the Minecraft namespace if applicable - if (instrument.startsWith("minecraft:")) { - instrument = instrument.substring("minecraft:".length()); - } - - int damage = INSTRUMENTS.indexOf(instrument); - if (damage == -1) { - damage = 0; - GeyserImpl.getInstance().getLogger().debug("Unknown goat horn instrument: " + instrumentTag.getValue()); - } - builder.damage(damage); +// if (instrument.startsWith("minecraft:")) { +// instrument = instrument.substring("minecraft:".length()); +// } +// +// int damage = INSTRUMENTS.indexOf(instrument); +// if (damage == -1) { +// damage = 0; +// GeyserImpl.getInstance().getLogger().debug("Unknown goat horn instrument: " + instrumentTag.getValue()); +// } +// builder.damage(damage); } return builder; } @@ -90,7 +90,7 @@ public class GoatHornItem extends Item { String instrument = INSTRUMENTS.get(damage); StringTag instrumentTag = new StringTag("instrument", "minecraft:" + instrument); - itemStack.getNbt().put(instrumentTag); + //itemStack.getNbt().put(instrumentTag); return itemStack; } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/Item.java b/core/src/main/java/org/geysermc/geyser/item/type/Item.java index e2822ea7a..2779768db 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/Item.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/Item.java @@ -27,15 +27,15 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.Identifier; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.item.component.ItemEnchantments; import com.github.steveice10.opennbt.tag.builtin.*; import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMap; -import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.item.Enchantment; @@ -48,7 +48,6 @@ import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.text.MessageTranslator; -import org.geysermc.geyser.util.InventoryUtils; import java.util.ArrayList; import java.util.List; @@ -113,7 +112,7 @@ public class Item { if (itemData.getTag() == null) { return new ItemStack(javaId, itemData.getCount(), null); } - return new ItemStack(javaId, itemData.getCount(), ItemTranslator.translateToJavaNBT("", itemData.getTag())); + return new ItemStack(javaId, itemData.getCount(), null/*ItemTranslator.translateToJavaNBT("", itemData.getTag())*/); } public ItemMapping toBedrockDefinition(DataComponents components, ItemMappings mappings) { @@ -137,23 +136,19 @@ public class Item { builder.setDamage(damage); } - List newTags = new ArrayList<>(); + List enchantNbtList = new ArrayList<>(); ItemEnchantments enchantments = components.get(DataComponentType.ENCHANTMENTS); if (enchantments != null) { - - } - if (enchantmentTag instanceof ListTag listTag) { - for (Tag subTag : listTag.getValue()) { - if (!(subTag instanceof CompoundTag)) continue; - CompoundTag bedrockTag = remapEnchantment(session, (CompoundTag) subTag, tag); - if (bedrockTag != null) { - newTags.add(bedrockTag); + for (Map.Entry enchantment : enchantments.getEnchantments().entrySet()) { + NbtMap enchantNbt = remapEnchantment(session, enchantment.getKey(), enchantment.getValue(), builder); + if (enchantNbt != null) { + enchantNbtList.add(enchantNbt); } } } - if (!newTags.isEmpty()) { - tag.put(new ListTag("ench", newTags)); + if (!enchantNbtList.isEmpty()) { + builder.putList("ench", NbtType.COMPOUND, enchantNbtList); } } @@ -220,45 +215,30 @@ public class Item { } } - protected final @Nullable NbtMap remapEnchantment(GeyserSession session, ItemEnchantments, NbtMapBuilder rootBuilder) { - - Enchantment enchantment = Enchantment.getByJavaIdentifier(((StringTag) javaEnchId).getValue()); + protected final @Nullable NbtMap remapEnchantment(GeyserSession session, int enchantId, int level, BedrockItemBuilder builder) { + // TODO verify + // TODO streamline Enchantment process + Enchantment.JavaEnchantment enchantment = Enchantment.JavaEnchantment.of(enchantId); + if (enchantment == Enchantment.JavaEnchantment.SWEEPING_EDGE) { + addSweeping(session, builder, level); + return null; + } if (enchantment == null) { - if (Identifier.formalize((String) javaEnchId.getValue()).equals("minecraft:sweeping")) { - Tag javaEnchLvl = tag.get("lvl"); - int sweepingLvl = javaEnchLvl != null && javaEnchLvl.getValue() instanceof Number lvl ? lvl.intValue() : 0; - - addSweeping(session, rootTag, sweepingLvl); - return null; - } - GeyserImpl.getInstance().getLogger().debug("Unknown Java enchantment while NBT item translating: " + javaEnchId.getValue()); + GeyserImpl.getInstance().getLogger().debug("Unknown Java enchantment while NBT item translating: " + enchantId); return null; } - Tag javaEnchLvl = tag.get("lvl"); - - NbtMapBuilder builder = NbtMap.builder(); - builder.putShort("id", (short) enchantment.ordinal()); - builder.putShort("lvl", ); - return builder.build(); + return NbtMap.builder() + .putShort("id", (short) Enchantment.valueOf(enchantment.name()).ordinal()) + .putShort("lvl", (short) level) + .build(); } - private void addSweeping(GeyserSession session, CompoundTag itemTag, int level) { - CompoundTag displayTag = itemTag.get("display"); - if (displayTag == null) { - displayTag = new CompoundTag("display"); - itemTag.put(displayTag); - } - ListTag loreTag = displayTag.get("Lore"); - if (loreTag == null) { - loreTag = new ListTag("Lore"); - displayTag.put(loreTag); - } - + private void addSweeping(GeyserSession session, BedrockItemBuilder builder, int level) { String sweepingTranslation = MinecraftLocale.getLocaleString("enchantment.minecraft.sweeping", session.locale()); String lvlTranslation = MinecraftLocale.getLocaleString("enchantment.level." + level, session.locale()); - loreTag.add(new StringTag("", ChatColor.RESET + ChatColor.GRAY + sweepingTranslation + " " + lvlTranslation)); + builder.getOrCreateLore().add(ChatColor.RESET + ChatColor.GRAY + sweepingTranslation + " " + lvlTranslation); } /* Translation methods end */ diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java index 6aac28c05..63b9240c0 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java @@ -38,7 +38,6 @@ import org.geysermc.geyser.inventory.item.Potion; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.translator.item.CustomItemTranslator; -import org.geysermc.geyser.translator.item.ItemTranslator; public class PotionItem extends Item { public PotionItem(String javaIdentifier, Builder builder) { @@ -52,14 +51,14 @@ public class PotionItem extends Item { if (potionContents != null) { ItemDefinition customItemDefinition = CustomItemTranslator.getCustomItem(components, mapping); if (customItemDefinition == null) { - Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue()); + Potion potion = Potion.VALUES[potionContents.getPotionId()]; if (potion != null) { return ItemData.builder() .definition(mapping.getBedrockDefinition()) .damage(potion.getBedrockId()) .count(count); } - GeyserImpl.getInstance().getLogger().debug("Unknown Java potion: " + potionTag.getValue()); + GeyserImpl.getInstance().getLogger().debug("Unknown Java potion: " + potionContents.getPotionId()); } else { return ItemData.builder() .definition(customItemDefinition) @@ -75,7 +74,7 @@ public class PotionItem extends Item { ItemStack itemStack = super.translateToJava(itemData, mapping, mappings); if (potion != null) { StringTag potionTag = new StringTag("Potion", potion.getJavaIdentifier()); - itemStack.getNbt().put(potionTag); + //itemStack.getNbt().put(potionTag); } return itemStack; } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java index 30b50b436..f495222f3 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java @@ -26,10 +26,6 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.IntTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.item.components.ToolTier; import org.geysermc.geyser.session.GeyserSession; @@ -44,21 +40,22 @@ public class ShieldItem extends Item { public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) { - if (blockEntityTag.get("Patterns") instanceof ListTag patterns) { - for (Tag pattern : patterns) { - if (((CompoundTag) pattern).get("Color") instanceof IntTag color) { - color.setValue(15 - color.getValue()); - } - } - // Bedrock looks for patterns at the root - tag.put(patterns); - } - if (blockEntityTag.get("Base") instanceof IntTag base) { - base.setValue(15 - base.getValue()); - tag.put(base); - } - } + // TODO figure out patterns first. +// if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) { +// if (blockEntityTag.get("Patterns") instanceof ListTag patterns) { +// for (Tag pattern : patterns) { +// if (((CompoundTag) pattern).get("Color") instanceof IntTag color) { +// color.setValue(15 - color.getValue()); +// } +// } +// // Bedrock looks for patterns at the root +// tag.put(patterns); +// } +// if (blockEntityTag.get("Base") instanceof IntTag base) { +// base.setValue(15 - base.getValue()); +// tag.put(base); +// } +// } } @Override diff --git a/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java index e4bad2f32..9074c2ec8 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java @@ -25,15 +25,14 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import com.github.steveice10.mc.protocol.data.game.item.component.PotionContents; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.item.TippedArrowPotion; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; -import org.geysermc.geyser.translator.item.ItemTranslator; public class TippedArrowItem extends ArrowItem { public TippedArrowItem(String javaIdentifier, Builder builder) { @@ -42,16 +41,16 @@ public class TippedArrowItem extends ArrowItem { @Override public ItemData.Builder translateToBedrock(int count, DataComponents components, ItemMapping mapping, ItemMappings mappings) { - Tag potionTag = itemStack.getNbt().get("Potion"); - if (potionTag instanceof StringTag) { - TippedArrowPotion tippedArrowPotion = TippedArrowPotion.getByJavaIdentifier(((StringTag) potionTag).getValue()); + PotionContents potionContents = components.get(DataComponentType.POTION_CONTENTS); + if (potionContents != null) { + TippedArrowPotion tippedArrowPotion = TippedArrowPotion.of(potionContents.getPotionId()); if (tippedArrowPotion != null) { return ItemData.builder() .definition(mapping.getBedrockDefinition()) .damage(tippedArrowPotion.getBedrockId()) .count(count); } - GeyserImpl.getInstance().getLogger().debug("Unknown Java potion (tipped arrow): " + potionTag.getValue()); + GeyserImpl.getInstance().getLogger().debug("Unknown Java potion (tipped arrow): " + potionContents.getPotionId()); } return super.translateToBedrock(count, components, mapping, mappings); } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java index c0407e697..f70e6b295 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java @@ -27,7 +27,8 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.opennbt.tag.builtin.*; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.Tag; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.Style; @@ -39,7 +40,6 @@ import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.text.MessageTranslator; -import java.util.ArrayList; import java.util.List; public class TropicalFishBucketItem extends Item { @@ -57,24 +57,24 @@ public class TropicalFishBucketItem extends Item { builder.putByte("AppendCustomName", (byte) 1); builder.putString("CustomName", MinecraftLocale.getLocaleString("entity.minecraft.tropical_fish", session.locale())); // Add Java's client side lore tag - components.get(DataComponentType) - if (bucketVariantTag instanceof IntTag) { - CompoundTag displayTag = tag.get("display"); - if (displayTag == null) { - displayTag = new CompoundTag("display"); - tag.put(displayTag); + // Do you know how frequently Java NBT used to be before 1.20.5? It was a lot. And now it's just this lowly check. + CompoundTag entityTag = components.get(DataComponentType.BUCKET_ENTITY_DATA); + if (entityTag != null && !entityTag.isEmpty()) { + //TODO test + Tag bucketVariant = entityTag.get("BucketVariantTag"); + if (bucketVariant == null || !(bucketVariant.getValue() instanceof Number)) { + return; } + List lore = builder.getOrCreateLore(); - List lore = new ArrayList<>(); - - int varNumber = ((IntTag) bucketVariantTag).getValue(); + int varNumber = ((Number) bucketVariant.getValue()).intValue(); int predefinedVariantId = TropicalFishEntity.getPredefinedId(varNumber); if (predefinedVariantId != -1) { Component tooltip = Component.translatable("entity.minecraft.tropical_fish.predefined." + predefinedVariantId, LORE_STYLE); - lore.add(0, new StringTag("", MessageTranslator.convertMessage(tooltip, session.locale()))); + lore.add(0, MessageTranslator.convertMessage(tooltip, session.locale())); } else { Component typeTooltip = Component.translatable("entity.minecraft.tropical_fish.type." + TropicalFishEntity.getVariantName(varNumber), LORE_STYLE); - lore.add(0, new StringTag("", MessageTranslator.convertMessage(typeTooltip, session.locale()))); + lore.add(0, MessageTranslator.convertMessage(typeTooltip, session.locale())); byte baseColor = TropicalFishEntity.getBaseColor(varNumber); byte patternColor = TropicalFishEntity.getPatternColor(varNumber); @@ -83,14 +83,8 @@ public class TropicalFishBucketItem extends Item { colorTooltip = colorTooltip.append(Component.text(", ", LORE_STYLE)) .append(Component.translatable("color.minecraft." + TropicalFishEntity.getColorName(patternColor), LORE_STYLE)); } - lore.add(1, new StringTag("", MessageTranslator.convertMessage(colorTooltip, session.locale()))); + lore.add(1, MessageTranslator.convertMessage(colorTooltip, session.locale())); } - - ListTag loreTag = displayTag.get("Lore"); - if (loreTag != null) { - lore.addAll(loreTag.getValue()); - } - displayTag.put(new ListTag("Lore", lore)); } } } diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java index 4bd2244ab..eced0e50b 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java @@ -25,13 +25,14 @@ package org.geysermc.geyser.session.cache; +import com.github.steveice10.mc.protocol.data.game.entity.metadata.GlobalPos; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.item.component.LodestoneTracker; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.IntTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import org.checkerframework.checker.nullness.qual.Nullable; +import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.GeyserItemStack; import java.util.Map; @@ -54,22 +55,27 @@ public final class LodestoneCache { private int id = 1; public void cacheInventoryItem(GeyserItemStack itemStack) { - CompoundTag tag = itemStack.getNbt(); - if (tag == null) { + DataComponents components = itemStack.getComponents(); + if (components == null) { // invalid return; } - CompoundTag lodestonePos = tag.get("LodestonePos"); - if (lodestonePos == null) { - // invalid + LodestoneTracker tracker = components.get(DataComponentType.LODESTONE_TRACKER); + if (tracker == null) { return; } - // Get all info needed for tracking - int x = ((IntTag) lodestonePos.get("X")).getValue(); - int y = ((IntTag) lodestonePos.get("Y")).getValue(); - int z = ((IntTag) lodestonePos.get("Z")).getValue(); - String dim = ((StringTag) tag.get("LodestoneDimension")).getValue(); + GlobalPos position = tracker.getPos(); + + if (position == null) { + GeyserImpl.getInstance().getLogger().error("Position is null. Find out why."); + Thread.dumpStack(); + return; + } + int x = position.getX(); + int y = position.getY(); + int z = position.getZ(); + String dim = position.getDimension(); for (LodestonePos pos : this.activeLodestones.values()) { if (pos.equals(x, y, z, dim)) { @@ -90,17 +96,17 @@ public final class LodestoneCache { } public int store(LodestoneTracker tracker) { - CompoundTag lodestonePos = tag.get("LodestonePos"); - if (lodestonePos == null) { - // invalid - return 0; - } + GlobalPos position = tracker.getPos(); - // Get all info needed for tracking - int x = ((IntTag) lodestonePos.get("X")).getValue(); - int y = ((IntTag) lodestonePos.get("Y")).getValue(); - int z = ((IntTag) lodestonePos.get("Z")).getValue(); - String dim = ((StringTag) tag.get("LodestoneDimension")).getValue(); + if (position == null) { + GeyserImpl.getInstance().getLogger().error("Position is null. Find out why."); + Thread.dumpStack(); + return -1; + } + int x = position.getX(); + int y = position.getY(); + int z = position.getZ(); + String dim = position.getDimension(); for (LodestonePos pos : this.activeLodestones.values()) { if (pos.equals(x, y, z, dim)) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java index 0e43ba660..6c7a11ff2 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.translator.inventory; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; @@ -51,6 +52,7 @@ import org.geysermc.geyser.item.type.DyeItem; import org.geysermc.geyser.session.GeyserSession; import java.util.Collections; +import java.util.HashMap; import java.util.List; public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator { @@ -154,9 +156,10 @@ public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator { GeyserItemStack inputCopy = inventory.getItem(0).copy(1); inputCopy.setNetId(session.getNextItemNetId()); // Add the pattern manually, for better item synchronization - if (inputCopy.getNbt() == null) { - inputCopy.setNbt(new CompoundTag("")); + if (inputCopy.getComponents() == null) { + inputCopy.setComponents(new DataComponents(new HashMap<>())); } + //TODO CompoundTag blockEntityTag = inputCopy.getNbt().get("BlockEntityTag"); CompoundTag javaBannerPattern = BannerItem.getJavaBannerPattern(pattern); diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java b/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java index c1f7184f2..52d5b7e31 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/BedrockItemBuilder.java @@ -142,13 +142,12 @@ public final class BedrockItemBuilder { } /** - * Creates item NBT with count, name, and damage set. + * Creates item NBT to nest within NBT with name, count, and damage set. */ public static NbtMapBuilder createItemNbt(ItemMapping mapping, int count, int damage) { NbtMapBuilder builder = NbtMap.builder(); - builder.putByte("Count", (byte) count); builder.putString("Name", mapping.getBedrockIdentifier()); - + builder.putByte("Count", (byte) count); builder.putShort("Damage", (short) damage); return builder; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index 65ceb3497..c96542fc1 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -30,52 +30,42 @@ import com.github.steveice10.mc.protocol.data.game.Identifier; import com.github.steveice10.mc.protocol.data.game.entity.attribute.ModifierOperation; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.item.component.AdventureModePredicate; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.item.component.ItemAttributeModifiers; -import com.github.steveice10.opennbt.tag.builtin.ByteArrayTag; -import com.github.steveice10.opennbt.tag.builtin.ByteTag; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.DoubleTag; -import com.github.steveice10.opennbt.tag.builtin.FloatTag; -import com.github.steveice10.opennbt.tag.builtin.IntArrayTag; -import com.github.steveice10.opennbt.tag.builtin.IntTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.LongArrayTag; -import com.github.steveice10.opennbt.tag.builtin.LongTag; -import com.github.steveice10.opennbt.tag.builtin.ShortTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import com.github.steveice10.opennbt.tag.builtin.*; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; -import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; -import org.geysermc.geyser.api.block.custom.CustomBlockData; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtList; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; +import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.api.block.custom.CustomBlockData; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.registry.BlockRegistries; +import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.CustomSkull; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.skin.SkinManager; -import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.util.InventoryUtils; import java.text.DecimalFormat; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; public final class ItemTranslator { @@ -357,7 +347,7 @@ public final class ItemTranslator { return ItemDefinition.AIR; } - ItemMapping mapping = itemStack.asItem().toBedrockDefinition(itemStack.getNbt(), session.getItemMappings()); + ItemMapping mapping = itemStack.asItem().toBedrockDefinition(itemStack.getComponents(), session.getItemMappings()); ItemDefinition itemDefinition = mapping.getBedrockDefinition(); CustomBlockData customBlockData = BlockRegistries.CUSTOM_BLOCK_ITEM_OVERRIDES.getOrDefault( @@ -563,20 +553,21 @@ public final class ItemTranslator { if (components == null) { return null; } + //TODO GameProfile profile = components.get(DataComponentType.PROFILE); if (profile != null) { - if (!(nbt.get("SkullOwner") instanceof CompoundTag skullOwner)) { - // It's a username give up d: - return null; - } - SkinManager.GameProfileData data = SkinManager.GameProfileData.from(skullOwner); - if (data == null) { - session.getGeyser().getLogger().debug("Not sure how to handle skull head item display. " + nbt); - return null; - } - - String skinHash = data.skinUrl().substring(data.skinUrl().lastIndexOf('/') + 1); - return BlockRegistries.CUSTOM_SKULLS.get(skinHash); +// if (!(nbt.get("SkullOwner") instanceof CompoundTag skullOwner)) { +// // It's a username give up d: +// return null; +// } +// SkinManager.GameProfileData data = SkinManager.GameProfileData.from(skullOwner); +// if (data == null) { +// session.getGeyser().getLogger().debug("Not sure how to handle skull head item display. " + nbt); +// return null; +// } +// +// String skinHash = data.skinUrl().substring(data.skinUrl().lastIndexOf('/') + 1); +// return BlockRegistries.CUSTOM_SKULLS.get(skinHash); } return null; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java index ec1d62d16..ba802e42e 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java @@ -26,6 +26,8 @@ package org.geysermc.geyser.translator.protocol.bedrock; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; +import com.github.steveice10.mc.protocol.data.game.item.component.WritableBookContent; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundEditBookPacket; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; @@ -39,10 +41,7 @@ import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.translator.text.MessageTranslator; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; +import java.util.*; @Translator(packet = BookEditPacket.class) public class BedrockBookEditTranslator extends PacketTranslator { @@ -56,8 +55,9 @@ public class BedrockBookEditTranslator extends PacketTranslator GeyserItemStack itemStack = session.getPlayerInventory().getItemInHand(); if (itemStack != null) { - CompoundTag tag = itemStack.getNbt() != null ? itemStack.getNbt() : new CompoundTag(""); - ItemStack bookItem = new ItemStack(itemStack.getJavaId(), itemStack.getAmount(), tag); + DataComponents components = itemStack.getComponents() != null ? itemStack.getComponents() : new DataComponents(new HashMap<>()); + ItemStack bookItem = new ItemStack(itemStack.getJavaId(), itemStack.getAmount(), components); + WritableBookContent List pages = tag.contains("pages") ? new LinkedList<>(((ListTag) tag.get("pages")).getValue()) : new LinkedList<>(); int page = packet.getPageNumber(); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java index c178f27d4..6178a51e8 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java @@ -31,10 +31,7 @@ import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.Client import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.LivingEntity; -import org.geysermc.geyser.entity.type.player.PlayerEntity; -import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.skin.FakeHeadProvider; import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; @@ -62,14 +59,15 @@ public class JavaSetEquipmentTranslator extends PacketTranslator { ItemStack javaItem = equipment.getItem(); - if (livingEntity instanceof PlayerEntity - && javaItem != null - && javaItem.getId() == Items.PLAYER_HEAD.javaId() - && javaItem.getNbt() != null) { - FakeHeadProvider.setHead(session, (PlayerEntity) livingEntity, javaItem.getNbt().get("SkullOwner")); - } else { - FakeHeadProvider.restoreOriginalSkin(session, livingEntity); - } + // TODO +// if (livingEntity instanceof PlayerEntity +// && javaItem != null +// && javaItem.getId() == Items.PLAYER_HEAD.javaId() +// && javaItem.getNbt() != null) { +// FakeHeadProvider.setHead(session, (PlayerEntity) livingEntity, javaItem.getNbt().get("SkullOwner")); +// } else { +// FakeHeadProvider.restoreOriginalSkin(session, livingEntity); +// } livingEntity.setHelmet(item); armorUpdated = true; diff --git a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java index 7f3a02df6..08c2b6cdb 100644 --- a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java @@ -25,13 +25,12 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundPickItemPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetCreativeModeSlotPacket; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; @@ -43,11 +42,7 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.packet.InventorySlotPacket; import org.cloudburstmc.protocol.bedrock.packet.PlayerHotbarPacket; import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.inventory.Container; -import org.geysermc.geyser.inventory.GeyserItemStack; -import org.geysermc.geyser.inventory.Inventory; -import org.geysermc.geyser.inventory.LecternContainer; -import org.geysermc.geyser.inventory.PlayerInventory; +import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.click.Click; import org.geysermc.geyser.inventory.recipe.GeyserRecipe; import org.geysermc.geyser.inventory.recipe.GeyserShapedRecipe; @@ -256,7 +251,7 @@ public class InventoryUtils { continue; } // If this is the item we're looking for - if (geyserItem.getJavaId() == itemStack.getId() && Objects.equals(geyserItem.getNbt(), itemStack.getNbt())) { + if (geyserItem.getJavaId() == itemStack.getId() && Objects.equals(geyserItem.getComponents(), itemStack.getDataComponents())) { //TODO verify setHotbarItem(session, i); // Don't check inventory if item was in hotbar return; @@ -270,7 +265,7 @@ public class InventoryUtils { continue; } // If this is the item we're looking for - if (geyserItem.getJavaId() == itemStack.getId() && Objects.equals(geyserItem.getNbt(), itemStack.getNbt())) { + if (geyserItem.getJavaId() == itemStack.getId() && Objects.equals(geyserItem.getComponents(), itemStack.getDataComponents())) { //TODO verify ServerboundPickItemPacket packetToSend = new ServerboundPickItemPacket(i); // https://wiki.vg/Protocol#Pick_Item session.sendDownstreamGamePacket(packetToSend); return; From ab8832b771deffb569a5558fa171faf587bd370e Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Sun, 21 Apr 2024 01:09:23 -0400 Subject: [PATCH 076/272] Compiles --- .../BedrockBlockPickRequestTranslator.java | 4 +- .../bedrock/BedrockBookEditTranslator.java | 52 +++++++++---------- .../player/BedrockActionTranslator.java | 2 +- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java index 59317fd7c..3781ef3c0 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java @@ -69,7 +69,7 @@ public class BedrockBlockPickRequestTranslator extends PacketTranslator session.ensureInEventLoop(() -> { if (tag == null) { @@ -94,7 +94,7 @@ public class BedrockBlockPickRequestTranslator extends PacketTranslator if (itemStack != null) { DataComponents components = itemStack.getComponents() != null ? itemStack.getComponents() : new DataComponents(new HashMap<>()); ItemStack bookItem = new ItemStack(itemStack.getJavaId(), itemStack.getAmount(), components); - WritableBookContent - List pages = tag.contains("pages") ? new LinkedList<>(((ListTag) tag.get("pages")).getValue()) : new LinkedList<>(); + List pages = new LinkedList<>(); + + WritableBookContent writableBookContent = components.get(DataComponentType.WRITABLE_BOOK_CONTENT); + if (writableBookContent != null) { + for (Filterable page : writableBookContent.getPages()) { + pages.add(page.getRaw()); + } + } int page = packet.getPageNumber(); if (page < 0 || WrittenBookItem.MAXIMUM_PAGE_COUNT <= page) { @@ -69,21 +73,21 @@ public class BedrockBookEditTranslator extends PacketTranslator case ADD_PAGE: { // Add empty pages in between for (int i = pages.size(); i < page; i++) { - pages.add(i, new StringTag("", "")); + pages.add(i, ""); } - pages.add(page, new StringTag("", MessageTranslator.convertToPlainText(packet.getText()))); + pages.add(page, MessageTranslator.convertToPlainText(packet.getText())); break; } // Called whenever a page is modified case REPLACE_PAGE: { if (page < pages.size()) { - pages.set(page, new StringTag("", MessageTranslator.convertToPlainText(packet.getText()))); + pages.set(page, MessageTranslator.convertToPlainText(packet.getText())); } else { // Add empty pages in between for (int i = pages.size(); i < page; i++) { - pages.add(i, new StringTag("", "")); + pages.add(i, ""); } - pages.add(page, new StringTag("", MessageTranslator.convertToPlainText(packet.getText()))); + pages.add(page, MessageTranslator.convertToPlainText(packet.getText())); } break; } @@ -100,33 +104,29 @@ public class BedrockBookEditTranslator extends PacketTranslator } break; } - case SIGN_BOOK: { - tag.put(new StringTag("author", MessageTranslator.convertToPlainText(packet.getAuthor()))); - tag.put(new StringTag("title", MessageTranslator.convertToPlainText(packet.getTitle()))); - break; - } default: return; } // Remove empty pages at the end - while (pages.size() > 0) { - StringTag currentPage = (StringTag) pages.get(pages.size() - 1); - if (currentPage.getValue() == null || currentPage.getValue().isEmpty()) { + while (!pages.isEmpty()) { + String currentPage = pages.get(pages.size() - 1); + if (currentPage.isEmpty()) { pages.remove(pages.size() - 1); } else { break; } } - tag.put(new ListTag("pages", pages)); + + List> filterablePages = new ArrayList<>(pages.size()); + for (String raw : pages) { + filterablePages.add(new Filterable<>(raw, null)); + } + components.put(DataComponentType.WRITABLE_BOOK_CONTENT, new WritableBookContent(filterablePages)); + // Update local copy session.getPlayerInventory().setItem(36 + session.getPlayerInventory().getHeldItemSlot(), GeyserItemStack.from(bookItem), session); session.getInventoryTranslator().updateInventory(session, session.getPlayerInventory()); - List networkPages = new ArrayList<>(); - for (Tag pageTag : pages) { - networkPages.add(((StringTag) pageTag).getValue()); - } - String title; if (packet.getAction() == BookEditPacket.Action.SIGN_BOOK) { // Add title to packet so the server knows we're signing @@ -139,7 +139,7 @@ public class BedrockBookEditTranslator extends PacketTranslator title = null; } - session.getBookEditCache().setPacket(new ServerboundEditBookPacket(session.getPlayerInventory().getHeldItemSlot(), networkPages, title)); + session.getBookEditCache().setPacket(new ServerboundEditBookPacket(session.getPlayerInventory().getHeldItemSlot(), pages, title)); // There won't be any more book updates after this, so we can try sending the edit packet immediately if (packet.getAction() == BookEditPacket.Action.SIGN_BOOK) { session.getBookEditCache().checkForSend(); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java index f5122b256..2fd9ce405 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java @@ -168,7 +168,7 @@ public class BedrockActionTranslator extends PacketTranslator Date: Sun, 21 Apr 2024 16:20:22 -0400 Subject: [PATCH 077/272] Tiny fixes --- .../geyser/item/type/DecoratedPotItem.java | 21 ++++++++---- .../geyser/item/type/WrittenBookItem.java | 34 ++----------------- .../inventory/InventoryTranslator.java | 15 ++++---- 3 files changed, 24 insertions(+), 46 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java index 8d9be4db2..ea194522b 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java @@ -28,9 +28,14 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtType; +import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import java.util.ArrayList; +import java.util.List; + public class DecoratedPotItem extends BlockItem { public DecoratedPotItem(String javaIdentifier, Builder builder) { @@ -41,12 +46,14 @@ public class DecoratedPotItem extends BlockItem { public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - components.get(DataComponentType.POT_DECORATIONS); // TODO what does this look like on Bedrock? -// if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) { -// if (blockEntityTag.remove("sherds") instanceof ListTag sherds) { -// // bedrock wants it on the root level -// tag.put(sherds); -// } -// } + List decorations = components.get(DataComponentType.POT_DECORATIONS); // TODO maybe unbox in MCProtocolLib + if (decorations != null) { + List sherds = new ArrayList<>(decorations.size()); + for (Integer decoration : decorations) { + ItemMapping mapping = session.getItemMappings().getMapping(decoration); + sherds.add(mapping.getBedrockIdentifier()); + } + builder.putList("sherds", NbtType.STRING, sherds); + } } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java index 6ca52aca4..a6b5e73d4 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java @@ -29,10 +29,6 @@ import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentT import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.item.component.Filterable; import com.github.steveice10.mc.protocol.data.game.item.component.WrittenBookContent; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; @@ -47,7 +43,6 @@ import java.util.List; public class WrittenBookItem extends Item { public static final int MAXIMUM_PAGE_EDIT_LENGTH = 1024; - public static final int MAXIMUM_PAGE_LENGTH = 32768; public static final int MAXIMUM_PAGE_COUNT = 100; // Java edition limit. Bedrock edition has a limit of 50 pages. public static final int MAXIMUM_TITLE_LENGTH = 16; @@ -73,33 +68,8 @@ public class WrittenBookItem extends Item { builder.putList("pages", NbtType.COMPOUND, bedrockPages); builder.putString("title", bookContent.getTitle().getRaw()) - .putString("author", bookContent.getAuthor()); + .putString("author", bookContent.getAuthor()) + .putInt("generation", bookContent.getGeneration()); // TODO isResolved } - - private boolean isValidWrittenBook(CompoundTag tag) { - if (!(tag.get("title") instanceof StringTag title)) { - return false; - } - if (title.getValue().length() > (MAXIMUM_TITLE_LENGTH * 2)) { - // Java rejects books with titles more than 2x the maximum length allowed in the input box - return false; - } - - if (!(tag.get("author") instanceof StringTag)) { - return false; - } - - if (!(tag.get("pages") instanceof ListTag pages)) { - return false; - } - for (Tag pageTag : pages) { - if (pageTag instanceof StringTag page) { - if (page.getValue().length() > MAXIMUM_PAGE_LENGTH) { - return false; - } - } - } - return true; - } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java index e6e0c6340..2d7a1ae5a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; +import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; -import com.github.steveice10.opennbt.tag.builtin.IntTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import it.unimi.dsi.fastutil.ints.*; import lombok.AllArgsConstructor; import org.checkerframework.checker.nullness.qual.Nullable; @@ -909,10 +909,11 @@ public abstract class InventoryTranslator { // As of 1.16.210: Bedrock needs confirmation on what the current item durability is. // If 0 is sent, then Bedrock thinks the item is not damaged int durability = 0; - if (itemStack.getNbt() != null) { - Tag damage = itemStack.getNbt().get("Damage"); - if (damage instanceof IntTag) { - durability = ItemUtils.getCorrectBedrockDurability(itemStack.asItem(), ((IntTag) damage).getValue()); + DataComponents components = itemStack.getComponents(); + if (components != null) { + Integer damage = components.get(DataComponentType.DAMAGE); + if (damage != null) { + durability = ItemUtils.getCorrectBedrockDurability(itemStack.asItem(), damage); } } From 61907b18512276bf2a3ba959caff6cd74a9d17e4 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sun, 21 Apr 2024 16:36:54 -0400 Subject: [PATCH 078/272] Little more work --- .../geyser/inventory/AnvilContainer.java | 3 +- .../geyser/inventory/GeyserItemStack.java | 25 +++++++++++++++++ .../updater/AnvilInventoryUpdater.java | 28 +++++++------------ .../translator/text/MessageTranslator.java | 10 +++++++ .../geysermc/geyser/util/InventoryUtils.java | 2 +- .../org/geysermc/geyser/util/ItemUtils.java | 17 ++++++----- 6 files changed, 56 insertions(+), 29 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java index 9e0b83768..3c7b7e4bd 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java @@ -29,6 +29,7 @@ import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket; import lombok.Getter; import lombok.Setter; +import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.text.MessageTranslator; @@ -72,7 +73,7 @@ public class AnvilContainer extends Container { String correctRename; newName = rename; - String originalName = ItemUtils.getCustomName(getInput().getNbt()); + Component originalName = ItemUtils.getCustomName(getInput().getComponents()); String plainOriginalName = MessageTranslator.convertToPlainTextLenient(originalName, session.locale()); String plainNewName = MessageTranslator.convertToPlainText(rename); diff --git a/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java b/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java index 7e621d3aa..a1ecc6f58 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.inventory; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import lombok.AccessLevel; @@ -87,6 +88,30 @@ public class GeyserItemStack { return isEmpty() ? null : components; } + public boolean getComponent(DataComponentType type, boolean def) { + if (components == null) { + return def; + } + + Boolean result = components.get(type); + if (result != null) { + return result; + } + return def; + } + + public int getComponent(DataComponentType type, int def) { + if (components == null) { + return def; + } + + Integer result = components.get(type); + if (result != null) { + return result; + } + return def; + } + public int getNetId() { return isEmpty() ? 0 : netId; } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java b/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java index 96ef12861..9bf001f42 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.inventory.updater; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; @@ -34,6 +35,7 @@ import com.github.steveice10.opennbt.tag.builtin.Tag; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntMaps; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import net.kyori.adventure.text.Component; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerId; @@ -118,7 +120,8 @@ public class AnvilInventoryUpdater extends InventoryUpdater { // Changing the item in the input slot resets the name field on Bedrock, but // does not result in a FilterTextPacket - String originalName = MessageTranslator.convertToPlainTextLenient(ItemUtils.getCustomName(input.getNbt()), session.locale()); + // TODO test + String originalName = MessageTranslator.convertToPlainText(ItemUtils.getCustomName(input.getComponents())); ServerboundRenameItemPacket renameItemPacket = new ServerboundRenameItemPacket(originalName); session.sendDownstreamGamePacket(renameItemPacket); @@ -424,38 +427,27 @@ public class AnvilInventoryUpdater extends InventoryUpdater { } // This should really check the name field in all cases, but that requires the localized name // of the item which can change depending on NBT and Minecraft Edition - String originalName = ItemUtils.getCustomName(anvilContainer.getInput().getNbt()); + Component originalName = ItemUtils.getCustomName(anvilContainer.getInput().getComponents()); if (bedrock && originalName != null && anvilContainer.getNewName() != null) { // Check text and formatting - String legacyOriginalName = MessageTranslator.convertMessageLenient(originalName, session.locale()); + String legacyOriginalName = MessageTranslator.convertMessage(originalName, session.locale()); return !legacyOriginalName.equals(anvilContainer.getNewName()); } - return !Objects.equals(originalName, ItemUtils.getCustomName(anvilContainer.getResult().getNbt())); - } - - @SuppressWarnings("SameParameterValue") - private int getTagIntValueOr(GeyserItemStack itemStack, String tagName, int defaultValue) { - if (itemStack.getNbt() != null) { - Tag tag = itemStack.getNbt().get(tagName); - if (tag != null && tag.getValue() instanceof Number value) { - return value.intValue(); - } - } - return defaultValue; + return !Objects.equals(originalName, ItemUtils.getCustomName(anvilContainer.getResult().getComponents())); } private int getRepairCost(GeyserItemStack itemStack) { - return getTagIntValueOr(itemStack, "RepairCost", 0); + return itemStack.getComponent(DataComponentType.REPAIR_COST, 0); } private boolean hasDurability(GeyserItemStack itemStack) { if (itemStack.asItem().maxDamage() > 0) { - return getTagIntValueOr(itemStack, "Unbreakable", 0) == 0; + return itemStack.getComponent(DataComponentType.UNBREAKABLE, false); } return false; } private int getDamage(GeyserItemStack itemStack) { - return getTagIntValueOr(itemStack, "Damage", 0); + return itemStack.getComponent(DataComponentType.DAMAGE, 0); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java index d93123cff..ed6b9404d 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java @@ -245,6 +245,16 @@ public class MessageTranslator { return GSON_SERIALIZER.serialize(component); } + /** + * Convert legacy format message to plain text + * + * @param message Message to convert + * @return The plain text of the message + */ + public static String convertToPlainText(Component message) { + return PlainTextComponentSerializer.plainText().serialize(message); + } + /** * Convert legacy format message to plain text * diff --git a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java index 08c2b6cdb..2b619714e 100644 --- a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java @@ -180,7 +180,7 @@ public class InventoryUtils { public static boolean canStack(GeyserItemStack item1, GeyserItemStack item2) { if (item1.isEmpty() || item2.isEmpty()) return false; - return item1.getJavaId() == item2.getJavaId() && Objects.equals(item1.getNbt(), item2.getNbt()); + return item1.getJavaId() == item2.getJavaId() && Objects.equals(item1.getComponents(), item2.getComponents()); } /** diff --git a/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java b/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java index a116c5cf2..2138103d4 100644 --- a/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java @@ -25,10 +25,13 @@ package org.geysermc.geyser.util; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; +import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.FishingRodItem; @@ -70,17 +73,13 @@ public class ItemUtils { } /** - * @param itemTag the NBT tag of the item + * @param components the data components of the item * @return the custom name of the item */ - public static @Nullable String getCustomName(CompoundTag itemTag) { - if (itemTag != null) { - if (itemTag.get("display") instanceof CompoundTag displayTag) { - if (displayTag.get("Name") instanceof StringTag nameTag) { - return nameTag.getValue(); - } - } + public static @Nullable Component getCustomName(DataComponents components) { + if (components == null) { + return null; } - return null; + return components.get(DataComponentType.CUSTOM_NAME); } } From 57ce5706ee6fc7f2f674a95beef293cd84dd278a Mon Sep 17 00:00:00 2001 From: basaigh <53559772+basaigh@users.noreply.github.com> Date: Sun, 21 Apr 2024 21:49:56 +0100 Subject: [PATCH 079/272] Update mappings submodule --- core/src/main/resources/mappings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/resources/mappings b/core/src/main/resources/mappings index 4f89411d5..cb2cbe9f2 160000 --- a/core/src/main/resources/mappings +++ b/core/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 4f89411d5bfb4e48699f635876d9c556e5c7e505 +Subproject commit cb2cbe9f262d14640f7c46885f1c8c9d23f2beaa From b73f23de0f190ae2b6942af083b9767059dc78dd Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Sun, 21 Apr 2024 22:54:54 +0200 Subject: [PATCH 080/272] remove global palette bits, fix nullable block entity tags --- .../java/org/geysermc/geyser/session/GeyserSession.java | 5 ----- .../geysermc/geyser/translator/level/BiomeTranslator.java | 4 ---- .../java/level/JavaLevelChunkWithLightTranslator.java | 8 ++++---- .../src/main/java/org/geysermc/geyser/util/MathUtils.java | 7 ------- 4 files changed, 4 insertions(+), 20 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 8e1ed2e51..994879f82 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -263,11 +263,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { @Setter private ItemMappings itemMappings; - /** - * Required to decode biomes correctly. - */ - @Setter - private int biomeGlobalPalette; /** * Stores the map between Java and Bedrock biome network IDs. */ diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java index d4288c5a7..f05ed5ed1 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java @@ -31,7 +31,6 @@ import com.github.steveice10.mc.protocol.data.game.chunk.DataPalette; import com.github.steveice10.mc.protocol.data.game.chunk.palette.GlobalPalette; import com.github.steveice10.mc.protocol.data.game.chunk.palette.Palette; import com.github.steveice10.mc.protocol.data.game.chunk.palette.SingletonPalette; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import it.unimi.dsi.fastutil.ints.*; import org.geysermc.geyser.level.chunk.BlockStorage; import org.geysermc.geyser.level.chunk.bitarray.BitArray; @@ -39,7 +38,6 @@ import org.geysermc.geyser.level.chunk.bitarray.BitArrayVersion; import org.geysermc.geyser.level.chunk.bitarray.SingletonBitArray; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.util.MathUtils; import java.util.List; @@ -49,8 +47,6 @@ public class BiomeTranslator { public static void loadServerBiomes(GeyserSession session, List entries) { Int2IntMap biomeTranslations = new Int2IntOpenHashMap(); - session.setBiomeGlobalPalette(MathUtils.getGlobalPaletteForSize(entries.size())); - int greatestBiomeId = 0; for (int i = 0; i < entries.size(); i++) { RegistryEntry entry = entries.get(i); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java index a98ead719..e34c0d96d 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java @@ -98,7 +98,6 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator Date: Sun, 21 Apr 2024 22:22:15 +0100 Subject: [PATCH 081/272] Bump mcpl to fix item deserialization --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 08c04a84a..5e2720942 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "897eb241b6" # Revert from jitpack after release +mcprotocollib = "2a7176f7ee" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From c5e02d28e6adedeffcad6c2b2d4dddc4c8602bee Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Sun, 21 Apr 2024 23:48:30 +0200 Subject: [PATCH 082/272] ensure geyser builds --- .../java/org/geysermc/geyser/inventory/AnvilContainer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java index 3c7b7e4bd..1c5826cdb 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java @@ -29,7 +29,6 @@ import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket; import lombok.Getter; import lombok.Setter; -import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.text.MessageTranslator; @@ -73,7 +72,8 @@ public class AnvilContainer extends Container { String correctRename; newName = rename; - Component originalName = ItemUtils.getCustomName(getInput().getComponents()); + // TODO 1.20.5 fix properly - this name is apparently nullable?? + String originalName = MessageTranslator.convertMessage(ItemUtils.getCustomName(getInput().getComponents())); String plainOriginalName = MessageTranslator.convertToPlainTextLenient(originalName, session.locale()); String plainNewName = MessageTranslator.convertToPlainText(rename); From 8381a148fc3557534cd250ba9b0eb3871a3e49f5 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Sun, 21 Apr 2024 19:23:05 -0400 Subject: [PATCH 083/272] Fix book signing --- .../translator/protocol/bedrock/BedrockBookEditTranslator.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java index 8e045a51c..4350f6a83 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java @@ -104,6 +104,9 @@ public class BedrockBookEditTranslator extends PacketTranslator } break; } + case SIGN_BOOK: { + break; + } default: return; } From dac5f69d47aa74f46c2ca0bd0a3d505879f8f20e Mon Sep 17 00:00:00 2001 From: basaigh <53559772+basaigh@users.noreply.github.com> Date: Mon, 22 Apr 2024 20:56:57 +0100 Subject: [PATCH 084/272] Bump mcpl --- .../java/org/geysermc/geyser/item/type/ArmorItem.java | 11 +++++------ .../org/geysermc/geyser/item/type/GoatHornItem.java | 3 ++- gradle/libs.versions.toml | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java index ba7f05205..33ff6a7d8 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java @@ -52,16 +52,15 @@ public class ArmorItem extends Item { ArmorTrim trim = components.get(DataComponentType.TRIM); if (trim != null) { - // TODO material IDs - String material = trim.getMaterial().getAssetName(); - String pattern = trim.getPattern().getAssetId(); - // discard custom trim patterns/materials to prevent visual glitches on bedrock - if (!material.startsWith("minecraft:") - || !pattern.startsWith("minecraft:")) { + if (trim.getMaterial().isCustom() || trim.getPattern().isCustom()) { return; } + // TODO material IDs + String material = trim.getMaterial().getCustomValue().getAssetName(); + String pattern = trim.getPattern().getCustomValue().getAssetId(); + NbtMapBuilder trimBuilder = NbtMap.builder(); // bedrock has an uppercase first letter key, and the value is not namespaced trimBuilder.put("Material", stripNamespace(material)); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java index 48e75dc79..35b7a76fc 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.item.type; +import com.github.steveice10.mc.protocol.data.game.Holder; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; @@ -60,7 +61,7 @@ public class GoatHornItem extends Item { if (components == null) { return builder; } - Instrument instrument = components.get(DataComponentType.INSTRUMENT); + Holder instrument = components.get(DataComponentType.INSTRUMENT); // TODO registry if (instrument != null) { // Drop the Minecraft namespace if applicable diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5e2720942..4189f8857 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "2a7176f7ee" # Revert from jitpack after release +mcprotocollib = "8bc6990525" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From c34f0f2c3b1b2f0ca024dd53899746f2cc3fbeab Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 22 Apr 2024 16:36:03 -0400 Subject: [PATCH 085/272] Update for latest MCProtocolLib --- .../main/java/org/geysermc/geyser/item/type/ArmorItem.java | 6 +++--- gradle/libs.versions.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java index 33ff6a7d8..ab936bd08 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java @@ -53,13 +53,13 @@ public class ArmorItem extends Item { ArmorTrim trim = components.get(DataComponentType.TRIM); if (trim != null) { // discard custom trim patterns/materials to prevent visual glitches on bedrock - if (trim.getMaterial().isCustom() || trim.getPattern().isCustom()) { + if (trim.material().isCustom() || trim.pattern().isCustom()) { return; } // TODO material IDs - String material = trim.getMaterial().getCustomValue().getAssetName(); - String pattern = trim.getPattern().getCustomValue().getAssetId(); + String material = trim.material().custom().assetName(); + String pattern = trim.pattern().custom().assetId(); NbtMapBuilder trimBuilder = NbtMap.builder(); // bedrock has an uppercase first letter key, and the value is not namespaced diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4189f8857..b7e692ab7 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "8bc6990525" # Revert from jitpack after release +mcprotocollib = "4ee05b62" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From 6a5efa3c9dc1aa7d3d29a5dd17378195104fb1d6 Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Mon, 22 Apr 2024 23:36:48 +0200 Subject: [PATCH 086/272] Start on 1.20.5 mod platform support - NeoForge (temporarily) excluded Also fixes lecterns, and block break speed calculations --- .github/workflows/build-remote.yml | 2 +- .github/workflows/build.yml | 2 +- .github/workflows/preview.yml | 2 +- bootstrap/mod/build.gradle.kts | 3 +- .../fabric/src/main/resources/fabric.mod.json | 5 +- .../platform/mod/ModPingPassthrough.java | 5 +- .../mod/command/ModCommandSender.java | 3 +- .../mod/world/GeyserModWorldManager.java | 153 +++++------------- .../geyser.modded-conventions.gradle.kts | 10 +- build.gradle.kts | 2 +- .../inventory/LecternInventoryTranslator.java | 22 ++- .../level/JavaBlockDestructionTranslator.java | 3 +- .../org/geysermc/geyser/util/BlockUtils.java | 45 +++--- .../org/geysermc/geyser/util/ItemUtils.java | 28 ++-- settings.gradle.kts | 4 +- 15 files changed, 110 insertions(+), 179 deletions(-) diff --git a/.github/workflows/build-remote.yml b/.github/workflows/build-remote.yml index d49920785..09326d429 100644 --- a/.github/workflows/build-remote.yml +++ b/.github/workflows/build-remote.yml @@ -64,7 +64,7 @@ jobs: with: name: Geyser NeoForge path: geyser/bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar - if-no-files-found: error + #if-no-files-found: error // TODO 1.20.5 until neoforge updates - name: Archive artifacts (Geyser Standalone) uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 if: success() diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 284fa265a..cfb509f30 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -68,7 +68,7 @@ jobs: with: name: Geyser NeoForge path: bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar - if-no-files-found: error + #if-no-files-found: error // TODO 1.20.5 - currently no neoforge artifacts - name: Archive artifacts (Geyser Standalone) uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 if: success() diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 13712d5ef..a33c71a79 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -53,10 +53,10 @@ jobs: with: appID: ${{ secrets.RELEASE_APP_ID }} appPrivateKey: ${{ secrets.RELEASE_APP_PK }} + # neoforge:Geyser-NeoForge.jar // TODO 1.20.5 files: | bungeecord:Geyser-BungeeCord.jar fabric:Geyser-Fabric.jar - neoforge:Geyser-NeoForge.jar spigot:Geyser-Spigot.jar standalone:Geyser-Standalone.jar velocity:Geyser-Velocity.jar diff --git a/bootstrap/mod/build.gradle.kts b/bootstrap/mod/build.gradle.kts index 7651a2df2..281fd45e7 100644 --- a/bootstrap/mod/build.gradle.kts +++ b/bootstrap/mod/build.gradle.kts @@ -1,5 +1,6 @@ architectury { - common("neoforge", "fabric") + common("fabric") + //common("neoforge", "fabric") // todo 1.20.5 } loom { diff --git a/bootstrap/mod/fabric/src/main/resources/fabric.mod.json b/bootstrap/mod/fabric/src/main/resources/fabric.mod.json index 6bd217433..7fb6b302c 100644 --- a/bootstrap/mod/fabric/src/main/resources/fabric.mod.json +++ b/bootstrap/mod/fabric/src/main/resources/fabric.mod.json @@ -23,9 +23,8 @@ "geyser.mixins.json" ], "depends": { - "fabricloader": ">=0.15.2", + "fabricloader": ">=0.15.10", "fabric": "*", - "minecraft": ">=1.20.4", - "fabric-permissions-api-v0": "*" + "minecraft": ">=1.20.4" } } diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/ModPingPassthrough.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/ModPingPassthrough.java index 12d690d83..a2bbfa379 100644 --- a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/ModPingPassthrough.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/ModPingPassthrough.java @@ -29,6 +29,7 @@ import lombok.AllArgsConstructor; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; +import net.minecraft.core.RegistryAccess; import net.minecraft.network.Connection; import net.minecraft.network.PacketSendListener; import net.minecraft.network.protocol.Packet; @@ -69,7 +70,7 @@ public class ModPingPassthrough implements IGeyserPingPassthrough { StatusInterceptor connection = new StatusInterceptor(); ServerStatusPacketListener statusPacketListener = new ServerStatusPacketListenerImpl(status, connection); - statusPacketListener.handleStatusRequest(new ServerboundStatusRequestPacket()); + statusPacketListener.handleStatusRequest(ServerboundStatusRequestPacket.INSTANCE); // mods like MiniMOTD (that inject into the above method) have now processed the response status = Objects.requireNonNull(connection.status, "status response"); } catch (Exception e) { @@ -79,7 +80,7 @@ public class ModPingPassthrough implements IGeyserPingPassthrough { } } - String jsonDescription = net.minecraft.network.chat.Component.Serializer.toJson(status.description()); + String jsonDescription = net.minecraft.network.chat.Component.Serializer.toJson(status.description(), RegistryAccess.EMPTY); String legacyDescription = LEGACY_SERIALIZER.serialize(GSON_SERIALIZER.deserializeOr(jsonDescription, Component.empty())); return new GeyserPingInfo( diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/command/ModCommandSender.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/command/ModCommandSender.java index 17154ffd8..5bebfae93 100644 --- a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/command/ModCommandSender.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/command/ModCommandSender.java @@ -27,6 +27,7 @@ package org.geysermc.geyser.platform.mod.command; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.minecraft.commands.CommandSourceStack; +import net.minecraft.core.RegistryAccess; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; import org.checkerframework.checker.nullness.qual.NonNull; @@ -63,7 +64,7 @@ public class ModCommandSender implements GeyserCommandSource { public void sendMessage(net.kyori.adventure.text.Component message) { if (source.getEntity() instanceof ServerPlayer player) { String decoded = GsonComponentSerializer.gson().serialize(message); - player.displayClientMessage(Objects.requireNonNull(Component.Serializer.fromJson(decoded)), false); + player.displayClientMessage(Objects.requireNonNull(Component.Serializer.fromJson(decoded, RegistryAccess.EMPTY)), false); return; } GeyserCommandSource.super.sendMessage(message); diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java index 04c538632..e9d612976 100644 --- a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java @@ -27,37 +27,28 @@ package org.geysermc.geyser.platform.mod.world; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo; +import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import net.minecraft.SharedConstants; import net.minecraft.core.BlockPos; -import net.minecraft.nbt.ByteArrayTag; -import net.minecraft.nbt.ByteTag; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.DoubleTag; -import net.minecraft.nbt.EndTag; -import net.minecraft.nbt.FloatTag; -import net.minecraft.nbt.IntArrayTag; -import net.minecraft.nbt.IntTag; -import net.minecraft.nbt.ListTag; -import net.minecraft.nbt.LongArrayTag; -import net.minecraft.nbt.LongTag; -import net.minecraft.nbt.ShortTag; -import net.minecraft.nbt.StringTag; -import net.minecraft.nbt.Tag; -import net.minecraft.nbt.TagVisitor; +import net.minecraft.core.RegistryAccess; +import net.minecraft.core.component.DataComponents; +import net.minecraft.network.chat.Component; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.Filterable; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.WritableBookItem; -import net.minecraft.world.item.WrittenBookItem; +import net.minecraft.world.item.component.WritableBookContent; +import net.minecraft.world.item.component.WrittenBookContent; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BannerBlockEntity; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.LecternBlockEntity; import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkStatus; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunkSection; +import net.minecraft.world.level.chunk.status.ChunkStatus; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; @@ -72,10 +63,12 @@ import org.geysermc.geyser.util.BlockEntityUtils; import java.util.ArrayList; import java.util.List; -import java.util.Objects; import java.util.concurrent.CompletableFuture; public class GeyserModWorldManager extends GeyserWorldManager { + + private static final GsonComponentSerializer GSON_SERIALIZER = GsonComponentSerializer.gson(); + private static final LegacyComponentSerializer LEGACY_SERIALIZER = LegacyComponentSerializer.legacySection(); private final MinecraftServer server; public GeyserModWorldManager(MinecraftServer server) { @@ -180,7 +173,7 @@ public class GeyserModWorldManager extends GeyserWorldManager { } ItemStack book = lectern.getBook(); - int pageCount = WrittenBookItem.getPageCount(book); + int pageCount = getPageCount(book); boolean hasBookPages = pageCount > 0; NbtMapBuilder lecternTag = LecternUtils.getBaseLecternTag(x, y, z, hasBookPages ? pageCount : 1); lecternTag.putInt("page", lectern.getPage() / 2); @@ -189,11 +182,9 @@ public class GeyserModWorldManager extends GeyserWorldManager { .putShort("Damage", (short) 0) .putString("Name", "minecraft:writable_book"); List pages = new ArrayList<>(hasBookPages ? pageCount : 1); - if (hasBookPages && WritableBookItem.makeSureTagIsValid(book.getTag())) { - ListTag listTag = book.getTag().getList("pages", 8); - - for (int i = 0; i < listTag.size(); i++) { - String page = listTag.getString(i); + if (hasBookPages) { + List bookPages = getPages(book); + for (String page : bookPages) { NbtMapBuilder pageBuilder = NbtMap.builder() .putString("photoname", "") .putString("text", page); @@ -243,9 +234,8 @@ public class GeyserModWorldManager extends GeyserWorldManager { // Potentially exposes other NBT data? But we need to get the NBT data for the banner patterns *and* // the banner might have a custom name, both of which a Java client knows and caches ItemStack itemStack = banner.getItem(); - var tag = OpenNbtTagVisitor.convert("", itemStack.getOrCreateTag()); - future.complete(tag); + future.complete(null); // todo 1.20.5 return; } future.complete(null); @@ -257,95 +247,32 @@ public class GeyserModWorldManager extends GeyserWorldManager { return server.getPlayerList().getPlayer(session.getPlayerEntity().getUuid()); } - // Future considerations: option to clone; would affect arrays - private static class OpenNbtTagVisitor implements TagVisitor { - private String currentKey; - private final com.github.steveice10.opennbt.tag.builtin.CompoundTag root; - private com.github.steveice10.opennbt.tag.builtin.Tag currentTag; - - OpenNbtTagVisitor(String key) { - root = new com.github.steveice10.opennbt.tag.builtin.CompoundTag(key); + private static int getPageCount(ItemStack itemStack) { + WrittenBookContent writtenBookContent = itemStack.get(DataComponents.WRITTEN_BOOK_CONTENT); + if (writtenBookContent != null) { + return writtenBookContent.pages().size(); + } else { + WritableBookContent writableBookContent = itemStack.get(DataComponents.WRITABLE_BOOK_CONTENT); + return writableBookContent != null ? writableBookContent.pages().size() : 0; } + } - @Override - public void visitString(StringTag stringTag) { - currentTag = new com.github.steveice10.opennbt.tag.builtin.StringTag(currentKey, stringTag.getAsString()); - } - - @Override - public void visitByte(ByteTag byteTag) { - currentTag = new com.github.steveice10.opennbt.tag.builtin.ByteTag(currentKey, byteTag.getAsByte()); - } - - @Override - public void visitShort(ShortTag shortTag) { - currentTag = new com.github.steveice10.opennbt.tag.builtin.ShortTag(currentKey, shortTag.getAsShort()); - } - - @Override - public void visitInt(IntTag intTag) { - currentTag = new com.github.steveice10.opennbt.tag.builtin.IntTag(currentKey, intTag.getAsInt()); - } - - @Override - public void visitLong(LongTag longTag) { - currentTag = new com.github.steveice10.opennbt.tag.builtin.LongTag(currentKey, longTag.getAsLong()); - } - - @Override - public void visitFloat(FloatTag floatTag) { - currentTag = new com.github.steveice10.opennbt.tag.builtin.FloatTag(currentKey, floatTag.getAsFloat()); - } - - @Override - public void visitDouble(DoubleTag doubleTag) { - currentTag = new com.github.steveice10.opennbt.tag.builtin.DoubleTag(currentKey, doubleTag.getAsDouble()); - } - - @Override - public void visitByteArray(ByteArrayTag byteArrayTag) { - currentTag = new com.github.steveice10.opennbt.tag.builtin.ByteArrayTag(currentKey, byteArrayTag.getAsByteArray()); - } - - @Override - public void visitIntArray(IntArrayTag intArrayTag) { - currentTag = new com.github.steveice10.opennbt.tag.builtin.IntArrayTag(currentKey, intArrayTag.getAsIntArray()); - } - - @Override - public void visitLongArray(LongArrayTag longArrayTag) { - currentTag = new com.github.steveice10.opennbt.tag.builtin.LongArrayTag(currentKey, longArrayTag.getAsLongArray()); - } - - @Override - public void visitList(ListTag listTag) { - var newList = new com.github.steveice10.opennbt.tag.builtin.ListTag(currentKey); - for (Tag tag : listTag) { - currentKey = ""; - tag.accept(this); - newList.add(currentTag); + private static List getPages(ItemStack itemStack) { + WrittenBookContent writtenBookContent = itemStack.get(DataComponents.WRITTEN_BOOK_CONTENT); + if (writtenBookContent != null) { + return writtenBookContent.pages().stream() + .map(Filterable::raw) + .map((component) -> Component.Serializer.toJson(component, RegistryAccess.EMPTY)) + .map((json -> LEGACY_SERIALIZER.serialize(GSON_SERIALIZER.deserializeOr(json, net.kyori.adventure.text.Component.empty())))) + .toList(); + } else { + WritableBookContent writableBookContent = itemStack.get(DataComponents.WRITABLE_BOOK_CONTENT); + if (writableBookContent == null) { + return List.of(); } - currentTag = newList; - } - - @Override - public void visitCompound(@NonNull CompoundTag compoundTag) { - currentTag = convert(currentKey, compoundTag); - } - - private static com.github.steveice10.opennbt.tag.builtin.CompoundTag convert(String name, CompoundTag compoundTag) { - OpenNbtTagVisitor visitor = new OpenNbtTagVisitor(name); - for (String key : compoundTag.getAllKeys()) { - visitor.currentKey = key; - Tag tag = Objects.requireNonNull(compoundTag.get(key)); - tag.accept(visitor); - visitor.root.put(visitor.currentTag); - } - return visitor.root; - } - - @Override - public void visitEnd(@NonNull EndTag endTag) { + return writableBookContent.pages().stream() + .map(Filterable::raw) + .toList(); } } } diff --git a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts index 3d41dbbb4..c83ea2911 100644 --- a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts @@ -46,6 +46,12 @@ loom { silentMojangMappingsLicense() } +indra { + javaVersions { + target(21) + } +} + configurations { create("includeTransitive").isTransitive = true } @@ -104,7 +110,7 @@ afterEvaluate { } dependencies { - minecraft("com.mojang:minecraft:1.20.4") + minecraft("com.mojang:minecraft:1.20.5-rc3") mappings(loom.officialMojangMappings()) } @@ -128,6 +134,6 @@ modrinth { syncBodyFrom.set(rootProject.file("README.md").readText()) uploadFile.set(tasks.getByPath("remapModrinthJar")) - gameVersions.addAll("1.20.4") + gameVersions.addAll("1.20.5") failSilently.set(true) } \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index dfdff2187..fdacd5538 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -22,7 +22,7 @@ val basePlatforms = setOf( val moddedPlatforms = setOf( projects.fabric, - projects.neoforge, + //projects.neoforge, // todo 1.20.5 projects.mod ).map { it.dependencyProject } diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java index 9d0661b08..7dff2647c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java @@ -26,10 +26,11 @@ package org.geysermc.geyser.translator.inventory; import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.WritableBookContent; +import com.github.steveice10.mc.protocol.data.game.item.component.WrittenBookContent; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -152,7 +153,6 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator session.setDroppingLecternBook(false); InventoryUtils.closeInventory(session, inventory.getJavaId(), false); } else if (lecternContainer.getBlockEntityTag() == null) { - CompoundTag tag = book.getNbt(); Vector3i position = lecternContainer.isUsingRealBlock() ? session.getLastInteractionBlockPosition() : inventory.getHolderPosition(); // If shouldExpectLecternHandled returns true, this is already handled for us @@ -163,10 +163,20 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator && !GameProtocol.is1_20_60orHigher(session.getUpstream().getProtocolVersion()); NbtMap blockEntityTag; - if (tag != null) { - int pagesSize = ((ListTag) tag.get("pages")).size(); + if (book.getComponents() != null) { + int pages = 0; + WrittenBookContent writtenBookComponents = book.getComponents().get(DataComponentType.WRITTEN_BOOK_CONTENT); + if (writtenBookComponents != null) { + pages = writtenBookComponents.getPages().size(); + } else { + WritableBookContent writableBookComponents = book.getComponents().get(DataComponentType.WRITABLE_BOOK_CONTENT); + if (writableBookComponents != null) { + pages = writableBookComponents.getPages().size(); + } + } + ItemData itemData = book.getItemData(session); - NbtMapBuilder lecternTag = LecternUtils.getBaseLecternTag(position.getX(), position.getY(), position.getZ(), pagesSize); + NbtMapBuilder lecternTag = LecternUtils.getBaseLecternTag(position.getX(), position.getY(), position.getZ(), pages); lecternTag.putCompound("book", NbtMap.builder() .putByte("Count", (byte) itemData.getCount()) .putShort("Damage", (short) 0) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockDestructionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockDestructionTranslator.java index 2a9af8fbf..2fdba716b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockDestructionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockDestructionTranslator.java @@ -26,7 +26,6 @@ package org.geysermc.geyser.translator.protocol.java.level; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundBlockDestructionPacket; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; import org.geysermc.geyser.registry.BlockRegistries; @@ -43,7 +42,7 @@ public class JavaBlockDestructionTranslator extends PacketTranslator session.getTagCache().isAxeEffective(blockMapping); + case "hoe" -> session.getTagCache().isHoeEffective(blockMapping); + case "pickaxe" -> session.getTagCache().isPickaxeEffective(blockMapping); + case "shears" -> session.getTagCache().isShearsEffective(blockMapping); + case "shovel" -> session.getTagCache().isShovelEffective(blockMapping); + case "sword" -> blockMapping.getJavaBlockId() == BlockStateValues.JAVA_COBWEB_ID; + default -> { session.getGeyser().getLogger().warning("Unknown tool type: " + itemToolType); - return false; - } + yield false; + } + }; } private static double toolBreakTimeBonus(String toolType, String toolTier, boolean isShearsEffective) { if (toolType.equals("shears")) return isShearsEffective ? 5.0 : 15.0; - if (toolType.equals("")) return 1.0; + if (toolType.isEmpty()) return 1.0; return switch (toolTier) { // https://minecraft.wiki/w/Breaking#Speed case "wooden" -> 2.0; @@ -134,7 +130,7 @@ public final class BlockUtils { return 1.0 / speed; } - public static double getBreakTime(GeyserSession session, BlockMapping blockMapping, ItemMapping item, @Nullable CompoundTag nbtData, boolean isSessionPlayer) { + public static double getBreakTime(GeyserSession session, BlockMapping blockMapping, ItemMapping item, @Nullable DataComponents components, boolean isSessionPlayer) { boolean isShearsEffective = session.getTagCache().isShearsEffective(blockMapping); //TODO called twice boolean canHarvestWithHand = blockMapping.isCanBreakWithHand(); String toolType = ""; @@ -147,7 +143,8 @@ public final class BlockUtils { correctTool = correctTool(session, blockMapping, toolType); toolCanBreak = canToolTierBreakBlock(session, blockMapping, toolTier); } - int toolEfficiencyLevel = ItemUtils.getEnchantmentLevel(nbtData, "minecraft:efficiency"); + + int toolEfficiencyLevel = ItemUtils.getEnchantmentLevel(components, Enchantment.JavaEnchantment.EFFICIENCY.ordinal()); int hasteLevel = 0; int miningFatigueLevel = 0; @@ -162,7 +159,7 @@ public final class BlockUtils { boolean waterInEyes = session.getCollisionManager().isWaterInEyes(); boolean insideOfWaterWithoutAquaAffinity = waterInEyes && - ItemUtils.getEnchantmentLevel(session.getPlayerInventory().getItem(5).getNbt(), "minecraft:aqua_affinity") < 1; + ItemUtils.getEnchantmentLevel(session.getPlayerInventory().getItem(5).getComponents(), Enchantment.JavaEnchantment.AQUA_AFFINITY.ordinal()) < 1; return calculateBreakTime(blockMapping.getHardness(), toolTier, canHarvestWithHand, correctTool, toolCanBreak, toolType, isShearsEffective, toolEfficiencyLevel, hasteLevel, miningFatigueLevel, insideOfWaterWithoutAquaAffinity, session.getPlayerEntity().isOnGround()); @@ -172,12 +169,12 @@ public final class BlockUtils { PlayerInventory inventory = session.getPlayerInventory(); GeyserItemStack item = inventory.getItemInHand(); ItemMapping mapping = ItemMapping.AIR; - CompoundTag nbtData = null; + DataComponents components = null; if (item != null) { mapping = item.getMapping(session); - nbtData = item.getNbt(); + components = item.getComponents(); } - return getBreakTime(session, blockMapping, mapping, nbtData, true); + return getBreakTime(session, blockMapping, mapping, components, true); } /** diff --git a/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java b/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java index 2138103d4..b1591e911 100644 --- a/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java @@ -27,10 +27,7 @@ package org.geysermc.geyser.util; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import com.github.steveice10.mc.protocol.data.game.item.component.ItemEnchantments; import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.item.Items; @@ -39,24 +36,17 @@ import org.geysermc.geyser.item.type.Item; public class ItemUtils { - public static int getEnchantmentLevel(@Nullable CompoundTag itemNBTData, String enchantmentId) { - if (itemNBTData == null) { + public static int getEnchantmentLevel(@Nullable DataComponents components, int enchantmentId) { + if (components == null) { return 0; } - ListTag enchantments = itemNBTData.get("Enchantments"); - if (enchantments != null) { - for (Tag tag : enchantments) { - CompoundTag enchantment = (CompoundTag) tag; - StringTag enchantId = enchantment.get("id"); - if (enchantId.getValue().equals(enchantmentId)) { - Tag lvl = enchantment.get("lvl"); - if (lvl != null && lvl.getValue() instanceof Number number) { - return number.intValue(); - } - } - } + + ItemEnchantments enchantmentData = components.get(DataComponentType.ENCHANTMENTS); + if (enchantmentData == null) { + return 0; } - return 0; + + return enchantmentData.getEnchantments().getOrDefault(enchantmentId, 0); } /** diff --git a/settings.gradle.kts b/settings.gradle.kts index a39bfa3d2..3867d7a84 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -66,7 +66,7 @@ include(":ap") include(":api") include(":bungeecord") include(":fabric") -include(":neoforge") +//include(":neoforge") // todo 1.20.5 include(":mod") include(":spigot") include(":standalone") @@ -78,7 +78,7 @@ include(":core") // Specify project dirs project(":bungeecord").projectDir = file("bootstrap/bungeecord") project(":fabric").projectDir = file("bootstrap/mod/fabric") -project(":neoforge").projectDir = file("bootstrap/mod/neoforge") +//project(":neoforge").projectDir = file("bootstrap/mod/neoforge") // todo 1.20.5 project(":mod").projectDir = file("bootstrap/mod") project(":spigot").projectDir = file("bootstrap/spigot") project(":standalone").projectDir = file("bootstrap/standalone") From 11f79d4e2c955b35f353eb7bacd5b354a9ca9278 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 22 Apr 2024 19:40:50 -0400 Subject: [PATCH 087/272] Refactor Java registry storage; implement trim support --- .../geyser/inventory/recipe/TrimRecipe.java | 91 ++++++----- .../geysermc/geyser/item/type/ArmorItem.java | 19 +-- .../geysermc/geyser/level/JavaDimension.java | 14 ++ .../geyser/session/GeyserSession.java | 35 +--- .../geyser/session/cache/RegistryCache.java | 153 ++++++++++++++++++ .../geysermc/geyser/text/TextDecoration.java | 12 ++ .../translator/level/BiomeTranslator.java | 58 ++----- .../java/JavaRegistryDataTranslator.java | 35 +--- .../java/JavaUpdateRecipesTranslator.java | 4 +- .../translator/text/MessageTranslator.java | 2 +- .../org/geysermc/geyser/util/ChunkUtils.java | 2 +- 11 files changed, 253 insertions(+), 172 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java diff --git a/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java b/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java index 584928e65..441f050a7 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java @@ -25,63 +25,68 @@ package org.geysermc.geyser.inventory.recipe; +import com.github.steveice10.mc.protocol.data.game.RegistryEntry; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.StringTag; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.TextColor; import org.cloudburstmc.protocol.bedrock.data.TrimMaterial; import org.cloudburstmc.protocol.bedrock.data.TrimPattern; import org.cloudburstmc.protocol.bedrock.data.inventory.descriptor.ItemDescriptorWithCount; import org.cloudburstmc.protocol.bedrock.data.inventory.descriptor.ItemTagDescriptor; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import org.geysermc.geyser.registry.type.ItemMapping; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.text.MessageTranslator; /** - * Hardcoded recipe information about armor trims until further improvements can be made. This information was scraped - * from BDS 1.19.81 with a world with the next_major_update and sniffer features enabled, using ProxyPass. + * Stores information on trim materials and patterns, including smithing armor hacks for pre-1.20. */ -public class TrimRecipe { - - // For TrimDataPacket, which BDS sends just before the CraftingDataPacket - public static final List PATTERNS; - public static final List MATERIALS; - +public final class TrimRecipe { // For CraftingDataPacket public static final String ID = "minecraft:smithing_armor_trim"; public static final ItemDescriptorWithCount BASE = tagDescriptor("minecraft:trimmable_armors"); public static final ItemDescriptorWithCount ADDITION = tagDescriptor("minecraft:trim_materials"); public static final ItemDescriptorWithCount TEMPLATE = tagDescriptor("minecraft:trim_templates"); - static { - List patterns = new ArrayList<>(16); - patterns.add(new TrimPattern("minecraft:ward_armor_trim_smithing_template", "ward")); - patterns.add(new TrimPattern("minecraft:sentry_armor_trim_smithing_template", "sentry")); - patterns.add(new TrimPattern("minecraft:snout_armor_trim_smithing_template", "snout")); - patterns.add(new TrimPattern("minecraft:dune_armor_trim_smithing_template", "dune")); - patterns.add(new TrimPattern("minecraft:spire_armor_trim_smithing_template", "spire")); - patterns.add(new TrimPattern("minecraft:tide_armor_trim_smithing_template", "tide")); - patterns.add(new TrimPattern("minecraft:wild_armor_trim_smithing_template", "wild")); - patterns.add(new TrimPattern("minecraft:rib_armor_trim_smithing_template", "rib")); - patterns.add(new TrimPattern("minecraft:coast_armor_trim_smithing_template", "coast")); - patterns.add(new TrimPattern("minecraft:shaper_armor_trim_smithing_template", "shaper")); - patterns.add(new TrimPattern("minecraft:eye_armor_trim_smithing_template", "eye")); - patterns.add(new TrimPattern("minecraft:vex_armor_trim_smithing_template", "vex")); - patterns.add(new TrimPattern("minecraft:silence_armor_trim_smithing_template", "silence")); - patterns.add(new TrimPattern("minecraft:wayfinder_armor_trim_smithing_template", "wayfinder")); - patterns.add(new TrimPattern("minecraft:raiser_armor_trim_smithing_template", "raiser")); - patterns.add(new TrimPattern("minecraft:host_armor_trim_smithing_template", "host")); - PATTERNS = Collections.unmodifiableList(patterns); + public static TrimMaterial readTrimMaterial(GeyserSession session, RegistryEntry entry) { + String key = stripNamespace(entry.getId()); - List materials = new ArrayList<>(10); - materials.add(new TrimMaterial("quartz", "§h", "minecraft:quartz")); - materials.add(new TrimMaterial("iron", "§i", "minecraft:iron_ingot")); - materials.add(new TrimMaterial("netherite", "§j", "minecraft:netherite_ingot")); - materials.add(new TrimMaterial("redstone", "§m", "minecraft:redstone")); - materials.add(new TrimMaterial("copper", "§n", "minecraft:copper_ingot")); - materials.add(new TrimMaterial("gold", "§p", "minecraft:gold_ingot")); - materials.add(new TrimMaterial("emerald", "§q", "minecraft:emerald")); - materials.add(new TrimMaterial("diamond", "§s", "minecraft:diamond")); - materials.add(new TrimMaterial("lapis", "§t", "minecraft:lapis_lazuli")); - materials.add(new TrimMaterial("amethyst", "§u", "minecraft:amethyst_shard")); - MATERIALS = Collections.unmodifiableList(materials); + // Color is used when hovering over the item + // Find the nearest legacy color from the RGB Java gives us to work with + // Also yes this is a COMPLETE hack but it works ok!!!!! + StringTag colorTag = ((CompoundTag) entry.getData().get("description")).get("color"); + TextColor color = TextColor.fromHexString(colorTag.getValue()); + String legacy = MessageTranslator.convertMessage(Component.space().color(color)); + + String itemIdentifier = ((StringTag) entry.getData().get("ingredient")).getValue(); + ItemMapping itemMapping = session.getItemMappings().getMapping(itemIdentifier); + if (itemMapping == null) { + // This should never happen so not sure what to do here. + itemMapping = ItemMapping.AIR; + } + // Just pick out the resulting color code, without RESET in front. + return new TrimMaterial(key, legacy.substring(2).trim(), itemMapping.getBedrockIdentifier()); + } + + public static TrimPattern readTrimPattern(GeyserSession session, RegistryEntry entry) { + String key = stripNamespace(entry.getId()); + + String itemIdentifier = ((StringTag) entry.getData().get("template_item")).getValue(); + ItemMapping itemMapping = session.getItemMappings().getMapping(itemIdentifier); + if (itemMapping == null) { + // This should never happen so not sure what to do here. + itemMapping = ItemMapping.AIR; + } + return new TrimPattern(itemMapping.getBedrockIdentifier(), key); + } + + // TODO find a good place for a stripNamespace util method + private static String stripNamespace(String identifier) { + int i = identifier.indexOf(':'); + if (i >= 0) { + return identifier.substring(i + 1); + } + return identifier; } private TrimRecipe() { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java index ab936bd08..773b850c0 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java @@ -33,6 +33,8 @@ import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.protocol.bedrock.data.TrimMaterial; +import org.cloudburstmc.protocol.bedrock.data.TrimPattern; import org.geysermc.geyser.item.ArmorMaterial; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; @@ -57,14 +59,13 @@ public class ArmorItem extends Item { return; } - // TODO material IDs - String material = trim.material().custom().assetName(); - String pattern = trim.pattern().custom().assetId(); + TrimMaterial material = session.getRegistryCache().trimMaterials().get(trim.material().id()); + TrimPattern pattern = session.getRegistryCache().trimPatterns().get(trim.pattern().id()); NbtMapBuilder trimBuilder = NbtMap.builder(); // bedrock has an uppercase first letter key, and the value is not namespaced - trimBuilder.put("Material", stripNamespace(material)); - trimBuilder.put("Pattern", stripNamespace(pattern)); + trimBuilder.put("Material", material.getMaterialId()); + trimBuilder.put("Pattern", pattern.getPatternId()); builder.putCompound("Trim", trimBuilder.build()); } } @@ -86,12 +87,4 @@ public class ArmorItem extends Item { public boolean isValidRepairItem(Item other) { return material.getRepairIngredient() == other; } - - private static String stripNamespace(String identifier) { - int i = identifier.indexOf(':'); - if (i >= 0) { - return identifier.substring(i + 1); - } - return identifier; - } } diff --git a/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java b/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java index 6e7223da0..4babc3af0 100644 --- a/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java +++ b/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java @@ -55,4 +55,18 @@ public record JavaDimension(int minY, int maxY, boolean piglinSafe, double world map.put(i, new JavaDimension(minY, maxY, piglinSafe, coordinateScale)); } } + + public static JavaDimension read(RegistryEntry entry) { + CompoundTag dimension = entry.getData(); + int minY = ((IntTag) dimension.get("min_y")).getValue(); + int maxY = ((IntTag) dimension.get("height")).getValue(); + // Logical height can be ignored probably - seems to be for artificial limits like the Nether. + + // Set if piglins/hoglins should shake + boolean piglinSafe = ((Number) dimension.get("piglin_safe").getValue()).byteValue() != (byte) 0; + // Load world coordinate scale for the world border + double coordinateScale = ((Number) dimension.get("coordinate_scale").getValue()).doubleValue(); + + return new JavaDimension(minY, maxY, piglinSafe, coordinateScale); + } } diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 994879f82..9ae1f6f49 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -44,7 +44,6 @@ import com.github.steveice10.mc.protocol.data.game.statistic.CustomStatistic; import com.github.steveice10.mc.protocol.data.game.statistic.Statistic; import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundClientInformationPacket; import com.github.steveice10.mc.protocol.packet.handshake.serverbound.ClientIntentionPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatCommandPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatCommandSignedPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosPacket; @@ -54,11 +53,7 @@ import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.Server import com.github.steveice10.mc.protocol.packet.login.serverbound.ServerboundCustomQueryAnswerPacket; import com.github.steveice10.packetlib.BuiltinFlags; import com.github.steveice10.packetlib.Session; -import com.github.steveice10.packetlib.event.session.ConnectedEvent; -import com.github.steveice10.packetlib.event.session.DisconnectedEvent; -import com.github.steveice10.packetlib.event.session.PacketErrorEvent; -import com.github.steveice10.packetlib.event.session.PacketSendingEvent; -import com.github.steveice10.packetlib.event.session.SessionAdapter; +import com.github.steveice10.packetlib.event.session.*; import com.github.steveice10.packetlib.packet.Packet; import com.github.steveice10.packetlib.tcp.TcpClientSession; import com.github.steveice10.packetlib.tcp.TcpSession; @@ -66,8 +61,6 @@ import io.netty.channel.Channel; import io.netty.channel.EventLoop; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -import it.unimi.dsi.fastutil.longs.Long2ObjectMap; -import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; @@ -146,7 +139,6 @@ import org.geysermc.geyser.session.cache.*; import org.geysermc.geyser.skin.FloodgateSkinUploader; import org.geysermc.geyser.text.GeyserLocale; import org.geysermc.geyser.text.MinecraftLocale; -import org.geysermc.geyser.text.TextDecoration; import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.util.ChunkUtils; @@ -158,16 +150,7 @@ import java.net.ConnectException; import java.net.InetSocketAddress; import java.nio.charset.StandardCharsets; import java.time.Instant; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.BitSet; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Queue; -import java.util.Set; -import java.util.UUID; +import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ScheduledFuture; @@ -214,6 +197,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { private final LodestoneCache lodestoneCache; private final PistonCache pistonCache; private final PreferencesCache preferencesCache; + private final RegistryCache registryCache; private final SkullCache skullCache; private final StructureBlockCache structureBlockCache; private final TagCache tagCache; @@ -263,12 +247,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { @Setter private ItemMappings itemMappings; - /** - * Stores the map between Java and Bedrock biome network IDs. - */ - @Setter - private int[] biomeTranslations = null; - /** * A map of Vector3i positions to Java entities. * Used for translating Bedrock block actions to Java entity actions. @@ -360,12 +338,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { @MonotonicNonNull @Setter private JavaDimension dimensionType = null; - /** - * All dimensions that the client could possibly connect to. - */ - private final Int2ObjectMap dimensions = new Int2ObjectOpenHashMap<>(4); - - private final Int2ObjectMap chatTypes = new Int2ObjectOpenHashMap<>(7); @Setter private int breakingBlock; @@ -619,6 +591,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { this.lodestoneCache = new LodestoneCache(); this.pistonCache = new PistonCache(this); this.preferencesCache = new PreferencesCache(this); + this.registryCache = new RegistryCache(this); this.skullCache = new SkullCache(this); this.structureBlockCache = new StructureBlockCache(); this.tagCache = new TagCache(); diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java new file mode 100644 index 000000000..44a5469b8 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.session.cache; + +import com.github.steveice10.mc.protocol.data.game.RegistryEntry; +import com.github.steveice10.mc.protocol.packet.configuration.clientbound.ClientboundRegistryDataPacket; +import it.unimi.dsi.fastutil.ints.Int2IntMap; +import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.experimental.Accessors; +import org.cloudburstmc.protocol.bedrock.data.TrimMaterial; +import org.cloudburstmc.protocol.bedrock.data.TrimPattern; +import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.inventory.recipe.TrimRecipe; +import org.geysermc.geyser.level.JavaDimension; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.text.TextDecoration; +import org.geysermc.geyser.translator.level.BiomeTranslator; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.function.ToIntFunction; + +/** + * Stores any information sent via Java registries. May not contain all data in a given registry - we'll strip what's + * unneeded. + * + * Crafted as of 1.20.5 for easy "add new registry" in the future. + */ +@Accessors(fluent = true) +@Getter +public final class RegistryCache { + private static final Map>> REGISTRIES = new HashMap<>(); + + static { + register("chat_type", cache -> cache.chatTypes, ($, entry) -> TextDecoration.readChatType(entry)); + register("dimension_type", cache -> cache.dimensions, ($, entry) -> JavaDimension.read(entry)); + register("trim_material", cache -> cache.trimMaterials, TrimRecipe::readTrimMaterial); + register("trim_pattern", cache -> cache.trimPatterns, TrimRecipe::readTrimPattern); + register("worldgen/biome", (cache, array) -> cache.biomeTranslations = array, BiomeTranslator::loadServerBiome); + } + + @Getter(AccessLevel.NONE) + private final GeyserSession session; + + /** + * Java -> Bedrock biome network IDs. + */ + private int[] biomeTranslations; + private final Int2ObjectMap chatTypes = new Int2ObjectOpenHashMap<>(7); + /** + * All dimensions that the client could possibly connect to. + */ + private final Int2ObjectMap dimensions = new Int2ObjectOpenHashMap<>(4); + private final Int2ObjectMap trimMaterials = new Int2ObjectOpenHashMap<>(); + private final Int2ObjectMap trimPatterns = new Int2ObjectOpenHashMap<>(); + + public RegistryCache(GeyserSession session) { + this.session = session; + } + + /** + * Loads a registry in, if we are tracking it. + */ + public void load(ClientboundRegistryDataPacket packet) { + var reader = REGISTRIES.get(packet.getRegistry()); + if (reader != null) { + reader.accept(this, packet.getEntries()); + } else { + GeyserImpl.getInstance().getLogger().debug("Ignoring registry of type " + packet.getRegistry()); + } + } + + /** + * @param registry the Java registry resource location, without the "minecraft:" prefix. + * @param localCacheFunction which local field in RegistryCache are we caching entries for this registry? + * @param reader converts the RegistryEntry NBT into a class file + * @param the class that represents these entries. + */ + private static void register(String registry, Function> localCacheFunction, BiFunction reader) { + REGISTRIES.put("minecraft:" + registry, (registryCache, entries) -> { + Int2ObjectMap localCache = localCacheFunction.apply(registryCache); + // Clear each local cache every time a new registry entry is given to us + localCache.clear(); + for (int i = 0; i < entries.size(); i++) { + RegistryEntry entry = entries.get(i); + // This is what Geyser wants to keep as a value for this registry. + T cacheEntry = reader.apply(registryCache.session, entry); + localCache.put(i, cacheEntry); + } + // Trim registry down to needed size + if (localCache instanceof Int2ObjectOpenHashMap hashMap) { + hashMap.trim(); + } + }); + } + + /** + * @param localCacheFunction the int array to set the final values to. + */ + private static void register(String registry, BiConsumer localCacheFunction, ToIntFunction reader) { + REGISTRIES.put("minecraft:" + registry, (registryCache, entries) -> { + Int2IntMap temp = new Int2IntOpenHashMap(); + int greatestId = 0; + for (int i = 0; i < entries.size(); i++) { + RegistryEntry entry = entries.get(i); + // This is what Geyser wants to keep as a value for this registry. + int cacheEntry = reader.applyAsInt(entry); + temp.put(i, cacheEntry); + if (i > greatestId) { + // Maximum registry ID, so far. Make sure the final array is at least this large. + greatestId = i; + } + } + + int[] array = new int[greatestId + 1]; + for (Int2IntMap.Entry entry : temp.int2IntEntrySet()) { + array[entry.getIntKey()] = entry.getIntValue(); + } + localCacheFunction.accept(registryCache, array); + }); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java b/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java index 121e1b2b9..bad55a5ca 100644 --- a/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java +++ b/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.text; +import com.github.steveice10.mc.protocol.data.game.RegistryEntry; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; @@ -87,6 +88,17 @@ public final class TextDecoration { '}'; } + public static TextDecoration readChatType(RegistryEntry entry) { + // Note: The ID is NOT ALWAYS THE SAME! ViaVersion as of 1.19 adds two registry entries that do NOT match vanilla. + CompoundTag tag = entry.getData(); + CompoundTag chat = tag.get("chat"); + TextDecoration textDecoration = null; + if (chat != null) { + textDecoration = new TextDecoration(chat); + } + return textDecoration; + } + public enum Parameter { CONTENT, SENDER, diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java index f05ed5ed1..fce928bdb 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java @@ -31,7 +31,9 @@ import com.github.steveice10.mc.protocol.data.game.chunk.DataPalette; import com.github.steveice10.mc.protocol.data.game.chunk.palette.GlobalPalette; import com.github.steveice10.mc.protocol.data.game.chunk.palette.Palette; import com.github.steveice10.mc.protocol.data.game.chunk.palette.SingletonPalette; -import it.unimi.dsi.fastutil.ints.*; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; +import it.unimi.dsi.fastutil.ints.IntLists; import org.geysermc.geyser.level.chunk.BlockStorage; import org.geysermc.geyser.level.chunk.bitarray.BitArray; import org.geysermc.geyser.level.chunk.bitarray.BitArrayVersion; @@ -39,58 +41,20 @@ import org.geysermc.geyser.level.chunk.bitarray.SingletonBitArray; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; -import java.util.List; - // Array index formula by https://wiki.vg/Chunk_Format public class BiomeTranslator { - public static void loadServerBiomes(GeyserSession session, List entries) { - Int2IntMap biomeTranslations = new Int2IntOpenHashMap(); - - int greatestBiomeId = 0; - for (int i = 0; i < entries.size(); i++) { - RegistryEntry entry = entries.get(i); - String javaIdentifier = entry.getId(); - int bedrockId = Registries.BIOME_IDENTIFIERS.get().getOrDefault(javaIdentifier, 0); - int javaId = i; - if (javaId > greatestBiomeId) { - greatestBiomeId = javaId; - } - - // TODO - the category tag no longer exists - find a better replacement option -// if (bedrockId == -1) { -// // There is no matching Bedrock variation for this biome; let's set the closest match based on biome category -// String category = ((StringTag) ((CompoundTag) biomeTag.get("element")).get("category")).getValue(); -// String replacementBiome = switch (category) { -// case "extreme_hills" -> "minecraft:mountains"; -// case "icy" -> "minecraft:ice_spikes"; -// case "mesa" -> "minecraft:badlands"; -// case "mushroom" -> "minecraft:mushroom_fields"; -// case "nether" -> "minecraft:nether_wastes"; -// default -> "minecraft:ocean"; // Typically ID 0 so a good default -// case "taiga", "jungle", "plains", "savanna", "the_end", "beach", "ocean", "desert", "river", "swamp" -> "minecraft:" + category; -// }; -// bedrockId = Registries.BIOME_IDENTIFIERS.get().getInt(replacementBiome); -// } - - // When we see the Java ID, we should instead apply the Bedrock ID - biomeTranslations.put(javaId, bedrockId); - - if (javaId == 0) { - // Matches Java behavior when it sees an invalid biome - it just replaces it with ID 0 - biomeTranslations.defaultReturnValue(bedrockId); - } - } - - int[] biomes = new int[greatestBiomeId + 1]; - for (Int2IntMap.Entry entry : biomeTranslations.int2IntEntrySet()) { - biomes[entry.getIntKey()] = entry.getIntValue(); - } - session.setBiomeTranslations(biomes); + public static int loadServerBiome(RegistryEntry entry) { + String javaIdentifier = entry.getId(); + return Registries.BIOME_IDENTIFIERS.get().getOrDefault(javaIdentifier, 0); +// if (javaId == 0) { +// // Matches Java behavior when it sees an invalid biome - it just replaces it with ID 0 +// biomeTranslations.defaultReturnValue(bedrockId); +// } } public static BlockStorage toNewBedrockBiome(GeyserSession session, DataPalette biomeData) { - int[] biomeTranslations = session.getBiomeTranslations(); + int[] biomeTranslations = session.getRegistryCache().biomeTranslations(); // As of 1.17.10: the client expects the same format as a chunk but filled with biomes // As of 1.18 this is the same as Java Edition diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRegistryDataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRegistryDataTranslator.java index 5d9bbff7d..ddb9c76b7 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRegistryDataTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRegistryDataTranslator.java @@ -25,49 +25,16 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.data.game.RegistryEntry; import com.github.steveice10.mc.protocol.packet.configuration.clientbound.ClientboundRegistryDataPacket; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import org.geysermc.geyser.level.JavaDimension; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.text.TextDecoration; -import org.geysermc.geyser.translator.level.BiomeTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; -import java.util.List; - @Translator(packet = ClientboundRegistryDataPacket.class) public class JavaRegistryDataTranslator extends PacketTranslator { @Override public void translate(GeyserSession session, ClientboundRegistryDataPacket packet) { - if (packet.getRegistry().equals("minecraft:dimension_type")) { - Int2ObjectMap dimensions = session.getDimensions(); - dimensions.clear(); - JavaDimension.load(packet.getEntries(), dimensions); - } - - if (packet.getRegistry().equals("minecraft:chat_type")) { - Int2ObjectMap chatTypes = session.getChatTypes(); - chatTypes.clear(); - List entries = packet.getEntries(); - for (int i = 0; i < entries.size(); i++) { - // The ID is NOT ALWAYS THE SAME! ViaVersion as of 1.19 adds two registry entries that do NOT match vanilla. - RegistryEntry entry = entries.get(i); - CompoundTag tag = entry.getData(); - CompoundTag chat = tag.get("chat"); - TextDecoration textDecoration = null; - if (chat != null) { - textDecoration = new TextDecoration(chat); - } - chatTypes.put(i, textDecoration); - } - } - - if (packet.getRegistry().equals("minecraft:worldgen/biome")) { - BiomeTranslator.loadServerBiomes(session, packet.getEntries()); - } + session.getRegistryCache().load(packet); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java index aca02feab..20b223248 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java @@ -269,8 +269,8 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator Date: Mon, 22 Apr 2024 22:49:46 -0400 Subject: [PATCH 088/272] Banners --- .../geyser/inventory/item/BannerPattern.java | 104 +++++++++++++ .../geyser/inventory/item/DyeColor.java | 75 +++++++++ .../geysermc/geyser/item/type/BannerItem.java | 145 ++++++++++++------ .../geyser/session/cache/RegistryCache.java | 4 + .../inventory/LoomInventoryTranslator.java | 27 +--- .../entity/BannerBlockEntityTranslator.java | 4 +- .../bedrock/BedrockBookEditTranslator.java | 1 + 7 files changed, 295 insertions(+), 65 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java create mode 100644 core/src/main/java/org/geysermc/geyser/inventory/item/DyeColor.java diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java b/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java new file mode 100644 index 000000000..442690d7d --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.inventory.item; + +import lombok.Getter; +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.Locale; + +@Getter +public enum BannerPattern { + BASE("b"), + SQUARE_BOTTOM_LEFT("bl"), + SQUARE_BOTTOM_RIGHT("br"), + SQUARE_TOP_LEFT("tl"), + SQUARE_TOP_RIGHT("tr"), + STRIPE_BOTTOM("bs"), + STRIPE_TOP("ts"), + STRIPE_LEFT("ls"), + STRIPE_RIGHT("rs"), + STRIPE_CENTER("cs"), + STRIPE_MIDDLE("ms"), + STRIPE_DOWNRIGHT("drs"), + STRIPE_DOWNLEFT("dls"), + SMALL_STRIPES("ss"), + CROSS("cr"), + STRAIGHT_CROSS("sc"), + TRIANGLE_BOTTOM("bt"), + TRIANGLE_TOP("tt"), + TRIANGLES_BOTTOM("bts"), + TRIANGLES_TOP("tts"), + DIAGONAL_LEFT("ld"), + DIAGONAL_UP_RIGHT("rd"), + DIAGONAL_UP_LEFT("lud"), + DIAGONAL_RIGHT("rud"), + CIRCLE("mc"), + RHOMBUS("mr"), + HALF_VERTICAL("vh"), + HALF_HORIZONTAL("hh"), + HALF_VERTICAL_RIGHT("vhr"), + HALF_HORIZONTAL_BOTTOM("hhb"), + BORDER("bo"), + CURLY_BORDER("cbo"), + GRADIENT("gra"), + GRADIENT_UP("gru"), + BRICKS("bri"), + GLOBE("glb"), + CREEPER("cre"), + SKULL("sku"), + FLOWER("flo"), + MOJANG("moj"), + PIGLIN("pig"); + + private static final BannerPattern[] VALUES = values(); + + private final String javaIdentifier; + private final String bedrockIdentifier; + + BannerPattern(String bedrockIdentifier) { + this.javaIdentifier = "minecraft:" + this.name().toLowerCase(Locale.ROOT); + this.bedrockIdentifier = bedrockIdentifier; + } + + public static @Nullable BannerPattern getByJavaIdentifier(String javaIdentifier) { + for (BannerPattern bannerPattern : VALUES) { + if (bannerPattern.javaIdentifier.equals(javaIdentifier)) { + return bannerPattern; + } + } + return null; + } + + public static @Nullable BannerPattern getByBedrockIdentifier(String bedrockIdentifier) { + for (BannerPattern bannerPattern : VALUES) { + if (bannerPattern.bedrockIdentifier.equals(bedrockIdentifier)) { + return bannerPattern; + } + } + return null; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/DyeColor.java b/core/src/main/java/org/geysermc/geyser/inventory/item/DyeColor.java new file mode 100644 index 000000000..e2649a343 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/DyeColor.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.inventory.item; + +import lombok.Getter; +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.Locale; + +@Getter +public enum DyeColor { + WHITE, + ORANGE, + MAGENTA, + LIGHT_BLUE, + YELLOW, + LIME, + PINK, + GRAY, + LIGHT_GRAY, + CYAN, + PURPLE, + BLUE, + BROWN, + GREEN, + RED, + BLACK; + + private static final DyeColor[] VALUES = values(); + + private final String javaIdentifier; + + DyeColor() { + this.javaIdentifier = this.name().toLowerCase(Locale.ROOT); + } + + public static @Nullable DyeColor getById(int id) { + if (id >= 0 && id < VALUES.length) { + return VALUES[id]; + } + return null; + } + + public static @Nullable DyeColor getByJavaIdentifier(String javaIdentifier) { + for (DyeColor dyeColor : VALUES) { + if (dyeColor.javaIdentifier.equals(javaIdentifier)) { + return dyeColor; + } + } + return null; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index 32806c3c2..0d8050dec 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -28,14 +28,14 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.protocol.data.game.item.component.BannerPatternLayer; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.IntTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import com.github.steveice10.opennbt.tag.builtin.*; +import it.unimi.dsi.fastutil.Pair; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtList; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtType; +import org.geysermc.geyser.inventory.item.BannerPattern; +import org.geysermc.geyser.inventory.item.DyeColor; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; @@ -51,20 +51,48 @@ public class BannerItem extends BlockItem { * ominous banners that we set instead. This variable is used to detect Java ominous banner patterns, and apply * the correct ominous banner pattern if Bedrock pulls the item from creative. */ - public static final List OMINOUS_BANNER_PATTERN; + private static final List> OMINOUS_BANNER_PATTERN; + private static final ListTag OMINOUS_BANNER_PATTERN_BLOCK; static { // Construct what an ominous banner is supposed to look like OMINOUS_BANNER_PATTERN = List.of( -// new BannerPatternLayer("mr", 9), -// new BannerPatternLayer("bs", 8), -// new BannerPatternLayer("cs", 7), -// new BannerPatternLayer("bo", 8), -// new BannerPatternLayer("ms", 15), -// new BannerPatternLayer("hh", 8), -// new BannerPatternLayer("mc", 8), -// new BannerPatternLayer("bo", 15) + Pair.of(BannerPattern.RHOMBUS, DyeColor.CYAN), + Pair.of(BannerPattern.STRIPE_BOTTOM, DyeColor.LIGHT_GRAY), + Pair.of(BannerPattern.STRIPE_CENTER, DyeColor.GRAY), + Pair.of(BannerPattern.BORDER, DyeColor.LIGHT_GRAY), + Pair.of(BannerPattern.STRIPE_MIDDLE, DyeColor.BLACK), + Pair.of(BannerPattern.HALF_HORIZONTAL, DyeColor.LIGHT_GRAY), + Pair.of(BannerPattern.CIRCLE, DyeColor.LIGHT_GRAY), + Pair.of(BannerPattern.BORDER, DyeColor.BLACK) ); + + OMINOUS_BANNER_PATTERN_BLOCK = new ListTag("patterns"); + for (Pair pair : OMINOUS_BANNER_PATTERN) { + OMINOUS_BANNER_PATTERN_BLOCK.add(getJavaBannerPatternTag(pair.left(), pair.right())); + } + } + + public static boolean isOminous(GeyserSession session, List patternLayers) { + if (OMINOUS_BANNER_PATTERN.size() != patternLayers.size()) { + return false; + } + for (int i = 0; i < OMINOUS_BANNER_PATTERN.size(); i++) { + BannerPatternLayer patternLayer = patternLayers.get(i); + Pair pair = OMINOUS_BANNER_PATTERN.get(i); + if (!patternLayer.getPattern().isId() || patternLayer.getColorId() != pair.right().ordinal()) { + return false; + } + BannerPattern bannerPattern = session.getRegistryCache().bannerPatterns().get(patternLayer.getPattern().id()); + if (bannerPattern != pair.left()) { + return false; + } + } + return true; + } + + public static boolean isOminous(ListTag blockEntityPatterns) { + return OMINOUS_BANNER_PATTERN_BLOCK.equals(blockEntityPatterns); } /** @@ -76,7 +104,10 @@ public class BannerItem extends BlockItem { public static NbtList convertBannerPattern(ListTag patterns) { List tagsList = new ArrayList<>(); for (Tag patternTag : patterns.getValue()) { - tagsList.add(getBedrockBannerPattern((CompoundTag) patternTag)); + NbtMap bedrockBannerPattern = getBedrockBannerPattern((CompoundTag) patternTag); + if (bedrockBannerPattern != null) { + tagsList.add(bedrockBannerPattern); + } } return new NbtList<>(NbtType.COMPOUND, tagsList); @@ -88,35 +119,41 @@ public class BannerItem extends BlockItem { * @param pattern Java edition pattern nbt * @return The Bedrock edition format pattern nbt */ - @NonNull private static NbtMap getBedrockBannerPattern(CompoundTag pattern) { + BannerPattern bannerPattern = BannerPattern.getByJavaIdentifier((String) pattern.get("pattern").getValue()); + DyeColor dyeColor = DyeColor.getByJavaIdentifier((String) pattern.get("color").getValue()); + if (bannerPattern == null || dyeColor == null) { + return null; + } + return NbtMap.builder() - .putInt("Color", 15 - (int) pattern.get("Color").getValue()) - .putString("Pattern", (String) pattern.get("Pattern").getValue()) + .putString("Pattern", bannerPattern.getBedrockIdentifier()) + .putInt("Color", 15 - dyeColor.ordinal()) .build(); } + public static CompoundTag getJavaBannerPatternTag(BannerPattern bannerPattern, DyeColor dyeColor) { + CompoundTag tag = new CompoundTag(""); + tag.put(new StringTag("pattern", bannerPattern.getJavaIdentifier())); + tag.put(new StringTag("color", dyeColor.getJavaIdentifier())); + return tag; + } + /** * Convert the Bedrock edition banner pattern nbt to Java edition * * @param pattern Bedrock edition pattern nbt - * @return The Java edition format pattern nbt + * @return The Java edition format pattern layer */ - public static CompoundTag getJavaBannerPattern(NbtMap pattern) { - //return new BannerPatternLayer(0/*pattern.getString("Pattern")*/, 15 - pattern.getInt("Color")); - return null; - } - - /** - * Convert a list of patterns from Java nbt to Bedrock nbt, or vice versa (we just need to invert the color) - * - * @param patterns The patterns to convert - */ - private void invertBannerColors(ListTag patterns) { - for (Tag patternTag : patterns.getValue()) { - IntTag color = ((CompoundTag) patternTag).get("Color"); - color.setValue(15 - color.getValue()); + public static BannerPatternLayer getJavaBannerPattern(GeyserSession session, NbtMap pattern) { + return null; // TODO + /*Int2ObjectBiMap registry = session.getRegistryCache().bannerPatterns(); + BannerPattern bannerPattern = BannerPattern.getByBedrockIdentifier(pattern.getString("Pattern")); + DyeColor dyeColor = DyeColor.getById(15 - pattern.getInt("Color")); + if (bannerPattern != null && dyeColor != null && registry.containsValue(bannerPattern)) { + return new BannerPatternLayer(Holder.ofId(registry.get(bannerPattern)), dyeColor.ordinal()); } + return null;*/ } public BannerItem(String javaIdentifier, Builder builder) { @@ -129,31 +166,51 @@ public class BannerItem extends BlockItem { List patterns = components.get(DataComponentType.BANNER_PATTERNS); if (patterns != null) { -// if (patterns.equals(OMINOUS_BANNER_PATTERN)) { -// // Remove the current patterns and set the ominous banner type -// builder.putInt("Type", 1); -// } else { -// invertBannerColors(patterns); -// tag.put(patterns); -// } + if (isOminous(session, patterns)) { + // Remove the current patterns and set the ominous banner type + builder.putInt("Type", 1); + } else { + List patternList = new ArrayList<>(patterns.size()); + for (BannerPatternLayer patternLayer : patterns) { + patternLayer.getPattern().ifId(holder -> { + BannerPattern bannerPattern = session.getRegistryCache().bannerPatterns().get(holder.id()); + if (bannerPattern != null) { + NbtMap tag = NbtMap.builder() + .putString("Pattern", bannerPattern.getBedrockIdentifier()) + .putInt("Color", 15 - patternLayer.getColorId()) + .build(); + patternList.add(tag); + } + }); + } + builder.putList("Patterns", NbtType.COMPOUND, patternList); + } } } @Override - public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { + public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { // TODO super.translateNbtToJava(tag, mapping); if (tag.get("Type") instanceof IntTag type && type.getValue() == 1) { // Ominous banner pattern tag.remove("Type"); CompoundTag blockEntityTag = new CompoundTag("BlockEntityTag"); - //blockEntityTag.put(OMINOUS_BANNER_PATTERN); + blockEntityTag.put(OMINOUS_BANNER_PATTERN_BLOCK); tag.put(blockEntityTag); - } else if (tag.get("Patterns") instanceof ListTag patterns) { + } else if (tag.get("Patterns") instanceof ListTag patterns && patterns.getElementType() == CompoundTag.class) { CompoundTag blockEntityTag = new CompoundTag("BlockEntityTag"); - invertBannerColors(patterns); - blockEntityTag.put(patterns); + + ListTag javaPatterns = new ListTag("patterns"); + for (Tag pattern : patterns.getValue()) { + BannerPattern bannerPattern = BannerPattern.getByBedrockIdentifier((String) ((CompoundTag) pattern).get("Pattern").getValue()); + DyeColor dyeColor = DyeColor.getById((int) ((CompoundTag) pattern).get("Color").getValue()); + if (bannerPattern != null && dyeColor != null) { + javaPatterns.add(getJavaBannerPatternTag(bannerPattern, dyeColor)); + } + } + blockEntityTag.put(javaPatterns); tag.put(blockEntityTag); tag.remove("Patterns"); // Remove the old Bedrock patterns list diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java index 44a5469b8..6f69574ed 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java @@ -37,6 +37,7 @@ import lombok.experimental.Accessors; import org.cloudburstmc.protocol.bedrock.data.TrimMaterial; import org.cloudburstmc.protocol.bedrock.data.TrimPattern; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.inventory.item.BannerPattern; import org.geysermc.geyser.inventory.recipe.TrimRecipe; import org.geysermc.geyser.level.JavaDimension; import org.geysermc.geyser.session.GeyserSession; @@ -68,6 +69,7 @@ public final class RegistryCache { register("trim_material", cache -> cache.trimMaterials, TrimRecipe::readTrimMaterial); register("trim_pattern", cache -> cache.trimPatterns, TrimRecipe::readTrimPattern); register("worldgen/biome", (cache, array) -> cache.biomeTranslations = array, BiomeTranslator::loadServerBiome); + register("banner_pattern", cache -> cache.bannerPatterns, ($, entry) -> BannerPattern.getByJavaIdentifier(entry.getId())); } @Getter(AccessLevel.NONE) @@ -85,6 +87,8 @@ public final class RegistryCache { private final Int2ObjectMap trimMaterials = new Int2ObjectOpenHashMap<>(); private final Int2ObjectMap trimPatterns = new Int2ObjectOpenHashMap<>(); + private final Int2ObjectMap bannerPatterns = new Int2ObjectOpenHashMap<>(); + public RegistryCache(GeyserSession session) { this.session = session; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java index 6c7a11ff2..636a7982a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.translator.inventory; +import com.github.steveice10.mc.protocol.data.game.item.component.BannerPatternLayer; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import org.cloudburstmc.nbt.NbtMap; @@ -51,7 +51,7 @@ import org.geysermc.geyser.item.type.BannerItem; import org.geysermc.geyser.item.type.DyeItem; import org.geysermc.geyser.session.GeyserSession; -import java.util.Collections; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -159,23 +159,12 @@ public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator { if (inputCopy.getComponents() == null) { inputCopy.setComponents(new DataComponents(new HashMap<>())); } - //TODO - CompoundTag blockEntityTag = inputCopy.getNbt().get("BlockEntityTag"); - CompoundTag javaBannerPattern = BannerItem.getJavaBannerPattern(pattern); - if (blockEntityTag != null) { - ListTag patternsList = blockEntityTag.get("Patterns"); - if (patternsList != null) { - patternsList.add(javaBannerPattern); - } else { - patternsList = new ListTag("Patterns", Collections.singletonList(javaBannerPattern)); - blockEntityTag.put(patternsList); - } - } else { - blockEntityTag = new CompoundTag("BlockEntityTag"); - ListTag patternsList = new ListTag("Patterns", Collections.singletonList(javaBannerPattern)); - blockEntityTag.put(patternsList); - inputCopy.getNbt().put(blockEntityTag); + BannerPatternLayer bannerPatternLayer = BannerItem.getJavaBannerPattern(session, pattern); // TODO + if (bannerPatternLayer != null) { + List patternsList = inputCopy.getComponents().getOrDefault(DataComponentType.BANNER_PATTERNS, new ArrayList<>()); + patternsList.add(bannerPatternLayer); + inputCopy.getComponents().put(DataComponentType.BANNER_PATTERNS, patternsList); } // Set the new item as the output diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java index f23433bbe..e0e0130c5 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java @@ -46,8 +46,8 @@ public class BannerBlockEntityTranslator extends BlockEntityTranslator implement return; } - if (tag.get("Patterns") instanceof ListTag patterns) { - if (patterns.equals(BannerItem.OMINOUS_BANNER_PATTERN)) { + if (tag.get("patterns") instanceof ListTag patterns) { + if (BannerItem.isOminous(patterns)) { // This is an ominous banner; don't try to translate the raw patterns (it doesn't translate correctly) // and tell the Bedrock client that this is an ominous banner builder.putInt("Type", 1); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java index 4350f6a83..10024c02f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java @@ -105,6 +105,7 @@ public class BedrockBookEditTranslator extends PacketTranslator break; } case SIGN_BOOK: { + // As of JE 1.20.5, client no longer adds title and author on its own break; } default: From 1bdbcab4e8fc8a8373b13cdf962eb17e7fccaa02 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Tue, 23 Apr 2024 00:44:20 -0400 Subject: [PATCH 089/272] Wolf variants --- .../geyser/entity/EntityDefinitions.java | 1 + .../living/animal/tameable/WolfEntity.java | 41 +++++++++++++++++++ .../geysermc/geyser/item/type/BannerItem.java | 3 +- .../geyser/session/cache/RegistryCache.java | 3 ++ 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index e9d49fbd8..6b243212d 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -971,6 +971,7 @@ public final class EntityDefinitions { .addTranslator(MetadataType.BOOLEAN, (wolfEntity, entityMetadata) -> wolfEntity.setFlag(EntityFlag.INTERESTED, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue())) .addTranslator(MetadataType.INT, WolfEntity::setCollarColor) .addTranslator(MetadataType.INT, WolfEntity::setWolfAngerTime) + .addTranslator(MetadataType.WOLF_VARIANT, WolfEntity::setWolfVariant) .build(); // As of 1.18 these don't track entity data at all diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java index c75247fdf..ee7281772 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java @@ -29,6 +29,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEnti import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -43,6 +44,7 @@ import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; import java.util.Collections; +import java.util.Locale; import java.util.Set; import java.util.UUID; @@ -102,6 +104,15 @@ public class WolfEntity extends TameableEntity { dirtyMetadata.put(EntityDataTypes.COLOR, time != 0 ? (byte) 0 : collarColor); } + // 1.20.5+ + public void setWolfVariant(IntEntityMetadata entityMetadata) { + WolfVariant wolfVariant = session.getRegistryCache().wolfVariants().get(entityMetadata.getPrimitiveValue()); + if (wolfVariant == null) { + wolfVariant = WolfVariant.PALE; + } + dirtyMetadata.put(EntityDataTypes.VARIANT, wolfVariant.ordinal()); + } + @Override public boolean canEat(Item item) { // Cannot be a baby to eat these foods @@ -147,4 +158,34 @@ public class WolfEntity extends TameableEntity { return InteractionResult.PASS; } } + + // Ordered by bedrock id + public enum WolfVariant { + PALE, + ASHEN, + BLACK, + CHESTNUT, + RUSTY, + SNOWY, + SPOTTED, + STRIPED, + WOODS; + + private static final WolfVariant[] VALUES = values(); + + private final String javaIdentifier; + + WolfVariant() { + this.javaIdentifier = "minecraft:" + this.name().toLowerCase(Locale.ROOT); + } + + public static @Nullable WolfVariant getByJavaIdentifier(String javaIdentifier) { + for (WolfVariant wolfVariant : VALUES) { + if (wolfVariant.javaIdentifier.equals(javaIdentifier)) { + return wolfVariant; + } + } + return null; + } + } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index 0d8050dec..fe378d4c6 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -80,7 +80,8 @@ public class BannerItem extends BlockItem { for (int i = 0; i < OMINOUS_BANNER_PATTERN.size(); i++) { BannerPatternLayer patternLayer = patternLayers.get(i); Pair pair = OMINOUS_BANNER_PATTERN.get(i); - if (!patternLayer.getPattern().isId() || patternLayer.getColorId() != pair.right().ordinal()) { + if (patternLayer.getColorId() != pair.right().ordinal() || + !patternLayer.getPattern().isId()) { return false; } BannerPattern bannerPattern = session.getRegistryCache().bannerPatterns().get(patternLayer.getPattern().id()); diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java index 6f69574ed..d5293c5c3 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java @@ -37,6 +37,7 @@ import lombok.experimental.Accessors; import org.cloudburstmc.protocol.bedrock.data.TrimMaterial; import org.cloudburstmc.protocol.bedrock.data.TrimPattern; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.entity.type.living.animal.tameable.WolfEntity; import org.geysermc.geyser.inventory.item.BannerPattern; import org.geysermc.geyser.inventory.recipe.TrimRecipe; import org.geysermc.geyser.level.JavaDimension; @@ -70,6 +71,7 @@ public final class RegistryCache { register("trim_pattern", cache -> cache.trimPatterns, TrimRecipe::readTrimPattern); register("worldgen/biome", (cache, array) -> cache.biomeTranslations = array, BiomeTranslator::loadServerBiome); register("banner_pattern", cache -> cache.bannerPatterns, ($, entry) -> BannerPattern.getByJavaIdentifier(entry.getId())); + register("wolf_variant", cache -> cache.wolfVariants, ($, entry) -> WolfEntity.WolfVariant.getByJavaIdentifier(entry.getId())); } @Getter(AccessLevel.NONE) @@ -88,6 +90,7 @@ public final class RegistryCache { private final Int2ObjectMap trimPatterns = new Int2ObjectOpenHashMap<>(); private final Int2ObjectMap bannerPatterns = new Int2ObjectOpenHashMap<>(); + private final Int2ObjectMap wolfVariants = new Int2ObjectOpenHashMap<>(); public RegistryCache(GeyserSession session) { this.session = session; From 3f499e3ec05592510a9cdeca0e642478a435cf17 Mon Sep 17 00:00:00 2001 From: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> Date: Tue, 23 Apr 2024 03:09:42 -0700 Subject: [PATCH 090/272] Start on custom skulls Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> --- .../geyser/skin/FakeHeadProvider.java | 86 ++++++++++++------- .../inventory/InventoryTranslator.java | 2 +- .../inventory/PlayerInventoryTranslator.java | 4 +- .../translator/item/ItemTranslator.java | 36 +++++--- .../entity/SkullBlockEntityTranslator.java | 1 + .../entity/JavaSetEquipmentTranslator.java | 20 +++-- .../JavaLevelChunkWithLightTranslator.java | 1 + 7 files changed, 96 insertions(+), 54 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/skin/FakeHeadProvider.java b/core/src/main/java/org/geysermc/geyser/skin/FakeHeadProvider.java index c7bd235b2..2d6345bfa 100644 --- a/core/src/main/java/org/geysermc/geyser/skin/FakeHeadProvider.java +++ b/core/src/main/java/org/geysermc/geyser/skin/FakeHeadProvider.java @@ -25,9 +25,13 @@ package org.geysermc.geyser.skin; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import com.github.steveice10.mc.auth.data.GameProfile; +import com.github.steveice10.mc.auth.data.GameProfile.Texture; +import com.github.steveice10.mc.auth.data.GameProfile.TextureModel; +import com.github.steveice10.mc.auth.data.GameProfile.TextureType; +import com.github.steveice10.mc.auth.exception.property.PropertyException; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; @@ -39,11 +43,13 @@ import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.entity.type.LivingEntity; import org.geysermc.geyser.entity.type.player.PlayerEntity; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.skin.SkinManager.GameProfileData; import org.geysermc.geyser.text.GeyserLocale; import java.awt.*; import java.awt.image.BufferedImage; import java.io.IOException; +import java.util.Map; import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; @@ -95,38 +101,60 @@ public class FakeHeadProvider { } }); - public static void setHead(GeyserSession session, PlayerEntity entity, Tag skullOwner) { - if (skullOwner == null) { + public static void setHead(GeyserSession session, PlayerEntity entity, DataComponents components) { + GameProfile profile = components.get(DataComponentType.PROFILE); + + if (profile == null) { return; } - if (skullOwner instanceof CompoundTag profileTag) { - SkinManager.GameProfileData gameProfileData = SkinManager.GameProfileData.from(profileTag); - if (gameProfileData == null) { + + Map textures = null; + try { + textures = profile.getTextures(false); + } catch (PropertyException e) { + session.getGeyser().getLogger().debug("Failed to get textures from GameProfile: " + e); + } + + if (textures == null || textures.isEmpty()) { + loadHead(session, entity, profile.getName()); + return; + } + + Texture skinTexture = textures.get(TextureType.SKIN); + + if (skinTexture == null) { + return; + } + + Texture capeTexture = textures.get(TextureType.CAPE); + String capeUrl = capeTexture != null ? capeTexture.getURL() : null; + + boolean isAlex = skinTexture.getModel() == TextureModel.SLIM; + + loadHead(session, entity, new GameProfileData(skinTexture.getURL(), capeUrl, isAlex)); + } + + public static void loadHead(GeyserSession session, PlayerEntity entity, String owner) { + if (owner == null || owner.isEmpty()) { + return; + } + + CompletableFuture completableFuture = SkinProvider.requestTexturesFromUsername(owner); + completableFuture.whenCompleteAsync((encodedJson, throwable) -> { + if (throwable != null) { + GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.skin.fail", entity.getUuid()), throwable); return; } - loadHead(session, entity, gameProfileData); - } else if (skullOwner instanceof StringTag ownerTag) { - String owner = ownerTag.getValue(); - if (owner.isEmpty()) { - return; - } - CompletableFuture completableFuture = SkinProvider.requestTexturesFromUsername(owner); - completableFuture.whenCompleteAsync((encodedJson, throwable) -> { - if (throwable != null) { - GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.skin.fail", entity.getUuid()), throwable); + try { + SkinManager.GameProfileData gameProfileData = SkinManager.GameProfileData.loadFromJson(encodedJson); + if (gameProfileData == null) { return; } - try { - SkinManager.GameProfileData gameProfileData = SkinManager.GameProfileData.loadFromJson(encodedJson); - if (gameProfileData == null) { - return; - } - loadHead(session, entity, gameProfileData); - } catch (IOException e) { - GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.skin.fail", entity.getUuid(), e.getMessage())); - } - }); - } + loadHead(session, entity, gameProfileData); + } catch (IOException e) { + GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.skin.fail", entity.getUuid(), e.getMessage())); + } + }); } public static void loadHead(GeyserSession session, PlayerEntity entity, SkinManager.GameProfileData gameProfileData) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java index 2d7a1ae5a..4a3e31b30 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java @@ -225,7 +225,7 @@ public abstract class InventoryTranslator { GeyserItemStack javaItem = inventory.getItem(sourceSlot); if (javaItem.asItem() == Items.PLAYER_HEAD && javaItem.getNbt() != null) { - FakeHeadProvider.setHead(session, session.getPlayerEntity(), javaItem.getNbt().get("SkullOwner")); + FakeHeadProvider.setHead(session, session.getPlayerEntity(), javaItem.getComponents()); } } else if (sourceSlot == 5) { //we are probably removing the head, so restore the original skin diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java index b461c7afc..36d10aa54 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java @@ -100,7 +100,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator { if (i == 5 && item.asItem() == Items.PLAYER_HEAD && item.getNbt() != null) { - FakeHeadProvider.setHead(session, session.getPlayerEntity(), item.getNbt().get("SkullOwner")); + FakeHeadProvider.setHead(session, session.getPlayerEntity(), item.getComponents()); } } armorContentPacket.setContents(Arrays.asList(contents)); @@ -144,7 +144,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator { // Check for custom skull if (javaItem.asItem() == Items.PLAYER_HEAD && javaItem.getNbt() != null) { - FakeHeadProvider.setHead(session, session.getPlayerEntity(), javaItem.getNbt().get("SkullOwner")); + FakeHeadProvider.setHead(session, session.getPlayerEntity(), javaItem.getComponents()); } else { FakeHeadProvider.restoreOriginalSkin(session, session.getPlayerEntity()); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index c96542fc1..a8e9e1c52 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -26,6 +26,9 @@ package org.geysermc.geyser.translator.item; import com.github.steveice10.mc.auth.data.GameProfile; +import com.github.steveice10.mc.auth.data.GameProfile.Texture; +import com.github.steveice10.mc.auth.data.GameProfile.TextureType; +import com.github.steveice10.mc.auth.exception.property.PropertyException; import com.github.steveice10.mc.protocol.data.game.Identifier; import com.github.steveice10.mc.protocol.data.game.entity.attribute.ModifierOperation; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; @@ -553,21 +556,28 @@ public final class ItemTranslator { if (components == null) { return null; } - //TODO + GameProfile profile = components.get(DataComponentType.PROFILE); if (profile != null) { -// if (!(nbt.get("SkullOwner") instanceof CompoundTag skullOwner)) { -// // It's a username give up d: -// return null; -// } -// SkinManager.GameProfileData data = SkinManager.GameProfileData.from(skullOwner); -// if (data == null) { -// session.getGeyser().getLogger().debug("Not sure how to handle skull head item display. " + nbt); -// return null; -// } -// -// String skinHash = data.skinUrl().substring(data.skinUrl().lastIndexOf('/') + 1); -// return BlockRegistries.CUSTOM_SKULLS.get(skinHash); + Map textures = null; + try { + textures = profile.getTextures(false); + } catch (PropertyException e) { + session.getGeyser().getLogger().debug("Failed to get textures from GameProfile: " + e); + } + + if (textures == null || textures.isEmpty()) { + return null; + } + + Texture skinTexture = textures.get(TextureType.SKIN); + + if (skinTexture == null) { + return null; + } + + String skinHash = skinTexture.getURL().substring(skinTexture.getURL().lastIndexOf('/') + 1); + return BlockRegistries.CUSTOM_SKULLS.get(skinHash); } return null; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java index 9ac9126db..e9aceece5 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java @@ -101,6 +101,7 @@ public class SkullBlockEntityTranslator extends BlockEntityTranslator implements } public static @Nullable BlockDefinition translateSkull(GeyserSession session, CompoundTag tag, Vector3i blockPosition, int blockState) { + // TODO: The tag layout follows new format (profille, etc...) CompoundTag owner = tag.get("SkullOwner"); if (owner == null) { session.getSkullCache().removeSkull(blockPosition); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java index 6178a51e8..b0168a4ce 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java @@ -31,7 +31,10 @@ import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.Client import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.LivingEntity; +import org.geysermc.geyser.entity.type.player.PlayerEntity; +import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.skin.FakeHeadProvider; import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; @@ -59,15 +62,14 @@ public class JavaSetEquipmentTranslator extends PacketTranslator { ItemStack javaItem = equipment.getItem(); - // TODO -// if (livingEntity instanceof PlayerEntity -// && javaItem != null -// && javaItem.getId() == Items.PLAYER_HEAD.javaId() -// && javaItem.getNbt() != null) { -// FakeHeadProvider.setHead(session, (PlayerEntity) livingEntity, javaItem.getNbt().get("SkullOwner")); -// } else { -// FakeHeadProvider.restoreOriginalSkin(session, livingEntity); -// } + if (livingEntity instanceof PlayerEntity + && javaItem != null + && javaItem.getId() == Items.PLAYER_HEAD.javaId() + && javaItem.getDataComponents() != null) { + FakeHeadProvider.setHead(session, (PlayerEntity) livingEntity, javaItem.getDataComponents()); + } else { + FakeHeadProvider.restoreOriginalSkin(session, livingEntity); + } livingEntity.setHelmet(item); armorUpdated = true; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java index e34c0d96d..fc1d0316c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java @@ -425,6 +425,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator Date: Tue, 23 Apr 2024 06:13:19 -0400 Subject: [PATCH 091/272] Fix horse inventory --- .../inventory/JavaHorseScreenOpenTranslator.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaHorseScreenOpenTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaHorseScreenOpenTranslator.java index 58deaa0e9..33cfeaf31 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaHorseScreenOpenTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaHorseScreenOpenTranslator.java @@ -112,19 +112,23 @@ public class JavaHorseScreenOpenTranslator extends PacketTranslator slots = new ArrayList<>(); + // Since 1.20.5, the armor slot is not included in the container size, + // but everything is still indexed the same. + int slotCount = packet.getNumberOfSlots() + 1; + InventoryTranslator inventoryTranslator; if (entity instanceof LlamaEntity) { - inventoryTranslator = new LlamaInventoryTranslator(packet.getNumberOfSlots()); + inventoryTranslator = new LlamaInventoryTranslator(slotCount); slots.add(CARPET_SLOT); } else if (entity instanceof ChestedHorseEntity) { - inventoryTranslator = new DonkeyInventoryTranslator(packet.getNumberOfSlots()); + inventoryTranslator = new DonkeyInventoryTranslator(slotCount); slots.add(SADDLE_SLOT); } else if (entity instanceof CamelEntity) { // The camel has an invisible armor slot and needs special handling, same as the donkey - inventoryTranslator = new DonkeyInventoryTranslator(packet.getNumberOfSlots()); + inventoryTranslator = new DonkeyInventoryTranslator(slotCount); slots.add(SADDLE_SLOT); } else { - inventoryTranslator = new HorseInventoryTranslator(packet.getNumberOfSlots()); + inventoryTranslator = new HorseInventoryTranslator(slotCount); slots.add(SADDLE_SLOT); slots.add(ARMOR_SLOT); } @@ -136,6 +140,6 @@ public class JavaHorseScreenOpenTranslator extends PacketTranslator Date: Tue, 23 Apr 2024 17:57:03 +0200 Subject: [PATCH 092/272] init: pick item component change --- .../mod/world/GeyserModWorldManager.java | 50 +++++++++++++++++-- .../manager/GeyserSpigotWorldManager.java | 9 ++-- .../erosion/GeyserboundPacketHandlerImpl.java | 15 ++++-- .../geyser/level/GeyserWorldManager.java | 14 ++++-- .../geysermc/geyser/level/WorldManager.java | 4 +- .../BedrockBlockPickRequestTranslator.java | 27 +++------- gradle/libs.versions.toml | 2 +- 7 files changed, 79 insertions(+), 42 deletions(-) diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java index e9d612976..b9fbd6cdc 100644 --- a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java @@ -25,7 +25,10 @@ package org.geysermc.geyser.platform.mod.world; +import com.github.steveice10.mc.protocol.data.game.Holder; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; +import com.github.steveice10.mc.protocol.data.game.item.component.BannerPatternLayer; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; @@ -43,6 +46,7 @@ import net.minecraft.world.item.component.WrittenBookContent; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BannerBlockEntity; +import net.minecraft.world.level.block.entity.BannerPatternLayers; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.LecternBlockEntity; import net.minecraft.world.level.chunk.ChunkAccess; @@ -62,6 +66,7 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.BlockEntityUtils; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -217,8 +222,8 @@ public class GeyserModWorldManager extends GeyserWorldManager { @NonNull @Override - public CompletableFuture getPickItemNbt(GeyserSession session, int x, int y, int z, boolean addNbtData) { - CompletableFuture future = new CompletableFuture<>(); + public CompletableFuture getPickItemComponents(GeyserSession session, int x, int y, int z, boolean addNbtData) { + CompletableFuture future = new CompletableFuture<>(); server.execute(() -> { ServerPlayer player = getPlayer(session); if (player == null) { @@ -235,7 +240,22 @@ public class GeyserModWorldManager extends GeyserWorldManager { // the banner might have a custom name, both of which a Java client knows and caches ItemStack itemStack = banner.getItem(); - future.complete(null); // todo 1.20.5 + com.github.steveice10.mc.protocol.data.game.item.component.DataComponents components = + new com.github.steveice10.mc.protocol.data.game.item.component.DataComponents(new HashMap<>()); + + components.put(DataComponentType.DAMAGE, itemStack.getDamageValue()); + + Component customName = itemStack.getComponents().get(DataComponents.CUSTOM_NAME); + if (customName != null) { + components.put(DataComponentType.CUSTOM_NAME, toKyoriComponent(customName)); + } + + BannerPatternLayers pattern = itemStack.get(DataComponents.BANNER_PATTERNS); + if (pattern != null) { + components.put(DataComponentType.BANNER_PATTERNS, toPatternList(pattern)); + } + + future.complete(components); return; } future.complete(null); @@ -262,8 +282,7 @@ public class GeyserModWorldManager extends GeyserWorldManager { if (writtenBookContent != null) { return writtenBookContent.pages().stream() .map(Filterable::raw) - .map((component) -> Component.Serializer.toJson(component, RegistryAccess.EMPTY)) - .map((json -> LEGACY_SERIALIZER.serialize(GSON_SERIALIZER.deserializeOr(json, net.kyori.adventure.text.Component.empty())))) + .map(GeyserModWorldManager::fromComponent) .toList(); } else { WritableBookContent writableBookContent = itemStack.get(DataComponents.WRITABLE_BOOK_CONTENT); @@ -275,4 +294,25 @@ public class GeyserModWorldManager extends GeyserWorldManager { .toList(); } } + + private static String fromComponent(Component component) { + String json = Component.Serializer.toJson(component, RegistryAccess.EMPTY); + return LEGACY_SERIALIZER.serialize(GSON_SERIALIZER.deserializeOr(json, net.kyori.adventure.text.Component.empty())); + } + + private static net.kyori.adventure.text.Component toKyoriComponent(Component component) { + String json = Component.Serializer.toJson(component, RegistryAccess.EMPTY); + return GSON_SERIALIZER.deserializeOr(json, net.kyori.adventure.text.Component.empty()); + } + + private static List toPatternList(BannerPatternLayers patternLayers) { + return patternLayers.layers().stream() + .map(layer -> { + BannerPatternLayer.BannerPattern pattern = new BannerPatternLayer.BannerPattern( + layer.pattern().value().assetId().toString(), layer.pattern().value().translationKey() + ); + return new BannerPatternLayer(Holder.ofCustom(pattern), layer.color().getId()); + }) + .toList(); + } } diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java index 42f0d17f4..07a9d489a 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java @@ -26,8 +26,8 @@ package org.geysermc.geyser.platform.spigot.world.manager; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.World; @@ -39,7 +39,6 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMap; import org.geysermc.erosion.bukkit.BukkitLecterns; import org.geysermc.erosion.bukkit.BukkitUtils; -import org.geysermc.erosion.bukkit.PickBlockUtils; import org.geysermc.erosion.bukkit.SchedulerUtils; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.level.GameRule; @@ -205,8 +204,8 @@ public class GeyserSpigotWorldManager extends WorldManager { } @Override - public @NonNull CompletableFuture<@Nullable CompoundTag> getPickItemNbt(GeyserSession session, int x, int y, int z, boolean addNbtData) { - CompletableFuture<@Nullable CompoundTag> future = new CompletableFuture<>(); + public @NonNull CompletableFuture<@Nullable DataComponents> getPickItemComponents(GeyserSession session, int x, int y, int z, boolean addNbtData) { + CompletableFuture<@Nullable DataComponents> future = new CompletableFuture<>(); Player bukkitPlayer; if ((bukkitPlayer = Bukkit.getPlayer(session.getPlayerEntity().getUuid())) == null) { future.complete(null); @@ -215,7 +214,7 @@ public class GeyserSpigotWorldManager extends WorldManager { Block block = bukkitPlayer.getWorld().getBlockAt(x, y, z); // Paper 1.19.3 complains about async access otherwise. // java.lang.IllegalStateException: Tile is null, asynchronous access? - SchedulerUtils.runTask(this.plugin, () -> future.complete(PickBlockUtils.pickBlock(block)), block); + SchedulerUtils.runTask(this.plugin, () -> future.complete(/*PickBlockUtils.pickBlock(block)*/ null), block); // TODO fix erosion once clear how to handle this return future; } diff --git a/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java b/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java index 3ae458f63..57147fc49 100644 --- a/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java +++ b/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.erosion; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.level.block.value.PistonValueType; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import io.netty.channel.Channel; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; @@ -43,7 +43,14 @@ import org.geysermc.erosion.packet.ErosionPacketHandler; import org.geysermc.erosion.packet.ErosionPacketSender; import org.geysermc.erosion.packet.backendbound.BackendboundInitializePacket; import org.geysermc.erosion.packet.backendbound.BackendboundPacket; -import org.geysermc.erosion.packet.geyserbound.*; +import org.geysermc.erosion.packet.geyserbound.GeyserboundBatchBlockIdPacket; +import org.geysermc.erosion.packet.geyserbound.GeyserboundBlockEntityPacket; +import org.geysermc.erosion.packet.geyserbound.GeyserboundBlockIdPacket; +import org.geysermc.erosion.packet.geyserbound.GeyserboundBlockLookupFailPacket; +import org.geysermc.erosion.packet.geyserbound.GeyserboundBlockPlacePacket; +import org.geysermc.erosion.packet.geyserbound.GeyserboundHandshakePacket; +import org.geysermc.erosion.packet.geyserbound.GeyserboundPickBlockPacket; +import org.geysermc.erosion.packet.geyserbound.GeyserboundPistonEventPacket; import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.physics.Direction; import org.geysermc.geyser.network.GameProtocol; @@ -64,7 +71,7 @@ public final class GeyserboundPacketHandlerImpl extends AbstractGeyserboundPacke @Setter private CompletableFuture pendingBatchLookup = null; @Setter - private CompletableFuture pickBlockLookup = null; + private CompletableFuture pickBlockLookup = null; private final AtomicInteger nextTransactionId = new AtomicInteger(1); @@ -140,7 +147,7 @@ public final class GeyserboundPacketHandlerImpl extends AbstractGeyserboundPacke @Override public void handlePickBlock(GeyserboundPickBlockPacket packet) { if (this.pickBlockLookup != null) { - this.pickBlockLookup.complete(packet.getTag()); + //this.pickBlockLookup.complete(packet.getTag()); // TODO 1.20.5 } } diff --git a/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java b/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java index 44c3b94b3..9a9eac2df 100644 --- a/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java +++ b/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java @@ -26,8 +26,8 @@ package org.geysermc.geyser.level; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import it.unimi.dsi.fastutil.objects.Object2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -36,7 +36,11 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; -import org.geysermc.erosion.packet.backendbound.*; +import org.geysermc.erosion.packet.backendbound.BackendboundBatchBlockEntityPacket; +import org.geysermc.erosion.packet.backendbound.BackendboundBatchBlockRequestPacket; +import org.geysermc.erosion.packet.backendbound.BackendboundBlockEntityPacket; +import org.geysermc.erosion.packet.backendbound.BackendboundBlockRequestPacket; +import org.geysermc.erosion.packet.backendbound.BackendboundPickBlockPacket; import org.geysermc.erosion.util.BlockPositionIterator; import org.geysermc.erosion.util.LecternUtils; import org.geysermc.geyser.session.GeyserSession; @@ -174,12 +178,12 @@ public class GeyserWorldManager extends WorldManager { @NonNull @Override - public CompletableFuture<@Nullable CompoundTag> getPickItemNbt(GeyserSession session, int x, int y, int z, boolean addNbtData) { + public CompletableFuture<@Nullable DataComponents> getPickItemComponents(GeyserSession session, int x, int y, int z, boolean addNbtData) { var erosionHandler = session.getErosionHandler().getAsActive(); if (erosionHandler == null) { - return super.getPickItemNbt(session, x, y, z, addNbtData); + return super.getPickItemComponents(session, x, y, z, addNbtData); } - CompletableFuture future = new CompletableFuture<>(); + CompletableFuture future = new CompletableFuture<>(); erosionHandler.setPickBlockLookup(future); erosionHandler.sendPacket(new BackendboundPickBlockPacket(Vector3i.from(x, y, z))); return future; diff --git a/core/src/main/java/org/geysermc/geyser/level/WorldManager.java b/core/src/main/java/org/geysermc/geyser/level/WorldManager.java index be7e2c139..aa0b43b80 100644 --- a/core/src/main/java/org/geysermc/geyser/level/WorldManager.java +++ b/core/src/main/java/org/geysermc/geyser/level/WorldManager.java @@ -26,9 +26,9 @@ package org.geysermc.geyser.level; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; +import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo; import com.github.steveice10.mc.protocol.data.game.setting.Difficulty; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3i; @@ -220,7 +220,7 @@ public abstract class WorldManager { * @return expected NBT for this item. */ @NonNull - public CompletableFuture<@Nullable CompoundTag> getPickItemNbt(GeyserSession session, int x, int y, int z, boolean addNbtData) { + public CompletableFuture<@Nullable DataComponents> getPickItemComponents(GeyserSession session, int x, int y, int z, boolean addExtraData) { return CompletableFuture.completedFuture(null); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java index 3781ef3c0..f4116ec0c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java @@ -26,9 +26,6 @@ package org.geysermc.geyser.translator.protocol.bedrock; import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.packet.BlockPickRequestPacket; import org.geysermc.geyser.entity.EntityDefinitions; @@ -68,33 +65,23 @@ public class BedrockBlockPickRequestTranslator extends PacketTranslator session.ensureInEventLoop(() -> { - if (tag == null) { + boolean addExtraData = packet.isAddUserData() && blockMapping.isBlockEntity(); // Holding down CTRL + if (BlockStateValues.getBannerColor(blockToPick) != -1 || addExtraData) { //TODO + session.getGeyser().getWorldManager().getPickItemComponents(session, vector.getX(), vector.getY(), vector.getZ(), addExtraData) + .whenComplete((components, ex) -> session.ensureInEventLoop(() -> { + if (components == null) { pickItem(session, blockMapping); return; } - if (addNbtData) { - ListTag lore = new ListTag("Lore"); - lore.add(new StringTag("", "\"(+NBT)\"")); - CompoundTag display = tag.get("display"); - if (display == null) { - display = new CompoundTag("display"); - tag.put(display); - } - display.put(lore); - } // I don't really like this... I'd rather get an ID from the block mapping I think ItemMapping mapping = session.getItemMappings().getMapping(blockMapping.getPickItem()); - ItemStack itemStack = new ItemStack(mapping.getJavaItem().javaId(), 1, tag); + ItemStack itemStack = new ItemStack(mapping.getJavaItem().javaId(), 1, components); InventoryUtils.findOrCreateItem(session, itemStack); })); return; - }*/ + } pickItem(session, blockMapping); } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b7e692ab7..f2e068c22 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "4ee05b62" # Revert from jitpack after release +mcprotocollib = "7026b600" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From b81408820b7308c6fa8a6bb218ff3627d4f70b93 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 23 Apr 2024 12:33:06 -0400 Subject: [PATCH 093/272] Refactor TagCache to be extensible Previously, for any new tag, we would have to add a field, add the line to load it, add the line to clear it, and make a method for that tag. Now, you just add an enum. --- .../entity/type/living/DolphinEntity.java | 5 +- .../type/living/animal/AxolotlEntity.java | 3 +- .../entity/type/living/animal/BeeEntity.java | 3 +- .../entity/type/living/animal/FoxEntity.java | 3 +- .../type/living/animal/MooshroomEntity.java | 4 +- .../type/living/animal/SnifferEntity.java | 3 +- .../type/living/monster/CreeperEntity.java | 5 +- .../type/living/monster/PiglinEntity.java | 3 +- .../geyser/session/cache/RegistryCache.java | 3 +- .../geyser/session/cache/TagCache.java | 188 +++++------------- .../geyser/session/cache/tags/BlockTag.java | 48 +++++ .../geyser/session/cache/tags/ItemTag.java | 47 +++++ .../translator/level/BiomeTranslator.java | 4 - .../org/geysermc/geyser/util/BlockUtils.java | 19 +- 14 files changed, 177 insertions(+), 161 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/session/cache/tags/BlockTag.java create mode 100644 core/src/main/java/org/geysermc/geyser/session/cache/tags/ItemTag.java diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/DolphinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/DolphinEntity.java index f0348bcaf..a43bb666f 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/DolphinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/DolphinEntity.java @@ -31,6 +31,7 @@ import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; @@ -49,7 +50,7 @@ public class DolphinEntity extends WaterEntity { @NonNull @Override protected InteractiveTag testMobInteraction(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) { - if (!itemInHand.isEmpty() && session.getTagCache().isFish(itemInHand)) { + if (!itemInHand.isEmpty() && session.getTagCache().is(ItemTag.FISHES, itemInHand)) { return InteractiveTag.FEED; } return super.testMobInteraction(hand, itemInHand); @@ -58,7 +59,7 @@ public class DolphinEntity extends WaterEntity { @NonNull @Override protected InteractionResult mobInteract(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) { - if (!itemInHand.isEmpty() && session.getTagCache().isFish(itemInHand)) { + if (!itemInHand.isEmpty() && session.getTagCache().is(ItemTag.FISHES, itemInHand)) { // Feed return InteractionResult.SUCCESS; } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java index 97753f63f..c4f95e546 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java @@ -36,6 +36,7 @@ import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.EntityUtils; import org.geysermc.geyser.util.InteractionResult; @@ -61,7 +62,7 @@ public class AxolotlEntity extends AnimalEntity { @Override public boolean canEat(Item item) { - return session.getTagCache().isAxolotlFood(item); + return session.getTagCache().is(ItemTag.AXOLOTL_FOOD, item); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java index e05b44cf0..7f1a88d7b 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java @@ -35,6 +35,7 @@ import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import java.util.UUID; @@ -67,6 +68,6 @@ public class BeeEntity extends AnimalEntity { @Override public boolean canEat(Item item) { - return session.getTagCache().isFlower(item); + return session.getTagCache().is(ItemTag.FLOWERS, item); } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FoxEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FoxEntity.java index 98c73cbce..200505f14 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FoxEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FoxEntity.java @@ -33,6 +33,7 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import java.util.UUID; @@ -56,6 +57,6 @@ public class FoxEntity extends AnimalEntity { @Override public boolean canEat(Item item) { - return session.getTagCache().isFoxFood(item); + return session.getTagCache().is(ItemTag.FOX_FOOD, item); } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/MooshroomEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/MooshroomEntity.java index 1c347bf31..8673eb18e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/MooshroomEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/MooshroomEntity.java @@ -33,8 +33,8 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.FlowerItem; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; @@ -77,7 +77,7 @@ public class MooshroomEntity extends AnimalEntity { } else if (!isBaby && isAlive() && itemInHand.asItem() == Items.SHEARS) { // Shear items return InteractionResult.SUCCESS; - } else if (isBrown && session.getTagCache().isSmallFlower(itemInHand) && itemInHand.asItem() instanceof FlowerItem) { + } else if (isBrown && session.getTagCache().is(ItemTag.SMALL_FLOWERS, itemInHand)) { // ? return InteractionResult.SUCCESS; } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SnifferEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SnifferEntity.java index a97756e39..0e6fffbc0 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SnifferEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SnifferEntity.java @@ -39,6 +39,7 @@ import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.type.Tickable; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import java.util.UUID; @@ -72,7 +73,7 @@ public class SnifferEntity extends AnimalEntity implements Tickable { @Override public boolean canEat(Item item) { - return session.getTagCache().isSnifferFood(item); + return session.getTagCache().is(ItemTag.SNIFFER_FOOD, item); } public void setSnifferState(ObjectEntityMetadata entityMetadata) { diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/CreeperEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/CreeperEntity.java index 33ea4e544..f134c31b3 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/CreeperEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/CreeperEntity.java @@ -35,6 +35,7 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; @@ -65,7 +66,7 @@ public class CreeperEntity extends MonsterEntity { @NonNull @Override protected InteractiveTag testMobInteraction(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) { - if (session.getTagCache().isCreeperIgniter(itemInHand.asItem())) { + if (session.getTagCache().is(ItemTag.CREEPER_IGNITERS, itemInHand)) { return InteractiveTag.IGNITE_CREEPER; } else { return super.testMobInteraction(hand, itemInHand); @@ -75,7 +76,7 @@ public class CreeperEntity extends MonsterEntity { @NonNull @Override protected InteractionResult mobInteract(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) { - if (session.getTagCache().isCreeperIgniter(itemInHand.asItem())) { + if (session.getTagCache().is(ItemTag.CREEPER_IGNITERS, itemInHand)) { // Ignite creeper - as of 1.19.3 session.playSoundEvent(SoundEvent.IGNITE, position); return InteractionResult.SUCCESS; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java index 450c546ec..696982a33 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java @@ -35,6 +35,7 @@ import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; @@ -65,7 +66,7 @@ public class PiglinEntity extends BasePiglinEntity { @Override public void updateOffHand(GeyserSession session) { // Check if the Piglin is holding Gold and set the ADMIRING flag accordingly so its pose updates - setFlag(EntityFlag.ADMIRING, session.getTagCache().shouldPiglinAdmire(session.getItemMappings().getMapping(this.offHand).getJavaItem())); + setFlag(EntityFlag.ADMIRING, session.getTagCache().is(ItemTag.PIGLIN_LOVED, session.getItemMappings().getMapping(this.offHand).getJavaItem())); super.updateBedrockMetadata(); super.updateOffHand(session); diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java index d5293c5c3..d6d5ae292 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java @@ -57,7 +57,7 @@ import java.util.function.ToIntFunction; * Stores any information sent via Java registries. May not contain all data in a given registry - we'll strip what's * unneeded. * - * Crafted as of 1.20.5 for easy "add new registry" in the future. + * Crafted as of 1.20.5 for easy "add new registry" functionality in the future. */ @Accessors(fluent = true) @Getter @@ -118,6 +118,7 @@ public final class RegistryCache { REGISTRIES.put("minecraft:" + registry, (registryCache, entries) -> { Int2ObjectMap localCache = localCacheFunction.apply(registryCache); // Clear each local cache every time a new registry entry is given to us + // (e.g. proxy server switches) localCache.clear(); for (int i = 0; i < entries.size(); i++) { RegistryEntry entry = entries.get(i); diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java index 57000bf8b..b2f43f180 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java @@ -27,64 +27,45 @@ package org.geysermc.geyser.session.cache; import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundUpdateTagsPacket; import it.unimi.dsi.fastutil.ints.IntList; -import it.unimi.dsi.fastutil.ints.IntLists; -import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.registry.type.BlockMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.BlockTag; +import org.geysermc.geyser.session.cache.tags.ItemTag; import javax.annotation.ParametersAreNonnullByDefault; +import java.util.EnumMap; +import java.util.HashMap; import java.util.Map; /** * Manages information sent from the {@link ClientboundUpdateTagsPacket}. If that packet is not sent, all lists here * will remain empty, matching Java Edition behavior. + * + * This system is designed for easy extensibility - just add an enum to {@link BlockTag} or {@link ItemTag}. */ @ParametersAreNonnullByDefault -public class TagCache { - /* Blocks */ - private IntList leaves; - private IntList wool; +public final class TagCache { + // Put these here so the enums can load without a static map + public static final Map ALL_BLOCK_TAGS = new HashMap<>(); + public static final Map ALL_ITEM_TAGS = new HashMap<>(); - private IntList axeEffective; - private IntList hoeEffective; - private IntList pickaxeEffective; - private IntList shovelEffective; - - private IntList requiresStoneTool; - private IntList requiresIronTool; - private IntList requiresDiamondTool; - - /* Items */ - private IntList axolotlFood; - private IntList creeperIgniters; - private IntList fishes; - private IntList flowers; - private IntList foxFood; - private IntList piglinLoved; - private IntList smallFlowers; - private IntList snifferFood; - - public TagCache() { - // Ensure all lists are non-null - clear(); - } + private final Map blocks = new EnumMap<>(BlockTag.class); + private final Map items = new EnumMap<>(ItemTag.class); public void loadPacket(GeyserSession session, ClientboundUpdateTagsPacket packet) { Map blockTags = packet.getTags().get("minecraft:block"); - this.leaves = IntList.of(blockTags.get("minecraft:leaves")); - this.wool = IntList.of(blockTags.get("minecraft:wool")); - - this.axeEffective = IntList.of(blockTags.get("minecraft:mineable/axe")); - this.hoeEffective = IntList.of(blockTags.get("minecraft:mineable/hoe")); - this.pickaxeEffective = IntList.of(blockTags.get("minecraft:mineable/pickaxe")); - this.shovelEffective = IntList.of(blockTags.get("minecraft:mineable/shovel")); - - this.requiresStoneTool = IntList.of(blockTags.get("minecraft:needs_stone_tool")); - this.requiresIronTool = IntList.of(blockTags.get("minecraft:needs_iron_tool")); - this.requiresDiamondTool = IntList.of(blockTags.get("minecraft:needs_diamond_tool")); + this.blocks.clear(); + ALL_BLOCK_TAGS.forEach((location, tag) -> { + int[] values = blockTags.get(location); + if (values != null) { + this.blocks.put(tag, IntList.of(values)); + } else { + session.getGeyser().getLogger().debug("Block tag not found from server: " + location); + } + }); // Hack btw GeyserLogger logger = session.getGeyser().getLogger(); @@ -96,14 +77,15 @@ public class TagCache { } Map itemTags = packet.getTags().get("minecraft:item"); - this.axolotlFood = IntList.of(itemTags.get("minecraft:axolotl_food")); - this.creeperIgniters = load(itemTags.get("minecraft:creeper_igniters")); - this.fishes = IntList.of(itemTags.get("minecraft:fishes")); - this.flowers = IntList.of(itemTags.get("minecraft:flowers")); - this.foxFood = IntList.of(itemTags.get("minecraft:fox_food")); - this.piglinLoved = IntList.of(itemTags.get("minecraft:piglin_loved")); - this.smallFlowers = IntList.of(itemTags.get("minecraft:small_flowers")); - this.snifferFood = load(itemTags.get("minecraft:sniffer_food")); + this.items.clear(); + ALL_ITEM_TAGS.forEach((location, tag) -> { + int[] values = itemTags.get(location); + if (values != null) { + this.items.put(tag, IntList.of(values)); + } else { + session.getGeyser().getLogger().debug("Item tag not found from server: " + location); + } + }); // Hack btw boolean emulatePost1_13Logic = itemTags.get("minecraft:signs").length > 1; @@ -113,98 +95,32 @@ public class TagCache { } } - private IntList load(int @Nullable[] tags) { - if (tags == null) { - return IntLists.EMPTY_LIST; + /** + * @return true if the block tag is present and contains this block mapping's Java ID. + */ + public boolean is(BlockTag tag, BlockMapping mapping) { + IntList values = this.blocks.get(tag); + if (values != null) { + return values.contains(mapping.getJavaBlockId()); } - return IntList.of(tags); + return false; } - public void clear() { - this.leaves = IntLists.emptyList(); - this.wool = IntLists.emptyList(); - - this.axeEffective = IntLists.emptyList(); - this.hoeEffective = IntLists.emptyList(); - this.pickaxeEffective = IntLists.emptyList(); - this.shovelEffective = IntLists.emptyList(); - - this.requiresStoneTool = IntLists.emptyList(); - this.requiresIronTool = IntLists.emptyList(); - this.requiresDiamondTool = IntLists.emptyList(); - - this.axolotlFood = IntLists.emptyList(); - this.creeperIgniters = IntLists.emptyList(); - this.fishes = IntLists.emptyList(); - this.flowers = IntLists.emptyList(); - this.foxFood = IntLists.emptyList(); - this.piglinLoved = IntLists.emptyList(); - this.smallFlowers = IntLists.emptyList(); - this.snifferFood = IntLists.emptyList(); + /** + * @return true if the item tag is present and contains this item stack's Java ID. + */ + public boolean is(ItemTag tag, GeyserItemStack itemStack) { + return is(tag, itemStack.asItem()); } - public boolean isAxolotlFood(Item item) { - return axolotlFood.contains(item.javaId()); - } - - public boolean isCreeperIgniter(Item item) { - return creeperIgniters.contains(item.javaId()); - } - - public boolean isFish(GeyserItemStack itemStack) { - return fishes.contains(itemStack.getJavaId()); - } - - public boolean isFlower(Item item) { - return flowers.contains(item.javaId()); - } - - public boolean isFoxFood(Item item) { - return foxFood.contains(item.javaId()); - } - - public boolean shouldPiglinAdmire(Item item) { - return piglinLoved.contains(item.javaId()); - } - - public boolean isSmallFlower(GeyserItemStack itemStack) { - return smallFlowers.contains(itemStack.getJavaId()); - } - - public boolean isSnifferFood(Item item) { - return snifferFood.contains(item.javaId()); - } - - public boolean isAxeEffective(BlockMapping blockMapping) { - return axeEffective.contains(blockMapping.getJavaBlockId()); - } - - public boolean isHoeEffective(BlockMapping blockMapping) { - return hoeEffective.contains(blockMapping.getJavaBlockId()); - } - - public boolean isPickaxeEffective(BlockMapping blockMapping) { - return pickaxeEffective.contains(blockMapping.getJavaBlockId()); - } - - public boolean isShovelEffective(BlockMapping blockMapping) { - return shovelEffective.contains(blockMapping.getJavaBlockId()); - } - - public boolean isShearsEffective(BlockMapping blockMapping) { - int javaBlockId = blockMapping.getJavaBlockId(); - return leaves.contains(javaBlockId) || wool.contains(javaBlockId); - } - - public boolean requiresStoneTool(BlockMapping blockMapping) { - return requiresStoneTool.contains(blockMapping.getJavaBlockId()); - } - - public boolean requiresIronTool(BlockMapping blockMapping) { - return requiresIronTool.contains(blockMapping.getJavaBlockId()); - } - - public boolean requiresDiamondTool(BlockMapping blockMapping) { - return requiresDiamondTool.contains(blockMapping.getJavaBlockId()); + /** + * @return true if the item tag is present and contains this item's Java ID. + */ + public boolean is(ItemTag tag, Item item) { + IntList values = this.items.get(tag); + if (values != null) { + return values.contains(item.javaId()); + } + return false; } } diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/tags/BlockTag.java b/core/src/main/java/org/geysermc/geyser/session/cache/tags/BlockTag.java new file mode 100644 index 000000000..7017ad55c --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/session/cache/tags/BlockTag.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.session.cache.tags; + +import org.geysermc.geyser.session.cache.TagCache; + +public enum BlockTag { + LEAVES("leaves"), + WOOL("wool"), + AXE_EFFECTIVE("mineable/axe"), + HOE_EFFECTIVE("mineable/hoe"), + PICKAXE_EFFECTIVE("mineable/pickaxe"), + SHOVEL_EFFECTIVE("mineable/shovel"), + NEEDS_STONE_TOOL("needs_stone_tool"), + NEEDS_IRON_TOOL("needs_iron_tool"), + NEEDS_DIAMOND_TOOL("needs_diamond_tool"); + + BlockTag(String identifier) { + register(identifier, this); + } + + private static void register(String name, BlockTag tag) { + TagCache.ALL_BLOCK_TAGS.put("minecraft:" + name, tag); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/tags/ItemTag.java b/core/src/main/java/org/geysermc/geyser/session/cache/tags/ItemTag.java new file mode 100644 index 000000000..df9a423ed --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/session/cache/tags/ItemTag.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.session.cache.tags; + +import org.geysermc.geyser.session.cache.TagCache; + +public enum ItemTag { + AXOLOTL_FOOD("axolotl_food"), + CREEPER_IGNITERS("creeper_igniters"), + FISHES("fishes"), + FLOWERS("flowers"), + FOX_FOOD("fox_food"), + PIGLIN_LOVED("piglin_loved"), + SMALL_FLOWERS("small_flowers"), + SNIFFER_FOOD("sniffer_food"); + + ItemTag(String identifier) { + register(identifier, this); + } + + private static void register(String name, ItemTag tag) { + TagCache.ALL_ITEM_TAGS.put("minecraft:" + name, tag); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java index fce928bdb..450c786f2 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java @@ -47,10 +47,6 @@ public class BiomeTranslator { public static int loadServerBiome(RegistryEntry entry) { String javaIdentifier = entry.getId(); return Registries.BIOME_IDENTIFIERS.get().getOrDefault(javaIdentifier, 0); -// if (javaId == 0) { -// // Matches Java behavior when it sees an invalid biome - it just replaces it with ID 0 -// biomeTranslations.defaultReturnValue(bedrockId); -// } } public static BlockStorage toNewBedrockBiome(GeyserSession session, DataPalette biomeData) { diff --git a/core/src/main/java/org/geysermc/geyser/util/BlockUtils.java b/core/src/main/java/org/geysermc/geyser/util/BlockUtils.java index da98f45c7..8392f9fcd 100644 --- a/core/src/main/java/org/geysermc/geyser/util/BlockUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/BlockUtils.java @@ -36,17 +36,18 @@ import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.type.BlockMapping; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.BlockTag; import org.geysermc.geyser.translator.collision.BlockCollision; public final class BlockUtils { private static boolean correctTool(GeyserSession session, BlockMapping blockMapping, String itemToolType) { return switch (itemToolType) { - case "axe" -> session.getTagCache().isAxeEffective(blockMapping); - case "hoe" -> session.getTagCache().isHoeEffective(blockMapping); - case "pickaxe" -> session.getTagCache().isPickaxeEffective(blockMapping); - case "shears" -> session.getTagCache().isShearsEffective(blockMapping); - case "shovel" -> session.getTagCache().isShovelEffective(blockMapping); + case "axe" -> session.getTagCache().is(BlockTag.AXE_EFFECTIVE, blockMapping); + case "hoe" -> session.getTagCache().is(BlockTag.HOE_EFFECTIVE, blockMapping); + case "pickaxe" -> session.getTagCache().is(BlockTag.PICKAXE_EFFECTIVE, blockMapping); + case "shears" -> session.getTagCache().is(BlockTag.LEAVES, blockMapping) || session.getTagCache().is(BlockTag.WOOL, blockMapping); + case "shovel" -> session.getTagCache().is(BlockTag.SHOVEL_EFFECTIVE, blockMapping); case "sword" -> blockMapping.getJavaBlockId() == BlockStateValues.JAVA_COBWEB_ID; default -> { session.getGeyser().getLogger().warning("Unknown tool type: " + itemToolType); @@ -79,15 +80,15 @@ public final class BlockUtils { switch (toolTier) { // Use intentional fall-throughs to check each tier with this block default: - if (session.getTagCache().requiresStoneTool(blockMapping)) { + if (session.getTagCache().is(BlockTag.NEEDS_STONE_TOOL, blockMapping)) { return false; } case "stone": - if (session.getTagCache().requiresIronTool(blockMapping)) { + if (session.getTagCache().is(BlockTag.NEEDS_IRON_TOOL, blockMapping)) { return false; } case "iron": - if (session.getTagCache().requiresDiamondTool(blockMapping)) { + if (session.getTagCache().is(BlockTag.NEEDS_DIAMOND_TOOL, blockMapping)) { return false; } } @@ -131,7 +132,7 @@ public final class BlockUtils { } public static double getBreakTime(GeyserSession session, BlockMapping blockMapping, ItemMapping item, @Nullable DataComponents components, boolean isSessionPlayer) { - boolean isShearsEffective = session.getTagCache().isShearsEffective(blockMapping); //TODO called twice + boolean isShearsEffective = session.getTagCache().is(BlockTag.LEAVES, blockMapping) || session.getTagCache().is(BlockTag.WOOL, blockMapping); //TODO called twice boolean canHarvestWithHand = blockMapping.isCanBreakWithHand(); String toolType = ""; String toolTier = ""; From d105dadf62a79d6f81e6829f1919545dce745c4a Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 23 Apr 2024 12:36:39 -0400 Subject: [PATCH 094/272] Update for release. STILL NOT READY YET THOUGH --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f2e068c22..bbb6045f5 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "7026b600" # Revert from jitpack after release +mcprotocollib = "3c81cc80" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From abea0131e41e62fe76f750f8e7a1e08a73b32eb2 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 23 Apr 2024 16:08:26 -0400 Subject: [PATCH 095/272] Fix llama carpets --- .../geyser/entity/EntityDefinitions.java | 1 - .../type/living/animal/horse/LlamaEntity.java | 27 ------------------- .../populator/ItemRegistryPopulator.java | 10 ------- .../geyser/registry/type/ItemMappings.java | 1 - .../entity/JavaSetEquipmentTranslator.java | 3 ++- 5 files changed, 2 insertions(+), 40 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index 6b243212d..d825daa8a 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -938,7 +938,6 @@ public final class EntityDefinitions { .type(EntityType.LLAMA) .height(1.87f).width(0.9f) .addTranslator(MetadataType.INT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityDataTypes.STRENGTH, entityMetadata.getValue())) - .addTranslator(MetadataType.INT, LlamaEntity::setCarpetedColor) .addTranslator(MetadataType.INT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityDataTypes.VARIANT, entityMetadata.getValue())) .build(); TRADER_LLAMA = EntityDefinition.inherited(TraderLlamaEntity::new, LLAMA) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java index a32d7b1b5..7fcada504 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java @@ -25,11 +25,8 @@ package org.geysermc.geyser.entity.type.living.animal.horse; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; -import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; -import org.cloudburstmc.protocol.bedrock.packet.MobArmorEquipmentPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; @@ -45,30 +42,6 @@ public class LlamaEntity extends ChestedHorseEntity { dirtyMetadata.put(EntityDataTypes.CONTAINER_STRENGTH_MODIFIER, 3); // Presumably 3 slots for every 1 strength } - /** - * Color equipped on the llama - */ - public void setCarpetedColor(IntEntityMetadata entityMetadata) { - // Bedrock treats llama decoration as armor - MobArmorEquipmentPacket equipmentPacket = new MobArmorEquipmentPacket(); - equipmentPacket.setRuntimeEntityId(geyserId); - // -1 means no armor - int carpetIndex = entityMetadata.getPrimitiveValue(); - if (carpetIndex > -1 && carpetIndex <= 15) { - // The damage value is the dye color that Java sends us, for pre-1.16.220 - // The item is always going to be a carpet - equipmentPacket.setChestplate(session.getItemMappings().getCarpets().get(carpetIndex)); - } else { - equipmentPacket.setChestplate(ItemData.AIR); - } - // Required to fill out the rest of the equipment or Bedrock ignores it, including above else statement if removing armor - equipmentPacket.setBoots(ItemData.AIR); - equipmentPacket.setHelmet(ItemData.AIR); - equipmentPacket.setLeggings(ItemData.AIR); - - session.sendUpstreamPacket(equipmentPacket); - } - @Override public boolean canEat(Item item) { return item == Items.WHEAT || item == Items.HAY_BLOCK; diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java index 5b64da7a1..d3a4bed84 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java @@ -159,7 +159,6 @@ public class ItemRegistryPopulator { Object2ObjectMap customBlockItemDefinitions = new Object2ObjectOpenHashMap<>(); List buckets = new ObjectArrayList<>(); - List carpets = new ObjectArrayList<>(); List mappings = new ObjectArrayList<>(); // Temporary mapping to create stored items @@ -458,14 +457,6 @@ public class ItemRegistryPopulator { if (javaItem.javaIdentifier().contains("bucket") && !javaItem.javaIdentifier().contains("milk")) { buckets.add(definition); - } else if (javaItem.javaIdentifier().contains("_carpet") && !javaItem.javaIdentifier().contains("moss")) { - // This should be the numerical order Java sends as an integer value for llamas - carpets.add(ItemData.builder() - .definition(definition) - .damage(mapping.getBedrockData()) - .count(1) - .blockDefinition(mapping.getBedrockBlockDefinition()) - .build()); } else if (javaItem.javaIdentifier().startsWith("minecraft:music_disc_")) { // The Java record level event uses the item ID as the "key" to play the record Registries.RECORDS.register(javaItem.javaId(), SoundEvent.valueOf("RECORD_" + @@ -589,7 +580,6 @@ public class ItemRegistryPopulator { .storedItems(new StoredItemMappings(javaItemToMapping)) .javaOnlyItems(javaOnlyItems) .buckets(buckets) - .carpets(carpets) .componentItemData(componentItemData) .lodestoneCompass(lodestoneEntry) .customIdMappings(customIdMappings) diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java b/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java index 33908a7e7..5df969111 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java +++ b/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java @@ -69,7 +69,6 @@ public class ItemMappings implements DefinitionRegistry { List buckets; List boats; - List carpets; List componentItemData; Int2ObjectMap customIdMappings; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java index b0168a4ce..7c93725e0 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java @@ -74,7 +74,8 @@ public class JavaSetEquipmentTranslator extends PacketTranslator { + case CHESTPLATE, BODY -> { + // BODY is sent for llamas with a carpet equipped, as of 1.20.5 livingEntity.setChestplate(item); armorUpdated = true; } From c54624fb2632dd5dc60626eb55ea830b3818836c Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 23 Apr 2024 16:14:18 -0400 Subject: [PATCH 096/272] Fix some cases of empty tags being needed --- .../level/block/entity/BlockEntityTranslator.java | 8 ++++++-- .../level/JavaLevelChunkWithLightTranslator.java | 12 ++++++++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java index 7566e0d90..053e2c8f3 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java @@ -43,12 +43,16 @@ public abstract class BlockEntityTranslator { public abstract void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState); public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, CompoundTag tag, int blockState) { - NbtMapBuilder tagBuilder = getConstantBedrockTag(BlockEntityUtils.getBedrockBlockEntityId(type), x, y, z); + NbtMapBuilder tagBuilder = getConstantBedrockTag(type, x, y, z); translateTag(tagBuilder, tag, blockState); return tagBuilder.build(); } - protected NbtMapBuilder getConstantBedrockTag(String bedrockId, int x, int y, int z) { + public static NbtMapBuilder getConstantBedrockTag(BlockEntityType type, int x, int y, int z) { + return getConstantBedrockTag(BlockEntityUtils.getBedrockBlockEntityId(type), x, y, z); + } + + public static NbtMapBuilder getConstantBedrockTag(String bedrockId, int x, int y, int z) { return NbtMap.builder() .putInt("x", x) .putInt("y", y) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java index fc1d0316c..1e6534130 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java @@ -393,10 +393,9 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator Date: Tue, 23 Apr 2024 23:04:38 +0200 Subject: [PATCH 097/272] target 1.20.5 release, build neoforge again --- .github/workflows/build-remote.yml | 2 +- .github/workflows/build.yml | 2 +- .github/workflows/preview.yml | 2 +- README.md | 2 +- bootstrap/mod/build.gradle.kts | 3 +-- bootstrap/mod/fabric/src/main/resources/fabric.mod.json | 2 +- .../mod/neoforge/src/main/resources/META-INF/mods.toml | 4 ++-- .../src/main/kotlin/geyser.modded-conventions.gradle.kts | 4 ++-- build.gradle.kts | 2 +- gradle/libs.versions.toml | 8 ++++---- settings.gradle.kts | 4 ++-- 11 files changed, 17 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build-remote.yml b/.github/workflows/build-remote.yml index 09326d429..d49920785 100644 --- a/.github/workflows/build-remote.yml +++ b/.github/workflows/build-remote.yml @@ -64,7 +64,7 @@ jobs: with: name: Geyser NeoForge path: geyser/bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar - #if-no-files-found: error // TODO 1.20.5 until neoforge updates + if-no-files-found: error - name: Archive artifacts (Geyser Standalone) uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 if: success() diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cfb509f30..284fa265a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -68,7 +68,7 @@ jobs: with: name: Geyser NeoForge path: bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar - #if-no-files-found: error // TODO 1.20.5 - currently no neoforge artifacts + if-no-files-found: error - name: Archive artifacts (Geyser Standalone) uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 if: success() diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index a33c71a79..13712d5ef 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -53,10 +53,10 @@ jobs: with: appID: ${{ secrets.RELEASE_APP_ID }} appPrivateKey: ${{ secrets.RELEASE_APP_PK }} - # neoforge:Geyser-NeoForge.jar // TODO 1.20.5 files: | bungeecord:Geyser-BungeeCord.jar fabric:Geyser-Fabric.jar + neoforge:Geyser-NeoForge.jar spigot:Geyser-Spigot.jar standalone:Geyser-Standalone.jar velocity:Geyser-Velocity.jar diff --git a/README.md b/README.md index e17c9d2bb..314876d60 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here! -### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.80 and Minecraft Java 1.20.4 +### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.80 and Minecraft Java 1.20.5 ## Setting Up Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser. diff --git a/bootstrap/mod/build.gradle.kts b/bootstrap/mod/build.gradle.kts index 281fd45e7..7651a2df2 100644 --- a/bootstrap/mod/build.gradle.kts +++ b/bootstrap/mod/build.gradle.kts @@ -1,6 +1,5 @@ architectury { - common("fabric") - //common("neoforge", "fabric") // todo 1.20.5 + common("neoforge", "fabric") } loom { diff --git a/bootstrap/mod/fabric/src/main/resources/fabric.mod.json b/bootstrap/mod/fabric/src/main/resources/fabric.mod.json index 7fb6b302c..93f48b73c 100644 --- a/bootstrap/mod/fabric/src/main/resources/fabric.mod.json +++ b/bootstrap/mod/fabric/src/main/resources/fabric.mod.json @@ -25,6 +25,6 @@ "depends": { "fabricloader": ">=0.15.10", "fabric": "*", - "minecraft": ">=1.20.4" + "minecraft": ">=1.20.5" } } diff --git a/bootstrap/mod/neoforge/src/main/resources/META-INF/mods.toml b/bootstrap/mod/neoforge/src/main/resources/META-INF/mods.toml index 2f9e9b12e..1110568e8 100644 --- a/bootstrap/mod/neoforge/src/main/resources/META-INF/mods.toml +++ b/bootstrap/mod/neoforge/src/main/resources/META-INF/mods.toml @@ -14,12 +14,12 @@ config = "geyser.mixins.json" [[dependencies.geyser_neoforge]] modId="neoforge" type="required" - versionRange="[20.4.48-beta,)" + versionRange="[20.5.0-beta,)" ordering="NONE" side="BOTH" [[dependencies.geyser_neoforge]] modId="minecraft" type="required" - versionRange="[1.20,1.21)" + versionRange="[1.20.4,1.21)" ordering="NONE" side="BOTH" \ No newline at end of file diff --git a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts index c83ea2911..afea247a7 100644 --- a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts @@ -39,7 +39,7 @@ provided("io.netty", "netty-resolver-dns-native-macos") provided("org.ow2.asm", "asm") architectury { - minecraft = "1.20.4" + minecraft = "1.20.5" } loom { @@ -110,7 +110,7 @@ afterEvaluate { } dependencies { - minecraft("com.mojang:minecraft:1.20.5-rc3") + minecraft("com.mojang:minecraft:1.20.5") mappings(loom.officialMojangMappings()) } diff --git a/build.gradle.kts b/build.gradle.kts index fdacd5538..dfdff2187 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -22,7 +22,7 @@ val basePlatforms = setOf( val moddedPlatforms = setOf( projects.fabric, - //projects.neoforge, // todo 1.20.5 + projects.neoforge, projects.mod ).map { it.dependencyProject } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index bbb6045f5..2b6df11a6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -30,11 +30,11 @@ commodore = "2.2" bungeecord = "a7c6ede" velocity = "3.1.1" viaproxy = "3.2.0-SNAPSHOT" -fabric-minecraft = "1.20.4" -fabric-loader = "0.15.2" -fabric-api = "0.91.2+1.20.4" +fabric-minecraft = "1.20.5" +fabric-loader = "0.15.10" +fabric-api = "0.97.6+1.20.5" fabric-permissions = "0.2-SNAPSHOT" -neoforge-minecraft = "20.4.48-beta" +neoforge-minecraft = "20.5.0-beta" mixin = "0.8.5" # plugin versions diff --git a/settings.gradle.kts b/settings.gradle.kts index 3867d7a84..a39bfa3d2 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -66,7 +66,7 @@ include(":ap") include(":api") include(":bungeecord") include(":fabric") -//include(":neoforge") // todo 1.20.5 +include(":neoforge") include(":mod") include(":spigot") include(":standalone") @@ -78,7 +78,7 @@ include(":core") // Specify project dirs project(":bungeecord").projectDir = file("bootstrap/bungeecord") project(":fabric").projectDir = file("bootstrap/mod/fabric") -//project(":neoforge").projectDir = file("bootstrap/mod/neoforge") // todo 1.20.5 +project(":neoforge").projectDir = file("bootstrap/mod/neoforge") project(":mod").projectDir = file("bootstrap/mod") project(":spigot").projectDir = file("bootstrap/spigot") project(":standalone").projectDir = file("bootstrap/standalone") From bbaffb2ab38a825c0ab4ec7a360bf0ac831fa773 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Tue, 23 Apr 2024 19:12:20 -0400 Subject: [PATCH 098/272] Wolf interactions --- .../living/animal/tameable/WolfEntity.java | 25 ++++++++++++++----- .../geysermc/geyser/util/InteractiveTag.java | 5 +++- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java index ee7281772..ff130aeff 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java @@ -133,16 +133,29 @@ public class WolfEntity extends TameableEntity { if (itemInHand.asItem() == Items.BONE && !getFlag(EntityFlag.TAMED)) { // Bone and untamed - can tame return InteractiveTag.TAME; - } else { - if (itemInHand.asItem() instanceof DyeItem item) { + } + if (getFlag(EntityFlag.TAMED) && ownerBedrockId == session.getPlayerEntity().getGeyserId()) { + if (itemInHand.asItem() instanceof DyeItem dyeItem) { // If this fails, as of Java Edition 1.18.1, you cannot toggle sit/stand - if (item.dyeColor() != this.collarColor) { + if (dyeItem.dyeColor() != this.collarColor) { return InteractiveTag.DYE; + } else { + return super.testMobInteraction(hand, itemInHand); } - } else if (getFlag(EntityFlag.TAMED) && ownerBedrockId == session.getPlayerEntity().getGeyserId()) { - // Tamed and owned by player - can sit/stand - return getFlag(EntityFlag.SITTING) ? InteractiveTag.STAND : InteractiveTag.SIT; } + if (itemInHand.asItem() == Items.WOLF_ARMOR && !this.chestplate.isValid() && !getFlag(EntityFlag.BABY)) { + return InteractiveTag.EQUIP_WOLF_ARMOR; + } + if (itemInHand.asItem() == Items.SHEARS && this.chestplate.isValid()) { // TODO: check curse of binding + return InteractiveTag.REMOVE_WOLF_ARMOR; + } + if (Items.WOLF_ARMOR.isValidRepairItem(itemInHand.asItem()) && getFlag(EntityFlag.SITTING) && + this.chestplate.isValid() && this.chestplate.getTag() != null && + this.chestplate.getTag().getInt("Damage") > 0) { + return InteractiveTag.REPAIR_WOLF_ARMOR; + } + // Tamed and owned by player - can sit/stand + return getFlag(EntityFlag.SITTING) ? InteractiveTag.STAND : InteractiveTag.SIT; } return super.testMobInteraction(hand, itemInHand); } diff --git a/core/src/main/java/org/geysermc/geyser/util/InteractiveTag.java b/core/src/main/java/org/geysermc/geyser/util/InteractiveTag.java index 9607ac61e..168c861f5 100644 --- a/core/src/main/java/org/geysermc/geyser/util/InteractiveTag.java +++ b/core/src/main/java/org/geysermc/geyser/util/InteractiveTag.java @@ -70,7 +70,10 @@ public enum InteractiveTag { READ, WAKE_VILLAGER("wakevillager"), BARTER, - GIVE_ITEM_TO_ALLAY("allay"); + GIVE_ITEM_TO_ALLAY("allay"), + EQUIP_WOLF_ARMOR("equipwolfarmor"), + REMOVE_WOLF_ARMOR("removewolfarmor"), + REPAIR_WOLF_ARMOR("repairwolfarmor"); /** * The full string that should be passed on to the client. From a1534e45350f8787f49c8d07aacdfa683b65dbb4 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 23 Apr 2024 20:11:32 -0400 Subject: [PATCH 099/272] Basic Armadillo structure --- .../geyser/entity/EntityDefinitions.java | 6 +++ .../type/living/animal/ArmadilloEntity.java | 38 +++++++++++++++++++ .../geyser/registry/type/ItemMappings.java | 4 +- 3 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index d825daa8a..9563e6d37 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -53,6 +53,7 @@ import org.geysermc.geyser.translator.text.MessageTranslator; public final class EntityDefinitions { public static final EntityDefinition ALLAY; public static final EntityDefinition AREA_EFFECT_CLOUD; + public static final EntityDefinition ARMADILLO; public static final EntityDefinition ARMOR_STAND; public static final EntityDefinition ARROW; public static final EntityDefinition AXOLOTL; @@ -770,6 +771,11 @@ public final class EntityDefinitions { // Extends ageable { + ARMADILLO = EntityDefinition.inherited(ArmadilloEntity::new, ageableEntityBase) + .type(EntityType.ARMADILLO) + .height(0.65f).width(0.7f) + .addTranslator(null) + .build(); AXOLOTL = EntityDefinition.inherited(AxolotlEntity::new, ageableEntityBase) .type(EntityType.AXOLOTL) .height(0.42f).width(0.7f) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java new file mode 100644 index 000000000..d89b4e3f7 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.entity.type.living.animal; + +import org.cloudburstmc.math.vector.Vector3f; +import org.geysermc.geyser.entity.EntityDefinition; +import org.geysermc.geyser.session.GeyserSession; + +import java.util.UUID; + +public class ArmadilloEntity extends AnimalEntity { + public ArmadilloEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { + super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java b/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java index 5df969111..199481cbc 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java +++ b/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java @@ -98,9 +98,9 @@ public class ItemMappings implements DefinitionRegistry { return javaId >= 0 && javaId < this.items.length ? this.items[javaId] : ItemMapping.AIR; } - @Nullable + @NonNull public ItemMapping getMapping(Item javaItem) { - return getMapping(javaItem.javaIdentifier()); + return getMapping(javaItem.javaId()); } /** From 9490a091b576155b8d60a9216a6d0192153143a3 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Tue, 23 Apr 2024 20:43:46 -0400 Subject: [PATCH 100/272] Calculate horse inventory size --- .../geysermc/geyser/entity/EntityDefinitions.java | 2 +- .../type/living/animal/horse/LlamaEntity.java | 13 +++++++++++++ .../inventory/JavaHorseScreenOpenTranslator.java | 14 ++++++++++++-- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index 9563e6d37..f454bef88 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -943,7 +943,7 @@ public final class EntityDefinitions { LLAMA = EntityDefinition.inherited(LlamaEntity::new, chestedHorseEntityBase) .type(EntityType.LLAMA) .height(1.87f).width(0.9f) - .addTranslator(MetadataType.INT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityDataTypes.STRENGTH, entityMetadata.getValue())) + .addTranslator(MetadataType.INT, LlamaEntity::setStrength) .addTranslator(MetadataType.INT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityDataTypes.VARIANT, entityMetadata.getValue())) .build(); TRADER_LLAMA = EntityDefinition.inherited(TraderLlamaEntity::new, LLAMA) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java index 7fcada504..29da2e0dc 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java @@ -25,16 +25,24 @@ package org.geysermc.geyser.entity.type.living.animal.horse; +import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import lombok.Getter; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.util.MathUtils; import java.util.UUID; public class LlamaEntity extends ChestedHorseEntity { + /** + * Used to calculate inventory size + */ + @Getter + private int strength = 1; public LlamaEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); @@ -42,6 +50,11 @@ public class LlamaEntity extends ChestedHorseEntity { dirtyMetadata.put(EntityDataTypes.CONTAINER_STRENGTH_MODIFIER, 3); // Presumably 3 slots for every 1 strength } + public void setStrength(IntEntityMetadata entityMetadata) { + strength = MathUtils.constrain(entityMetadata.getPrimitiveValue(), 1, 5); + this.dirtyMetadata.put(EntityDataTypes.STRENGTH, strength); + } + @Override public boolean canEat(Item item) { return item == Items.WHEAT || item == Items.HAY_BLOCK; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaHorseScreenOpenTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaHorseScreenOpenTranslator.java index 33cfeaf31..d2abcb5e3 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaHorseScreenOpenTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaHorseScreenOpenTranslator.java @@ -29,6 +29,7 @@ import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.Cli import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; +import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; import org.cloudburstmc.protocol.bedrock.packet.UpdateEquipPacket; import org.geysermc.geyser.entity.type.Entity; @@ -114,16 +115,25 @@ public class JavaHorseScreenOpenTranslator extends PacketTranslator Date: Wed, 24 Apr 2024 16:39:35 -0400 Subject: [PATCH 101/272] Move MCProtocolLib to dev - package ID change --- .../mod/world/GeyserModWorldManager.java | 18 +++--- .../platform/spigot/GeyserSpigotInjector.java | 2 +- .../platform/spigot/PaperAdventure.java | 2 +- .../spigot/world/GeyserPistonListener.java | 2 +- .../manager/GeyserSpigotWorldManager.java | 6 +- .../java/org/geysermc/geyser/GeyserImpl.java | 2 +- .../command/defaults/StatisticsCommand.java | 4 +- .../geyser/dump/BootstrapDumpInfo.java | 2 +- .../org/geysermc/geyser/dump/DumpInfo.java | 7 +-- .../geyser/entity/EntityDefinition.java | 6 +- .../geyser/entity/EntityDefinitions.java | 8 +-- .../entity/type/AbstractArrowEntity.java | 4 +- .../entity/type/AreaEffectCloudEntity.java | 6 +- .../geyser/entity/type/BoatEntity.java | 9 ++- .../geyser/entity/type/ChestBoatEntity.java | 2 +- .../type/CommandBlockMinecartEntity.java | 2 +- .../type/DefaultBlockMinecartEntity.java | 4 +- .../entity/type/EnderCrystalEntity.java | 2 +- .../geysermc/geyser/entity/type/Entity.java | 27 +++------ .../entity/type/FallingBlockEntity.java | 2 +- .../geyser/entity/type/FireworkEntity.java | 6 +- .../geyser/entity/type/FishingHookEntity.java | 4 +- .../entity/type/FurnaceMinecartEntity.java | 4 +- .../geyser/entity/type/InteractionEntity.java | 8 +-- .../geyser/entity/type/ItemEntity.java | 4 +- .../geyser/entity/type/ItemFrameEntity.java | 14 ++--- .../geyser/entity/type/LeashKnotEntity.java | 2 +- .../geyser/entity/type/LivingEntity.java | 16 ++--- .../geyser/entity/type/MinecartEntity.java | 6 +- .../geyser/entity/type/PaintingEntity.java | 6 +- .../geyser/entity/type/TNTEntity.java | 2 +- .../geyser/entity/type/TextDisplayEntity.java | 4 +- .../geyser/entity/type/ThrowableEntity.java | 2 +- .../entity/type/ThrowableItemEntity.java | 4 +- .../entity/type/ThrownPotionEntity.java | 10 ++-- .../geyser/entity/type/TippedArrowEntity.java | 2 +- .../geyser/entity/type/WitherSkullEntity.java | 2 +- .../type/living/AbstractFishEntity.java | 2 +- .../entity/type/living/AgeableEntity.java | 2 +- .../entity/type/living/AllayEntity.java | 4 +- .../entity/type/living/ArmorStandEntity.java | 8 +-- .../geyser/entity/type/living/BatEntity.java | 2 +- .../entity/type/living/DolphinEntity.java | 2 +- .../entity/type/living/IronGolemEntity.java | 2 +- .../geyser/entity/type/living/MobEntity.java | 4 +- .../entity/type/living/SlimeEntity.java | 2 +- .../entity/type/living/SnowGolemEntity.java | 4 +- .../entity/type/living/TadpoleEntity.java | 2 +- .../type/living/animal/AnimalEntity.java | 2 +- .../type/living/animal/AxolotlEntity.java | 6 +- .../entity/type/living/animal/BeeEntity.java | 4 +- .../entity/type/living/animal/CowEntity.java | 2 +- .../entity/type/living/animal/FoxEntity.java | 4 +- .../entity/type/living/animal/FrogEntity.java | 6 +- .../entity/type/living/animal/GoatEntity.java | 6 +- .../type/living/animal/HoglinEntity.java | 2 +- .../type/living/animal/MooshroomEntity.java | 4 +- .../type/living/animal/OcelotEntity.java | 2 +- .../type/living/animal/PandaEntity.java | 6 +- .../entity/type/living/animal/PigEntity.java | 2 +- .../type/living/animal/PufferFishEntity.java | 2 +- .../type/living/animal/RabbitEntity.java | 2 +- .../type/living/animal/SheepEntity.java | 4 +- .../type/living/animal/SnifferEntity.java | 6 +- .../type/living/animal/StriderEntity.java | 4 +- .../living/animal/TropicalFishEntity.java | 4 +- .../type/living/animal/TurtleEntity.java | 2 +- .../animal/horse/AbstractHorseEntity.java | 4 +- .../type/living/animal/horse/CamelEntity.java | 6 +- .../type/living/animal/horse/HorseEntity.java | 2 +- .../type/living/animal/horse/LlamaEntity.java | 2 +- .../animal/horse/SkeletonHorseEntity.java | 2 +- .../animal/horse/ZombieHorseEntity.java | 2 +- .../living/animal/tameable/CatEntity.java | 8 +-- .../living/animal/tameable/ParrotEntity.java | 2 +- .../animal/tameable/TameableEntity.java | 6 +- .../living/animal/tameable/WolfEntity.java | 6 +- .../merchant/AbstractMerchantEntity.java | 2 +- .../type/living/merchant/VillagerEntity.java | 4 +- .../monster/AbstractSkeletonEntity.java | 2 +- .../type/living/monster/BasePiglinEntity.java | 2 +- .../type/living/monster/BlazeEntity.java | 2 +- .../type/living/monster/CreeperEntity.java | 6 +- .../living/monster/EnderDragonEntity.java | 10 +--- .../type/living/monster/EndermanEntity.java | 4 +- .../type/living/monster/GhastEntity.java | 2 +- .../type/living/monster/GuardianEntity.java | 2 +- .../type/living/monster/PhantomEntity.java | 2 +- .../type/living/monster/PiglinEntity.java | 4 +- .../type/living/monster/ShulkerEntity.java | 6 +- .../type/living/monster/SkeletonEntity.java | 2 +- .../type/living/monster/SpiderEntity.java | 2 +- .../entity/type/living/monster/VexEntity.java | 2 +- .../type/living/monster/WardenEntity.java | 4 +- .../type/living/monster/WitherEntity.java | 2 +- .../type/living/monster/ZoglinEntity.java | 2 +- .../type/living/monster/ZombieEntity.java | 2 +- .../living/monster/ZombieVillagerEntity.java | 8 +-- .../raid/SpellcasterIllagerEntity.java | 2 +- .../living/monster/raid/VindicatorEntity.java | 2 +- .../entity/type/player/PlayerEntity.java | 31 +++++----- .../type/player/SessionPlayerEntity.java | 14 ++--- .../entity/type/player/SkullPlayerEntity.java | 2 +- .../erosion/GeyserboundPacketHandlerImpl.java | 4 +- .../geyser/impl/camera/GeyserCameraData.java | 13 +---- .../geyser/impl/camera/GeyserCameraFade.java | 2 +- .../geyser/inventory/AnvilContainer.java | 4 +- .../geyser/inventory/BeaconContainer.java | 2 +- .../inventory/CartographyContainer.java | 2 +- .../geysermc/geyser/inventory/Container.java | 2 +- .../geyser/inventory/CrafterContainer.java | 2 +- .../geyser/inventory/EnchantingContainer.java | 2 +- .../geyser/inventory/Generic3X3Container.java | 2 +- .../geyser/inventory/GeyserItemStack.java | 6 +- .../geysermc/geyser/inventory/Inventory.java | 6 +- .../geyser/inventory/LecternContainer.java | 2 +- .../geyser/inventory/MerchantContainer.java | 6 +- .../geyser/inventory/PlayerInventory.java | 2 +- .../inventory/StonecutterContainer.java | 2 +- .../geyser/inventory/click/Click.java | 2 +- .../geyser/inventory/click/ClickPlan.java | 10 ++-- .../geyser/inventory/recipe/GeyserRecipe.java | 2 +- .../inventory/recipe/GeyserShapedRecipe.java | 6 +- .../recipe/GeyserShapelessRecipe.java | 6 +- .../recipe/GeyserStonecutterData.java | 2 +- .../geyser/inventory/recipe/TrimRecipe.java | 2 +- .../updater/AnvilInventoryUpdater.java | 6 +- .../geyser/item/DyeableLeatherItem.java | 6 +- .../geysermc/geyser/item/type/ArmorItem.java | 6 +- .../geysermc/geyser/item/type/ArrowItem.java | 2 +- .../geyser/item/type/AxolotlBucketItem.java | 2 +- .../geysermc/geyser/item/type/BannerItem.java | 6 +- .../geysermc/geyser/item/type/ChestItem.java | 2 +- .../geyser/item/type/CompassItem.java | 8 +-- .../geyser/item/type/CrossbowItem.java | 6 +- .../geyser/item/type/DecoratedPotItem.java | 4 +- .../geyser/item/type/DyeableArmorItem.java | 2 +- .../item/type/DyeableHorseArmorItem.java | 2 +- .../geyser/item/type/EnchantedBookItem.java | 6 +- .../geyser/item/type/FilledMapItem.java | 4 +- .../geyser/item/type/FireworkRocketItem.java | 10 ++-- .../geyser/item/type/FireworkStarItem.java | 6 +- .../geyser/item/type/FishingRodItem.java | 2 +- .../geyser/item/type/GoatHornItem.java | 10 ++-- .../org/geysermc/geyser/item/type/Item.java | 10 ++-- .../geysermc/geyser/item/type/MapItem.java | 7 ++- .../geyser/item/type/PlayerHeadItem.java | 4 +- .../geysermc/geyser/item/type/PotionItem.java | 8 +-- .../geysermc/geyser/item/type/ShieldItem.java | 2 +- .../geyser/item/type/ShulkerBoxItem.java | 6 +- .../geyser/item/type/TippedArrowItem.java | 6 +- .../item/type/TropicalFishBucketItem.java | 4 +- .../geyser/item/type/WritableBookItem.java | 8 +-- .../geyser/item/type/WrittenBookItem.java | 8 +-- .../geysermc/geyser/level/BedrockMapIcon.java | 2 +- .../geyser/level/GeyserAdvancement.java | 6 +- .../geyser/level/GeyserWorldManager.java | 12 ++-- .../geysermc/geyser/level/JavaDimension.java | 2 +- .../geysermc/geyser/level/PaintingType.java | 2 +- .../geysermc/geyser/level/WorldManager.java | 8 +-- .../block/GeyserCustomBlockComponents.java | 13 +---- .../geyser/level/chunk/GeyserChunk.java | 2 +- .../geyser/level/physics/BoundingBox.java | 2 +- .../level/physics/CollisionManager.java | 4 +- .../geyser/level/physics/Direction.java | 18 +++--- .../geysermc/geyser/network/GameProtocol.java | 4 +- .../geyser/network/netty/LocalSession.java | 14 ++--- .../geyser/pack/SkullResourcePackManager.java | 4 +- .../ping/GeyserLegacyPingPassthrough.java | 4 +- .../geyser/ping/IGeyserPingPassthrough.java | 1 + .../registry/PacketTranslatorRegistry.java | 8 +-- .../geysermc/geyser/registry/Registries.java | 12 ++-- .../loader/BlockEntityRegistryLoader.java | 2 +- .../loader/ParticleTypesRegistryLoader.java | 2 +- .../loader/SoundEventsRegistryLoader.java | 8 +-- .../mappings/versions/MappingsReader_v1.java | 2 +- .../populator/PacketRegistryPopulator.java | 2 +- .../populator/RecipeRegistryPopulator.java | 6 +- .../geyser/registry/type/ItemMappings.java | 2 +- .../geysermc/geyser/scoreboard/Objective.java | 6 +- .../org/geysermc/geyser/scoreboard/Score.java | 4 +- .../geyser/scoreboard/Scoreboard.java | 7 +-- .../org/geysermc/geyser/scoreboard/Team.java | 4 +- .../geyser/session/DownstreamSession.java | 6 +- .../geyser/session/GeyserSession.java | 58 +++++++++---------- .../session/cache/AdvancementsCache.java | 4 +- .../geyser/session/cache/BookEditCache.java | 2 +- .../geyser/session/cache/ChunkCache.java | 2 +- .../session/cache/EntityEffectCache.java | 2 +- .../geyser/session/cache/LodestoneCache.java | 8 +-- .../geyser/session/cache/RegistryCache.java | 4 +- .../geyser/session/cache/TagCache.java | 2 +- .../geyser/session/cache/TeleportCache.java | 2 +- .../geyser/session/cache/WorldCache.java | 2 +- .../geyser/skin/FakeHeadProvider.java | 4 +- .../geysermc/geyser/text/ChatTypeEntry.java | 4 +- .../geysermc/geyser/text/MinecraftLocale.java | 4 +- .../geysermc/geyser/text/TextDecoration.java | 2 +- .../translator/collision/BlockCollision.java | 4 +- .../entity/EntityMetadataTranslator.java | 4 +- .../inventory/AnvilInventoryTranslator.java | 2 +- .../inventory/BaseInventoryTranslator.java | 8 +-- .../inventory/BeaconInventoryTranslator.java | 4 +- .../CartographyInventoryTranslator.java | 2 +- .../inventory/CrafterInventoryTranslator.java | 8 +-- .../EnchantingInventoryTranslator.java | 4 +- .../Generic3X3InventoryTranslator.java | 2 +- .../inventory/InventoryTranslator.java | 10 ++-- .../inventory/LecternInventoryTranslator.java | 18 +++--- .../inventory/LoomInventoryTranslator.java | 8 +-- .../MerchantInventoryTranslator.java | 4 +- .../inventory/OldSmithingTableTranslator.java | 6 +- .../inventory/PlayerInventoryTranslator.java | 15 ++--- .../inventory/ShulkerInventoryTranslator.java | 2 +- .../StonecutterInventoryTranslator.java | 6 +- .../translator/item/CustomItemTranslator.java | 4 +- .../translator/item/ItemTranslator.java | 14 ++--- .../translator/level/BiomeTranslator.java | 12 ++-- .../entity/BannerBlockEntityTranslator.java | 2 +- .../entity/BeaconBlockEntityTranslator.java | 2 +- .../entity/BedBlockEntityTranslator.java | 2 +- .../level/block/entity/BlockEntity.java | 2 +- .../block/entity/BlockEntityTranslator.java | 2 +- .../BrushableBlockEntityTranslator.java | 2 +- .../entity/CampfireBlockEntityTranslator.java | 2 +- .../CommandBlockBlockEntityTranslator.java | 2 +- .../DecoratedPotBlockEntityTranslator.java | 2 +- .../DoubleChestBlockEntityTranslator.java | 2 +- .../EndGatewayBlockEntityTranslator.java | 6 +- .../HangingSignBlockEntityTranslator.java | 2 +- .../JigsawBlockBlockEntityTranslator.java | 2 +- .../level/block/entity/PistonBlockEntity.java | 2 +- .../ShulkerBoxBlockEntityTranslator.java | 2 +- .../entity/SignBlockEntityTranslator.java | 2 +- .../entity/SkullBlockEntityTranslator.java | 2 +- .../entity/SpawnerBlockEntityTranslator.java | 2 +- .../StructureBlockBlockEntityTranslator.java | 2 +- .../TrialSpawnerBlockEntityTranslator.java | 2 +- .../level/event/LevelEventTranslator.java | 2 +- .../level/event/PlaySoundEventTranslator.java | 2 +- .../event/SoundEventEventTranslator.java | 2 +- .../event/SoundLevelEventTranslator.java | 2 +- .../bedrock/BedrockAnimateTranslator.java | 6 +- .../BedrockBlockEntityDataTranslator.java | 4 +- .../BedrockBlockPickRequestTranslator.java | 2 +- .../bedrock/BedrockBookEditTranslator.java | 12 ++-- .../BedrockCommandBlockUpdateTranslator.java | 6 +- .../BedrockContainerCloseTranslator.java | 2 +- ...BedrockInventoryTransactionTranslator.java | 22 +++---- .../BedrockItemFrameDropItemTranslator.java | 6 +- .../BedrockLecternUpdateTranslator.java | 10 ++-- .../BedrockMobEquipmentTranslator.java | 6 +- .../BedrockMoveEntityAbsoluteTranslator.java | 2 +- .../BedrockNetworkStackLatencyTranslator.java | 2 +- .../bedrock/BedrockPlayerInputTranslator.java | 4 +- .../BedrockRequestAbilityTranslator.java | 4 +- .../bedrock/BedrockRespawnTranslator.java | 4 +- .../bedrock/BedrockShowCreditsTranslator.java | 4 +- ...BedrockStructureBlockUpdateTranslator.java | 4 +- ...tructureTemplateDataRequestTranslator.java | 4 +- ...ockToggleCrafterSlotRequestTranslator.java | 2 +- .../entity/BedrockEntityEventTranslator.java | 2 +- .../player/BedrockActionTranslator.java | 10 +--- .../player/BedrockInteractTranslator.java | 12 ++-- .../player/BedrockMovePlayerTranslator.java | 8 +-- .../player/BedrockRiderJumpTranslator.java | 4 +- .../BedrockSetDefaultGameTypeTranslator.java | 2 +- .../BedrockSetDifficultyTranslator.java | 2 +- .../BedrockSetPlayerGameTypeTranslator.java | 2 +- ...ckSetPlayerInventoryOptionsTranslator.java | 6 +- .../BedrockLevelSoundEventTranslator.java | 8 +-- .../java/JavaAwardStatsTranslator.java | 2 +- .../java/JavaBossEventTranslator.java | 2 +- .../java/JavaChangeDifficultyTranslator.java | 2 +- .../JavaClientboundRecipesTranslator.java | 2 +- ...JavaClientboundResourcePackPushPacket.java | 6 +- .../protocol/java/JavaCommandsTranslator.java | 10 ++-- .../java/JavaCustomPayloadTranslator.java | 8 +-- .../java/JavaCustomQueryTranslator.java | 4 +- .../java/JavaDisconnectTranslator.java | 2 +- .../java/JavaDisguisedChatTranslator.java | 2 +- .../java/JavaGameProfileTranslator.java | 4 +- .../java/JavaKeepAliveTranslator.java | 2 +- .../java/JavaLoginDisconnectTranslator.java | 2 +- .../protocol/java/JavaLoginTranslator.java | 6 +- .../protocol/java/JavaPingTranslator.java | 4 +- .../java/JavaPlayerChatTranslator.java | 2 +- .../java/JavaRegistryDataTranslator.java | 2 +- .../protocol/java/JavaRespawnTranslator.java | 4 +- .../JavaSelectAdvancementsTabTranslator.java | 2 +- .../java/JavaSystemChatTranslator.java | 2 +- .../JavaUpdateAdvancementsTranslator.java | 4 +- .../java/JavaUpdateRecipesTranslator.java | 24 ++++---- .../java/JavaUpdateTagsTranslator.java | 2 +- .../java/entity/JavaAnimateTranslator.java | 4 +- .../entity/JavaDamageEventTranslator.java | 2 +- .../entity/JavaEntityEventTranslator.java | 2 +- .../JavaMoveEntityPosRotTranslator.java | 2 +- .../entity/JavaMoveEntityPosTranslator.java | 2 +- .../entity/JavaMoveEntityRotTranslator.java | 2 +- .../entity/JavaMoveVehicleTranslator.java | 2 +- .../entity/JavaRemoveEntitiesTranslator.java | 2 +- .../entity/JavaRemoveMobEffectTranslator.java | 2 +- .../java/entity/JavaRotateHeadTranslator.java | 2 +- .../entity/JavaSetEntityDataTranslator.java | 4 +- .../entity/JavaSetEntityLinkTranslator.java | 2 +- .../entity/JavaSetEntityMotionTranslator.java | 2 +- .../entity/JavaSetEquipmentTranslator.java | 6 +- .../entity/JavaSetPassengersTranslator.java | 2 +- .../entity/JavaSoundEntityTranslator.java | 2 +- .../entity/JavaTakeItemEntityTranslator.java | 2 +- .../entity/JavaTeleportEntityTranslator.java | 2 +- .../JavaUpdateAttributesTranslator.java | 2 +- .../entity/JavaUpdateMobEffectTranslator.java | 2 +- .../player/JavaBlockChangedAckTranslator.java | 2 +- .../player/JavaPlayerAbilitiesTranslator.java | 2 +- .../JavaPlayerCombatKillTranslator.java | 2 +- .../JavaPlayerInfoRemoveTranslator.java | 2 +- .../JavaPlayerInfoUpdateTranslator.java | 6 +- .../player/JavaPlayerLookAtTranslator.java | 2 +- .../player/JavaPlayerPositionTranslator.java | 8 +-- .../player/JavaSetCarriedItemTranslator.java | 2 +- .../player/JavaSetExperienceTranslator.java | 2 +- .../player/JavaSetHealthTranslator.java | 2 +- .../entity/spawn/JavaAddEntityTranslator.java | 14 ++--- .../spawn/JavaAddExperienceOrbTranslator.java | 2 +- .../JavaContainerCloseTranslator.java | 2 +- .../JavaContainerSetContentTranslator.java | 2 +- .../JavaContainerSetDataTranslator.java | 2 +- .../JavaContainerSetSlotTranslator.java | 6 +- .../JavaHorseScreenOpenTranslator.java | 2 +- .../JavaMerchantOffersTranslator.java | 6 +- .../inventory/JavaOpenBookTranslator.java | 6 +- .../inventory/JavaOpenScreenTranslator.java | 6 +- .../level/JavaBlockDestructionTranslator.java | 2 +- .../level/JavaBlockEntityDataTranslator.java | 6 +- .../java/level/JavaBlockEventTranslator.java | 4 +- .../java/level/JavaBlockUpdateTranslator.java | 2 +- .../JavaChunkBatchFinishedTranslator.java | 4 +- .../java/level/JavaCooldownTranslator.java | 2 +- .../java/level/JavaExplodeTranslator.java | 2 +- .../level/JavaForgetLevelChunkTranslator.java | 2 +- .../java/level/JavaGameEventTranslator.java | 16 ++--- .../JavaLevelChunkWithLightTranslator.java | 29 ++++------ .../java/level/JavaLevelEventTranslator.java | 6 +- .../level/JavaLevelParticlesTranslator.java | 18 +++--- .../java/level/JavaMapItemDataTranslator.java | 6 +- .../level/JavaOpenSignEditorTranslator.java | 2 +- .../JavaSectionBlocksUpdateTranslator.java | 4 +- .../JavaSetChunkCacheCenterTranslator.java | 2 +- .../JavaSetChunkCacheRadiusTranslator.java | 2 +- ...JavaSetDefaultSpawnPositionTranslator.java | 2 +- .../java/level/JavaSetTimeTranslator.java | 2 +- .../java/level/JavaSoundTranslator.java | 2 +- .../java/level/JavaStopSoundTranslator.java | 2 +- .../JavaInitializeBorderTranslator.java | 2 +- .../border/JavaSetBorderCenterTranslator.java | 2 +- .../JavaSetBorderLerpSizeTranslator.java | 2 +- .../border/JavaSetBorderSizeTranslator.java | 2 +- .../JavaSetBorderWarningDelayTranslator.java | 2 +- ...avaSetBorderWarningDistanceTranslator.java | 2 +- .../java/scoreboard/JavaResetScorePacket.java | 4 +- .../JavaSetDisplayObjectiveTranslator.java | 2 +- .../JavaSetObjectiveTranslator.java | 6 +- .../JavaSetPlayerTeamTranslator.java | 8 +-- .../scoreboard/JavaSetScoreTranslator.java | 4 +- .../java/title/JavaClearTitlesTranslator.java | 2 +- .../title/JavaSetActionBarTextTranslator.java | 2 +- .../title/JavaSetSubtitleTextTranslator.java | 2 +- .../title/JavaSetTitleTextTranslator.java | 2 +- .../JavaSetTitlesAnimationTranslator.java | 2 +- .../BlockSoundInteractionTranslator.java | 2 +- .../translator/text/MessageTranslator.java | 4 +- .../geysermc/geyser/util/AttributeUtils.java | 6 +- .../geyser/util/BlockEntityUtils.java | 2 +- .../org/geysermc/geyser/util/BlockUtils.java | 4 +- .../geysermc/geyser/util/CooldownUtils.java | 2 +- .../geysermc/geyser/util/DimensionUtils.java | 8 +-- .../org/geysermc/geyser/util/EntityUtils.java | 8 +-- .../geysermc/geyser/util/InventoryUtils.java | 12 ++-- .../org/geysermc/geyser/util/ItemUtils.java | 6 +- .../geyser/util/PluginMessageUtils.java | 2 +- .../org/geysermc/geyser/util/SoundUtils.java | 2 +- .../geyser/util/StatisticFormatters.java | 2 +- .../geysermc/geyser/util/StatisticsUtils.java | 2 +- .../geyser/util/StructureBlockUtils.java | 24 ++++---- .../chat/MessageTranslatorTest.java | 2 +- .../loader/ResourcePackLoaderTest.java | 4 +- gradle/libs.versions.toml | 2 +- 389 files changed, 869 insertions(+), 956 deletions(-) diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java index b9fbd6cdc..656305690 100644 --- a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.platform.mod.world; -import com.github.steveice10.mc.protocol.data.game.Holder; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.item.component.BannerPatternLayer; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo; +import org.geysermc.mcprotocollib.protocol.data.game.Holder; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityInfo; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import net.minecraft.SharedConstants; @@ -222,8 +222,8 @@ public class GeyserModWorldManager extends GeyserWorldManager { @NonNull @Override - public CompletableFuture getPickItemComponents(GeyserSession session, int x, int y, int z, boolean addNbtData) { - CompletableFuture future = new CompletableFuture<>(); + public CompletableFuture getPickItemComponents(GeyserSession session, int x, int y, int z, boolean addNbtData) { + CompletableFuture future = new CompletableFuture<>(); server.execute(() -> { ServerPlayer player = getPlayer(session); if (player == null) { @@ -240,8 +240,8 @@ public class GeyserModWorldManager extends GeyserWorldManager { // the banner might have a custom name, both of which a Java client knows and caches ItemStack itemStack = banner.getItem(); - com.github.steveice10.mc.protocol.data.game.item.component.DataComponents components = - new com.github.steveice10.mc.protocol.data.game.item.component.DataComponents(new HashMap<>()); + org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents components = + new org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents(new HashMap<>()); components.put(DataComponentType.DAMAGE, itemStack.getDamageValue()); diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java index ad31131bd..43ecf7154 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.platform.spigot; -import com.github.steveice10.mc.protocol.MinecraftProtocol; +import org.geysermc.mcprotocollib.protocol.MinecraftProtocol; import com.viaversion.viaversion.bukkit.handlers.BukkitChannelInitializer; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.*; diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/PaperAdventure.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/PaperAdventure.java index 9e0b14b11..fa7555ac6 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/PaperAdventure.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/PaperAdventure.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.platform.spigot; -import com.github.steveice10.mc.protocol.data.DefaultComponentSerializer; +import org.geysermc.mcprotocollib.protocol.data.DefaultComponentSerializer; import net.kyori.adventure.text.Component; import org.bukkit.command.CommandSender; import org.checkerframework.checker.nullness.qual.Nullable; diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserPistonListener.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserPistonListener.java index 01b0be9f2..61c0d5fe8 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserPistonListener.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserPistonListener.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.platform.spigot.world; -import com.github.steveice10.mc.protocol.data.game.level.block.value.PistonValueType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.PistonValueType; import org.cloudburstmc.math.vector.Vector3i; import it.unimi.dsi.fastutil.objects.Object2IntArrayMap; import it.unimi.dsi.fastutil.objects.Object2IntMap; diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java index 07a9d489a..8a0e0b70d 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.platform.spigot.world.manager; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityInfo; import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.World; diff --git a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java index 8b54f5298..5c4313f09 100644 --- a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java +++ b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java @@ -29,7 +29,6 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import com.github.steveice10.packetlib.tcp.TcpSession; import io.netty.channel.epoll.Epoll; import io.netty.util.NettyRuntime; import io.netty.util.concurrent.DefaultThreadFactory; @@ -86,6 +85,7 @@ import org.geysermc.geyser.text.GeyserLocale; import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.util.*; +import org.geysermc.mcprotocollib.network.tcp.TcpSession; import java.io.File; import java.io.FileWriter; diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/StatisticsCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/StatisticsCommand.java index 1ff12dea3..5952ea00d 100644 --- a/core/src/main/java/org/geysermc/geyser/command/defaults/StatisticsCommand.java +++ b/core/src/main/java/org/geysermc/geyser/command/defaults/StatisticsCommand.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.command.defaults; -import com.github.steveice10.mc.protocol.data.game.ClientCommand; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.command.GeyserCommand; import org.geysermc.geyser.command.GeyserCommandSource; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.ClientCommand; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket; public class StatisticsCommand extends GeyserCommand { diff --git a/core/src/main/java/org/geysermc/geyser/dump/BootstrapDumpInfo.java b/core/src/main/java/org/geysermc/geyser/dump/BootstrapDumpInfo.java index 6a56c536a..7851fadfd 100644 --- a/core/src/main/java/org/geysermc/geyser/dump/BootstrapDumpInfo.java +++ b/core/src/main/java/org/geysermc/geyser/dump/BootstrapDumpInfo.java @@ -27,8 +27,8 @@ package org.geysermc.geyser.dump; import lombok.AllArgsConstructor; import lombok.Getter; -import org.geysermc.geyser.api.util.PlatformType; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.api.util.PlatformType; import org.geysermc.geyser.text.AsteriskSerializer; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/dump/DumpInfo.java b/core/src/main/java/org/geysermc/geyser/dump/DumpInfo.java index e54bbc1eb..6989dc10a 100644 --- a/core/src/main/java/org/geysermc/geyser/dump/DumpInfo.java +++ b/core/src/main/java/org/geysermc/geyser/dump/DumpInfo.java @@ -56,12 +56,7 @@ import java.net.InetSocketAddress; import java.net.Socket; import java.net.UnknownHostException; import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Properties; +import java.util.*; import java.util.stream.Collectors; @Getter diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinition.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinition.java index 8b430d559..f0e221bad 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinition.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinition.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.entity; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType; -import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.MetadataType; +import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import lombok.Setter; import lombok.experimental.Accessors; diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index f454bef88..328dd4bbf 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.entity; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.MetadataType; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.type.*; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/AbstractArrowEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/AbstractArrowEntity.java index 6828d1020..1cc746d7a 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/AbstractArrowEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/AbstractArrowEntity.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/AreaEffectCloudEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/AreaEffectCloudEntity.java index 84dfae468..4b8eea061 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/AreaEffectCloudEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/AreaEffectCloudEntity.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.level.particle.Particle; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.ParticleType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; @@ -35,6 +32,9 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.Particle; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/BoatEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/BoatEntity.java index e3420abeb..d9a64ccc6 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/BoatEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/BoatEntity.java @@ -25,22 +25,21 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; +import lombok.Getter; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.packet.AnimatePacket; import org.cloudburstmc.protocol.bedrock.packet.MoveEntityAbsolutePacket; -import lombok.Getter; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; -import java.util.concurrent.TimeUnit; public class BoatEntity extends Entity implements Tickable { diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ChestBoatEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ChestBoatEntity.java index 675e9517d..479b4d80d 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ChestBoatEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ChestBoatEntity.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/CommandBlockMinecartEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/CommandBlockMinecartEntity.java index 9c7a28f6e..2d0835286 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/CommandBlockMinecartEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/CommandBlockMinecartEntity.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/DefaultBlockMinecartEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/DefaultBlockMinecartEntity.java index 63b5ff2ab..fd6f17eb8 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/DefaultBlockMinecartEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/DefaultBlockMinecartEntity.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/EnderCrystalEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/EnderCrystalEntity.java index 86436f82b..932864bf7 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/EnderCrystalEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/EnderCrystalEntity.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java index 306c244b3..f1d6bfb98 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java @@ -25,13 +25,6 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; -import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType; import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; @@ -42,12 +35,7 @@ import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; -import org.cloudburstmc.protocol.bedrock.packet.AddEntityPacket; -import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket; -import org.cloudburstmc.protocol.bedrock.packet.MoveEntityAbsolutePacket; -import org.cloudburstmc.protocol.bedrock.packet.MoveEntityDeltaPacket; -import org.cloudburstmc.protocol.bedrock.packet.RemoveEntityPacket; -import org.cloudburstmc.protocol.bedrock.packet.SetEntityDataPacket; +import org.cloudburstmc.protocol.bedrock.packet.*; import org.geysermc.geyser.api.entity.type.GeyserEntity; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.GeyserDirtyMetadata; @@ -57,12 +45,15 @@ import org.geysermc.geyser.util.EntityUtils; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; import org.geysermc.geyser.util.MathUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; -import java.util.Collections; -import java.util.EnumSet; -import java.util.List; -import java.util.Optional; -import java.util.UUID; +import java.util.*; @Getter @Setter diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/FallingBlockEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/FallingBlockEntity.java index e6d3a5783..4fcec7a63 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/FallingBlockEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/FallingBlockEntity.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java index 04317e6d6..f0739abb3 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.packet.SetEntityMotionPacket; @@ -36,6 +33,9 @@ import org.geysermc.geyser.entity.type.player.PlayerEntity; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import java.util.OptionalInt; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java index 0de11c382..f4c0cea36 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java @@ -25,11 +25,10 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import lombok.Getter; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.packet.PlaySoundPacket; -import lombok.Getter; import org.geysermc.erosion.util.BlockPositionIterator; import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.type.player.PlayerEntity; @@ -38,6 +37,7 @@ import org.geysermc.geyser.level.physics.BoundingBox; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.collision.BlockCollision; import org.geysermc.geyser.util.BlockUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; import java.util.concurrent.ThreadLocalRandom; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/FurnaceMinecartEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/FurnaceMinecartEntity.java index a7a117fff..ef584c4fd 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/FurnaceMinecartEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/FurnaceMinecartEntity.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/InteractionEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/InteractionEntity.java index 0917465d4..4e7a805b4 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/InteractionEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/InteractionEntity.java @@ -25,16 +25,16 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundSwingPacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.AnimatePacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundSwingPacket; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java index 226ad7df8..ead717b34 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; @@ -38,6 +36,8 @@ import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.ItemTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import java.util.UUID; import java.util.concurrent.CompletableFuture; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java index 453125945..f38e727c0 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java @@ -25,12 +25,7 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.object.Direction; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; -import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType; +import lombok.Getter; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; @@ -39,12 +34,17 @@ import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.packet.BlockEntityDataPacket; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; -import lombok.Getter; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InventoryUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/LeashKnotEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/LeashKnotEntity.java index 3f0d2ee68..af739297c 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/LeashKnotEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/LeashKnotEntity.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java index b070bdfff..5823ba3b2 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java @@ -25,14 +25,6 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.attribute.Attribute; -import com.github.steveice10.mc.protocol.data.game.entity.attribute.AttributeType; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import lombok.AccessLevel; @@ -57,6 +49,14 @@ import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.AttributeUtils; import org.geysermc.geyser.util.InteractionResult; +import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.Attribute; +import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.AttributeType; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.*; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/MinecartEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/MinecartEntity.java index ecf67052b..9096d8bd6 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/MinecartEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/MinecartEntity.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; @@ -35,6 +32,9 @@ import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/PaintingEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/PaintingEntity.java index 4e5fe9d59..f5145c11f 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/PaintingEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/PaintingEntity.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.object.Direction; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.packet.AddPaintingPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.level.PaintingType; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; import java.util.UUID; @@ -49,7 +49,7 @@ public class PaintingEntity extends Entity { // Wait until we get the metadata needed } - public void setPaintingType(ObjectEntityMetadata entityMetadata) { + public void setPaintingType(ObjectEntityMetadata entityMetadata) { PaintingType type = PaintingType.getByPaintingType(entityMetadata.getValue()); AddPaintingPacket addPaintingPacket = new AddPaintingPacket(); addPaintingPacket.setUniqueEntityId(geyserId); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/TNTEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/TNTEntity.java index 98c2edd00..dca36cda0 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/TNTEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/TNTEntity.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.SetEntityDataPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/TextDisplayEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/TextDisplayEntity.java index 0b6160401..28f38f919 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/TextDisplayEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/TextDisplayEntity.java @@ -25,14 +25,14 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import net.kyori.adventure.text.Component; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.text.MessageTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import java.util.Optional; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEntity.java index 47884e60a..25bbdbd3c 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -34,6 +33,7 @@ import org.cloudburstmc.protocol.bedrock.packet.MoveEntityDeltaPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableItemEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableItemEntity.java index 3c080345e..55334010f 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableItemEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableItemEntity.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java index 31428477a..bfe429f33 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java @@ -25,11 +25,6 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.PotionContents; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -39,6 +34,11 @@ import org.geysermc.geyser.inventory.item.Potion; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.PotionContents; import java.util.EnumSet; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/TippedArrowEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/TippedArrowEntity.java index 856c4cc66..be4133028 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/TippedArrowEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/TippedArrowEntity.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.item.TippedArrowPotion; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/WitherSkullEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/WitherSkullEntity.java index 637ca4139..8427a8e10 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/WitherSkullEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/WitherSkullEntity.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.EntityDefinitions; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/AbstractFishEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/AbstractFishEntity.java index 9cc3a006e..6ecfa4978 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/AbstractFishEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/AbstractFishEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -34,6 +33,7 @@ import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.EntityUtils; import org.geysermc.geyser.util.InteractionResult; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/AgeableEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/AgeableEntity.java index 6e2e7a407..5b1d682ce 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/AgeableEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/AgeableEntity.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.entity.type.living; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/AllayEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/AllayEntity.java index 48d633e5d..01a42e527 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/AllayEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/AllayEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type.living; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -36,6 +34,8 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java index 9c56568c8..c64f2f218 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java @@ -25,10 +25,6 @@ package org.geysermc.geyser.entity.type.living; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import lombok.Getter; import net.kyori.adventure.text.Component; import org.cloudburstmc.math.vector.Vector3f; @@ -43,6 +39,10 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.MathUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.Optional; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/BatEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/BatEntity.java index 644054e72..bdfc20c88 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/BatEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/BatEntity.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.entity.type.living; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/DolphinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/DolphinEntity.java index a43bb666f..6182a27f4 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/DolphinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/DolphinEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.EntityDefinition; @@ -34,6 +33,7 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/IronGolemEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/IronGolemEntity.java index 7afa4b436..58a349cc9 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/IronGolemEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/IronGolemEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; @@ -35,6 +34,7 @@ import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/MobEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/MobEntity.java index 0ac81c957..95145ae60 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/MobEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/MobEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type.living; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import lombok.Getter; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; @@ -40,6 +38,8 @@ import org.geysermc.geyser.item.type.SpawnEggItem; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/SlimeEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/SlimeEntity.java index 1d2eb95bc..50095fe3f 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/SlimeEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/SlimeEntity.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.entity.type.living; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/SnowGolemEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/SnowGolemEntity.java index 7f0699415..50aa7b90e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/SnowGolemEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/SnowGolemEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type.living; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -36,6 +34,8 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/TadpoleEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/TadpoleEntity.java index 7094c431e..4fdaa1059 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/TadpoleEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/TadpoleEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.EntityDefinition; @@ -34,6 +33,7 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AnimalEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AnimalEntity.java index 7278709ce..bf23a5418 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AnimalEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AnimalEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; @@ -38,6 +37,7 @@ import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java index c4f95e546..37cd5f1e6 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; @@ -39,6 +36,9 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.EntityUtils; import org.geysermc.geyser.util.InteractionResult; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java index 7f1a88d7b..d6aa9615d 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; @@ -36,6 +34,8 @@ import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/CowEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/CowEntity.java index cdcf534a3..d542cb46f 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/CowEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/CowEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; @@ -36,6 +35,7 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FoxEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FoxEntity.java index 200505f14..18e346b98 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FoxEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FoxEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -34,6 +32,8 @@ import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FrogEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FrogEntity.java index 039ef5bf9..ed21a9609 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FrogEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FrogEntity.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -36,6 +33,9 @@ import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; import java.util.OptionalInt; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/GoatEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/GoatEntity.java index 9ed94f96f..7cbbd4433 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/GoatEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/GoatEntity.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; @@ -38,6 +35,9 @@ import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java index 154c2f688..29d1839c7 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/MooshroomEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/MooshroomEntity.java index 8673eb18e..55c3c406f 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/MooshroomEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/MooshroomEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; @@ -37,6 +35,8 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/OcelotEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/OcelotEntity.java index c115ebcdc..8a3dd6c72 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/OcelotEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/OcelotEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -36,6 +35,7 @@ import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java index d2ef36932..df72fdc63 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; @@ -42,6 +39,9 @@ import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PigEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PigEntity.java index 2bc02cd55..4dbf3064a 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PigEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PigEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -37,6 +36,7 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.EntityUtils; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PufferFishEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PufferFishEntity.java index d0d119593..6f0063474 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PufferFishEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PufferFishEntity.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.living.AbstractFishEntity; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/RabbitEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/RabbitEntity.java index 1efa87ec8..09db7257b 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/RabbitEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/RabbitEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -33,6 +32,7 @@ import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SheepEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SheepEntity.java index 13059244a..e87186bf6 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SheepEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SheepEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; @@ -38,6 +36,8 @@ import org.geysermc.geyser.item.type.DyeItem; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SnifferEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SnifferEntity.java index 0e6fffbc0..35b2b4183 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SnifferEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SnifferEntity.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.SnifferState; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; @@ -40,6 +37,9 @@ import org.geysermc.geyser.entity.type.Tickable; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.SnifferState; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/StriderEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/StriderEntity.java index 39a55fa1e..dcdd40199 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/StriderEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/StriderEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -39,6 +37,8 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.EntityUtils; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TropicalFishEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TropicalFishEntity.java index b18e55a48..b6751bc3f 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TropicalFishEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TropicalFishEntity.java @@ -25,14 +25,14 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import com.google.common.collect.ImmutableList; +import it.unimi.dsi.fastutil.ints.IntList; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; -import it.unimi.dsi.fastutil.ints.IntList; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.living.AbstractFishEntity; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.List; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TurtleEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TurtleEntity.java index 870ded193..1d0aec75f 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TurtleEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TurtleEntity.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.entity.type.living.animal; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/AbstractHorseEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/AbstractHorseEntity.java index faa495487..76416c146 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/AbstractHorseEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/AbstractHorseEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal.horse; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; @@ -44,6 +42,8 @@ import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.Set; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/CamelEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/CamelEntity.java index 8106b096d..00144617a 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/CamelEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/CamelEntity.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal.horse; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; @@ -38,6 +35,9 @@ import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/HorseEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/HorseEntity.java index dfa6ef30a..b8a9a8f28 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/HorseEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/HorseEntity.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.entity.type.living.animal.horse; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java index 29da2e0dc..346b6da9b 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal.horse; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import lombok.Getter; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; @@ -34,6 +33,7 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.MathUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/SkeletonHorseEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/SkeletonHorseEntity.java index 7080f9f75..d74913c31 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/SkeletonHorseEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/SkeletonHorseEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal.horse; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.EntityDefinition; @@ -33,6 +32,7 @@ import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/ZombieHorseEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/ZombieHorseEntity.java index 3275712fc..9e77daebc 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/ZombieHorseEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/ZombieHorseEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal.horse; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.EntityDefinition; @@ -33,6 +32,7 @@ import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/CatEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/CatEntity.java index 93cb92c7d..fc5978c2b 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/CatEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/CatEntity.java @@ -25,10 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal.tameable; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; @@ -40,6 +36,10 @@ import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/ParrotEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/ParrotEntity.java index 4c4b6a222..18feec979 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/ParrotEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/ParrotEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal.tameable; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -36,6 +35,7 @@ import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.Set; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/TameableEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/TameableEntity.java index 5fc8c459d..4a1cd70e9 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/TameableEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/TameableEntity.java @@ -25,16 +25,16 @@ package org.geysermc.geyser.entity.type.living.animal.tameable; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import lombok.Getter; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; -import lombok.Getter; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.living.animal.AnimalEntity; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import java.util.Optional; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java index ff130aeff..29c3526fe 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.entity.type.living.animal.tameable; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; @@ -42,6 +39,9 @@ import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.Collections; import java.util.Locale; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/AbstractMerchantEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/AbstractMerchantEntity.java index c7b29130f..64e35e52e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/AbstractMerchantEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/AbstractMerchantEntity.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.entity.type.living.merchant; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -37,6 +36,7 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/VillagerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/VillagerEntity.java index 9b0f50050..3c2160a2b 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/VillagerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/VillagerEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type.living.merchant; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.VillagerData; import lombok.Getter; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; @@ -38,6 +36,8 @@ import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.type.BlockMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.VillagerData; import java.util.Optional; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/AbstractSkeletonEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/AbstractSkeletonEntity.java index 04b3bba1b..3fbdda245 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/AbstractSkeletonEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/AbstractSkeletonEntity.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BasePiglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BasePiglinEntity.java index 5f2647b7a..09bd28cd0 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BasePiglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BasePiglinEntity.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BlazeEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BlazeEntity.java index 43d78f468..5b26d7bd1 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BlazeEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BlazeEntity.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/CreeperEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/CreeperEntity.java index f134c31b3..5f54d2942 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/CreeperEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/CreeperEntity.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; @@ -38,6 +35,9 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonEntity.java index 8c00d065a..0162d498e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonEntity.java @@ -25,23 +25,19 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import lombok.Data; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.ParticleType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; -import org.cloudburstmc.protocol.bedrock.packet.AddEntityPacket; -import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket; -import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; -import org.cloudburstmc.protocol.bedrock.packet.PlaySoundPacket; -import org.cloudburstmc.protocol.bedrock.packet.SpawnParticleEffectPacket; +import org.cloudburstmc.protocol.bedrock.packet.*; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.Tickable; import org.geysermc.geyser.entity.type.living.MobEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.DimensionUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.Optional; import java.util.Random; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EndermanEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EndermanEntity.java index 5b8e23f8b..586ba5cd9 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EndermanEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EndermanEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; @@ -35,6 +33,8 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEvent2Packet; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/GhastEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/GhastEntity.java index f7b9d17b8..984aab642 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/GhastEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/GhastEntity.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.living.FlyingEntity; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/GuardianEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/GuardianEntity.java index 92e50d207..40793522e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/GuardianEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/GuardianEntity.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PhantomEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PhantomEntity.java index 915e34e79..cb4b7a8cf 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PhantomEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PhantomEntity.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.living.FlyingEntity; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java index 696982a33..db2a3ecc3 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; @@ -38,6 +36,8 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ShulkerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ShulkerEntity.java index 27dd45f40..aecb4a915 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ShulkerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ShulkerEntity.java @@ -25,15 +25,15 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.object.Direction; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.living.GolemEntity; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/SkeletonEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/SkeletonEntity.java index da11b2759..a6343e256 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/SkeletonEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/SkeletonEntity.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/SpiderEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/SpiderEntity.java index 03e234911..4a4527cef 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/SpiderEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/SpiderEntity.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/VexEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/VexEntity.java index 56a0975ae..840f5b3b4 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/VexEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/VexEntity.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/WardenEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/WardenEntity.java index 7a0c5e040..2341b8c32 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/WardenEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/WardenEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.GenericMath; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; @@ -36,6 +34,8 @@ import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.Tickable; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.MathUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; import java.util.concurrent.ThreadLocalRandom; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/WitherEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/WitherEntity.java index 3abb7f122..19c1a457b 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/WitherEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/WitherEntity.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java index 6e40573ba..efbb7753c 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieEntity.java index af6a30a10..11354fbf8 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieEntity.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieVillagerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieVillagerEntity.java index 32e45507a..6e03e4f98 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieVillagerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieVillagerEntity.java @@ -25,10 +25,6 @@ package org.geysermc.geyser.entity.type.living.monster; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.VillagerData; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; @@ -40,6 +36,10 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.VillagerData; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/SpellcasterIllagerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/SpellcasterIllagerEntity.java index f083437ae..8d4b3c44e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/SpellcasterIllagerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/SpellcasterIllagerEntity.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.entity.type.living.monster.raid; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/VindicatorEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/VindicatorEntity.java index ad99dda50..04a58addd 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/VindicatorEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/VindicatorEntity.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.entity.type.living.monster.raid; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import java.util.UUID; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java index b957a0243..1ca387259 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java @@ -25,18 +25,6 @@ package org.geysermc.geyser.entity.type.player; -import com.github.steveice10.mc.protocol.codec.NbtComponentSerializer; -import com.github.steveice10.mc.protocol.data.game.chat.numbers.BlankFormat; -import com.github.steveice10.mc.protocol.data.game.chat.numbers.FixedFormat; -import com.github.steveice10.mc.protocol.data.game.chat.numbers.NumberFormat; -import com.github.steveice10.mc.protocol.data.game.chat.numbers.StyledFormat; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition; -import com.github.steveice10.mc.protocol.data.game.scoreboard.TeamColor; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import lombok.Getter; @@ -47,18 +35,13 @@ import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.Ability; import org.cloudburstmc.protocol.bedrock.data.AbilityLayer; -import org.cloudburstmc.protocol.bedrock.data.AttributeData; import org.cloudburstmc.protocol.bedrock.data.GameType; import org.cloudburstmc.protocol.bedrock.data.PlayerPermission; import org.cloudburstmc.protocol.bedrock.data.command.CommandPermission; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData; -import org.cloudburstmc.protocol.bedrock.packet.AddPlayerPacket; -import org.cloudburstmc.protocol.bedrock.packet.MovePlayerPacket; -import org.cloudburstmc.protocol.bedrock.packet.SetEntityDataPacket; -import org.cloudburstmc.protocol.bedrock.packet.SetEntityLinkPacket; -import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket; +import org.cloudburstmc.protocol.bedrock.packet.*; import org.geysermc.geyser.api.entity.type.player.GeyserPlayerEntity; import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.attribute.GeyserAttributeType; @@ -73,6 +56,18 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.util.ChunkUtils; +import org.geysermc.mcprotocollib.protocol.codec.NbtComponentSerializer; +import org.geysermc.mcprotocollib.protocol.data.game.chat.numbers.BlankFormat; +import org.geysermc.mcprotocollib.protocol.data.game.chat.numbers.FixedFormat; +import org.geysermc.mcprotocollib.protocol.data.game.chat.numbers.NumberFormat; +import org.geysermc.mcprotocollib.protocol.data.game.chat.numbers.StyledFormat; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.ScoreboardPosition; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.TeamColor; import java.util.Collections; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java index 89aa540d8..e10adb134 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java @@ -25,13 +25,6 @@ package org.geysermc.geyser.entity.type.player; -import com.github.steveice10.mc.protocol.data.game.entity.attribute.Attribute; -import com.github.steveice10.mc.protocol.data.game.entity.attribute.AttributeType; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.GlobalPos; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import lombok.Getter; import org.checkerframework.checker.nullness.qual.Nullable; @@ -45,6 +38,13 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.AttributeUtils; import org.geysermc.geyser.util.DimensionUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.Attribute; +import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.AttributeType; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.GlobalPos; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; import java.util.Collections; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/SkullPlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/SkullPlayerEntity.java index 939e4721d..89f9c37d6 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/SkullPlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/SkullPlayerEntity.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.entity.type.player; +import lombok.Getter; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.GameType; @@ -33,7 +34,6 @@ import org.cloudburstmc.protocol.bedrock.data.command.CommandPermission; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.AddPlayerPacket; -import lombok.Getter; import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.SkullCache; diff --git a/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java b/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java index 57147fc49..a62f9ec49 100644 --- a/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java +++ b/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.erosion; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.level.block.value.PistonValueType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.PistonValueType; import io.netty.channel.Channel; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; diff --git a/core/src/main/java/org/geysermc/geyser/impl/camera/GeyserCameraData.java b/core/src/main/java/org/geysermc/geyser/impl/camera/GeyserCameraData.java index 28c881eba..2a93c89e3 100644 --- a/core/src/main/java/org/geysermc/geyser/impl/camera/GeyserCameraData.java +++ b/core/src/main/java/org/geysermc/geyser/impl/camera/GeyserCameraData.java @@ -38,19 +38,10 @@ import org.cloudburstmc.protocol.bedrock.data.camera.CameraSetInstruction; import org.cloudburstmc.protocol.bedrock.packet.CameraInstructionPacket; import org.cloudburstmc.protocol.bedrock.packet.CameraShakePacket; import org.cloudburstmc.protocol.bedrock.packet.PlayerFogPacket; -import org.geysermc.geyser.api.bedrock.camera.CameraEaseType; -import org.geysermc.geyser.api.bedrock.camera.CameraData; -import org.geysermc.geyser.api.bedrock.camera.CameraFade; -import org.geysermc.geyser.api.bedrock.camera.CameraPerspective; -import org.geysermc.geyser.api.bedrock.camera.CameraPosition; -import org.geysermc.geyser.api.bedrock.camera.CameraShake; +import org.geysermc.geyser.api.bedrock.camera.*; import org.geysermc.geyser.session.GeyserSession; -import java.util.Collections; -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; -import java.util.UUID; +import java.util.*; public class GeyserCameraData implements CameraData { diff --git a/core/src/main/java/org/geysermc/geyser/impl/camera/GeyserCameraFade.java b/core/src/main/java/org/geysermc/geyser/impl/camera/GeyserCameraFade.java index 648e70c81..f69504545 100644 --- a/core/src/main/java/org/geysermc/geyser/impl/camera/GeyserCameraFade.java +++ b/core/src/main/java/org/geysermc/geyser/impl/camera/GeyserCameraFade.java @@ -29,7 +29,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.common.value.qual.IntRange; import org.geysermc.geyser.api.bedrock.camera.CameraFade; -import java.awt.Color; +import java.awt.*; import java.util.Objects; public record GeyserCameraFade( diff --git a/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java index 1c5826cdb..e6332bc41 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket; import lombok.Getter; import lombok.Setter; import org.checkerframework.checker.nullness.qual.Nullable; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/BeaconContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/BeaconContainer.java index 7644ada73..1b59772fa 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/BeaconContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/BeaconContainer.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import lombok.Getter; import lombok.Setter; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/CartographyContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/CartographyContainer.java index 72f1088c3..ace3f93ad 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/CartographyContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/CartographyContainer.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; public class CartographyContainer extends Container { public CartographyContainer(String title, int id, int size, ContainerType containerType, PlayerInventory playerInventory) { diff --git a/core/src/main/java/org/geysermc/geyser/inventory/Container.java b/core/src/main/java/org/geysermc/geyser/inventory/Container.java index 79fa67da1..209aeb24f 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/Container.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/Container.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import lombok.Getter; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.session.GeyserSession; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/CrafterContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/CrafterContainer.java index bcacd3587..41452bed6 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/CrafterContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/CrafterContainer.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import lombok.Getter; import lombok.Setter; import org.geysermc.geyser.GeyserImpl; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/EnchantingContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/EnchantingContainer.java index ac55aae60..08397ab44 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/EnchantingContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/EnchantingContainer.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import org.cloudburstmc.protocol.bedrock.data.inventory.EnchantOptionData; import lombok.Getter; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/Generic3X3Container.java b/core/src/main/java/org/geysermc/geyser/inventory/Generic3X3Container.java index 6518dce7c..65e47d877 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/Generic3X3Container.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/Generic3X3Container.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import lombok.Getter; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.inventory.Generic3X3InventoryTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; public class Generic3X3Container extends Container { /** diff --git a/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java b/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java index a1ecc6f58..f75c1fdd9 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import lombok.AccessLevel; import lombok.Data; @@ -42,6 +39,9 @@ import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.ItemTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; @Data public class GeyserItemStack { diff --git a/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java b/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java index b78bbe1b3..4e8257ff8 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java @@ -25,20 +25,20 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import com.github.steveice10.opennbt.tag.builtin.ByteTag; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.Tag; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.math.vector.Vector3i; import lombok.Getter; import lombok.Setter; import lombok.ToString; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.ItemTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import org.jetbrains.annotations.Range; import java.util.Arrays; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/LecternContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/LecternContainer.java index 7ac2fed99..389611c67 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/LecternContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/LecternContainer.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import lombok.Getter; import lombok.Setter; import org.checkerframework.checker.nullness.qual.NonNull; @@ -33,6 +32,7 @@ import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.java.inventory.JavaOpenBookTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; public class LecternContainer extends Container { @Getter @Setter diff --git a/core/src/main/java/org/geysermc/geyser/inventory/MerchantContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/MerchantContainer.java index 105b5ca5b..0bfa6d1a7 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/MerchantContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/MerchantContainer.java @@ -25,14 +25,14 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; -import com.github.steveice10.mc.protocol.data.game.inventory.VillagerTrade; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundMerchantOffersPacket; import lombok.Getter; import lombok.Setter; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.VillagerTrade; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundMerchantOffersPacket; public class MerchantContainer extends Container { @Getter @Setter diff --git a/core/src/main/java/org/geysermc/geyser/inventory/PlayerInventory.java b/core/src/main/java/org/geysermc/geyser/inventory/PlayerInventory.java index bda09a4ed..9bef4b08e 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/PlayerInventory.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/PlayerInventory.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import lombok.Getter; import lombok.Setter; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import org.jetbrains.annotations.Range; public class PlayerInventory extends Inventory { diff --git a/core/src/main/java/org/geysermc/geyser/inventory/StonecutterContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/StonecutterContainer.java index f99a0c71e..269a4fb7d 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/StonecutterContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/StonecutterContainer.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import lombok.Getter; import lombok.Setter; import org.checkerframework.checker.nullness.qual.NonNull; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/click/Click.java b/core/src/main/java/org/geysermc/geyser/inventory/click/Click.java index d7068920e..6897786c1 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/click/Click.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/click/Click.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.inventory.click; -import com.github.steveice10.mc.protocol.data.game.inventory.*; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.*; import lombok.AllArgsConstructor; @AllArgsConstructor diff --git a/core/src/main/java/org/geysermc/geyser/inventory/click/ClickPlan.java b/core/src/main/java/org/geysermc/geyser/inventory/click/ClickPlan.java index a118670af..53b02ef88 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/click/ClickPlan.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/click/ClickPlan.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.inventory.click; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerActionType; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; -import com.github.steveice10.mc.protocol.data.game.inventory.MoveToHotbarAction; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClickPacket; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerActionType; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.MoveToHotbarAction; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClickPacket; import it.unimi.dsi.fastutil.ints.*; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.inventory.Inventory; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserRecipe.java b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserRecipe.java index 641d5ad94..9d98e9fb3 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserRecipe.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserRecipe.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.inventory.recipe; /** - * A more compact version of {@link com.github.steveice10.mc.protocol.data.game.recipe.Recipe}. + * A more compact version of {@link org.geysermc.mcprotocollib.protocol.data.game.recipe.Recipe}. */ public interface GeyserRecipe { /** diff --git a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapedRecipe.java b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapedRecipe.java index d420170f4..ac9fa3ab4 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapedRecipe.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapedRecipe.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.inventory.recipe; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; -import com.github.steveice10.mc.protocol.data.game.recipe.data.ShapedRecipeData; import org.checkerframework.checker.nullness.qual.Nullable; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.Ingredient; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.data.ShapedRecipeData; public record GeyserShapedRecipe(int width, int height, Ingredient[] ingredients, @Nullable ItemStack result) implements GeyserRecipe { diff --git a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapelessRecipe.java b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapelessRecipe.java index e6eabea2d..388831d4c 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapelessRecipe.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserShapelessRecipe.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.inventory.recipe; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; -import com.github.steveice10.mc.protocol.data.game.recipe.data.ShapelessRecipeData; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.Ingredient; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.data.ShapelessRecipeData; import org.checkerframework.checker.nullness.qual.Nullable; public record GeyserShapelessRecipe(Ingredient[] ingredients, @Nullable ItemStack result) implements GeyserRecipe { diff --git a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserStonecutterData.java b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserStonecutterData.java index ce044e745..7bd21ecfa 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserStonecutterData.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserStonecutterData.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.inventory.recipe; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import org.checkerframework.checker.nullness.qual.Nullable; /** diff --git a/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java b/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java index 441f050a7..860ccfd89 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.inventory.recipe; -import com.github.steveice10.mc.protocol.data.game.RegistryEntry; +import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import net.kyori.adventure.text.Component; diff --git a/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java b/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java index 9bf001f42..d6324ba23 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.inventory.updater; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; diff --git a/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java b/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java index 214b9d78c..e884ecec5 100644 --- a/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.item; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.DyedItemColor; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DyedItemColor; public interface DyeableLeatherItem { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java index 773b850c0..fb9f35629 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.ArmorTrim; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; @@ -39,6 +36,9 @@ import org.geysermc.geyser.item.ArmorMaterial; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.ArmorTrim; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; public class ArmorItem extends Item { private final ArmorMaterial material; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java index 16d5fd482..f3c832a31 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; @@ -33,6 +32,7 @@ import org.geysermc.geyser.inventory.item.TippedArrowPotion; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; public class ArrowItem extends Item { public ArrowItem(String javaIdentifier, Builder builder) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java index 99f649e87..8895d45a8 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/AxolotlBucketItem.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; public class AxolotlBucketItem extends Item { public AxolotlBucketItem(String javaIdentifier, Builder builder) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index fe378d4c6..29a98e598 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.BannerPatternLayer; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.*; import it.unimi.dsi.fastutil.Pair; import org.checkerframework.checker.nullness.qual.NonNull; @@ -39,6 +36,9 @@ import org.geysermc.geyser.inventory.item.DyeColor; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import java.util.ArrayList; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java index 1f6ac6964..09718ba66 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; @Deprecated public class ChestItem extends BlockItem { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java b/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java index 10c574d5d..aa34f76ba 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java @@ -25,10 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.LodestoneTracker; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; @@ -36,6 +32,10 @@ import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.LodestoneTracker; public class CompassItem extends Item { public CompassItem(String javaIdentifier, Builder builder) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java index 5b92ba303..9a10c701c 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.ByteTag; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; @@ -39,6 +36,9 @@ import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.ItemTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java index ea194522b..2631bf9be 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import java.util.ArrayList; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java index 117e70b9a..e57470607 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.item.ArmorMaterial; @@ -33,6 +32,7 @@ import org.geysermc.geyser.item.DyeableLeatherItem; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; public class DyeableArmorItem extends ArmorItem implements DyeableLeatherItem { public DyeableArmorItem(String javaIdentifier, ArmorMaterial material, Builder builder) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java index cb6dd869b..881598648 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.item.DyeableLeatherItem; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; public class DyeableHorseArmorItem extends Item implements DyeableLeatherItem { public DyeableHorseArmorItem(String javaIdentifier, Builder builder) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java index 095537a09..952967475 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java @@ -25,14 +25,14 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.ItemEnchantments; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments; import java.util.ArrayList; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java index af0b84308..70a04b863 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FilledMapItem.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; public class FilledMapItem extends MapItem { public FilledMapItem(String javaIdentifier, Builder builder) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java index afb848e2d..e5656b494 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java @@ -25,10 +25,9 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.Fireworks; -import com.github.steveice10.opennbt.tag.builtin.*; +import com.github.steveice10.opennbt.tag.builtin.ByteTag; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.IntArrayTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -38,6 +37,9 @@ import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.util.MathUtils; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.Fireworks; import java.util.ArrayList; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java index 505296418..ab6b7f300 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.Fireworks; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; @@ -35,6 +32,9 @@ import org.cloudburstmc.nbt.NbtMap; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.Fireworks; public class FireworkStarItem extends Item { public FireworkStarItem(String javaIdentifier, Builder builder) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java index 743928482..32b1d5df5 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FishingRodItem.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; public class FishingRodItem extends Item { public FishingRodItem(String javaIdentifier, Builder builder) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java index 35b7a76fc..0ff78676c 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java @@ -25,17 +25,17 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.Holder; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.Instrument; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; +import org.geysermc.mcprotocollib.protocol.data.game.Holder; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.Instrument; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/Item.java b/core/src/main/java/org/geysermc/geyser/item/type/Item.java index 2779768db..64e2dcbc6 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/Item.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/Item.java @@ -25,11 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.Identifier; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.ItemEnchantments; import com.github.steveice10.opennbt.tag.builtin.*; import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.NonNull; @@ -48,6 +43,11 @@ import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.text.MessageTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.Identifier; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments; import java.util.ArrayList; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java b/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java index 72014e15e..f6492a169 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java @@ -25,13 +25,14 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.opennbt.tag.builtin.*; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.IntTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; public class MapItem extends Item { public MapItem(String javaIdentifier, Builder builder) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java index 82219d7d9..0cdbe70f1 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java @@ -26,13 +26,13 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.auth.data.GameProfile; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; public class PlayerHeadItem extends Item { public PlayerHeadItem(String javaIdentifier, Builder builder) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java index 63b9240c0..13d7ccd5e 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java @@ -25,10 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.PotionContents; import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; @@ -38,6 +34,10 @@ import org.geysermc.geyser.inventory.item.Potion; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.translator.item.CustomItemTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.PotionContents; public class PotionItem extends Item { public PotionItem(String javaIdentifier, Builder builder) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java index f495222f3..001fa74b6 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.item.components.ToolTier; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; public class ShieldItem extends Item { public ShieldItem(String javaIdentifier, Builder builder) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java index 267946442..4108d0fa0 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; @@ -38,6 +35,9 @@ import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.ItemTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import java.util.ArrayList; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java index 9074c2ec8..85291886e 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java @@ -25,14 +25,14 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.PotionContents; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.item.TippedArrowPotion; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.PotionContents; public class TippedArrowItem extends ArrowItem { public TippedArrowItem(String javaIdentifier, Builder builder) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java index f70e6b295..8c00cb049 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import net.kyori.adventure.text.Component; @@ -39,6 +37,8 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.text.MessageTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java index d925d2b8a..097a5e65b 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java @@ -25,10 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.Filterable; -import com.github.steveice10.mc.protocol.data.game.item.component.WritableBookContent; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; @@ -41,6 +37,10 @@ import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.text.MessageTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.Filterable; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.WritableBookContent; import java.util.ArrayList; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java index a6b5e73d4..a11c4f583 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java @@ -25,10 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.Filterable; -import com.github.steveice10.mc.protocol.data.game.item.component.WrittenBookContent; import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; @@ -37,6 +33,10 @@ import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.text.MessageTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.Filterable; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.WrittenBookContent; import java.util.ArrayList; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/level/BedrockMapIcon.java b/core/src/main/java/org/geysermc/geyser/level/BedrockMapIcon.java index 120e40f17..c55a74cd2 100644 --- a/core/src/main/java/org/geysermc/geyser/level/BedrockMapIcon.java +++ b/core/src/main/java/org/geysermc/geyser/level/BedrockMapIcon.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.level; -import com.github.steveice10.mc.protocol.data.game.level.map.MapIconType; import lombok.Getter; import org.checkerframework.checker.nullness.qual.Nullable; +import org.geysermc.mcprotocollib.protocol.data.game.level.map.MapIconType; public enum BedrockMapIcon { ICON_WHITE_ARROW(MapIconType.WHITE_ARROW, 0), diff --git a/core/src/main/java/org/geysermc/geyser/level/GeyserAdvancement.java b/core/src/main/java/org/geysermc/geyser/level/GeyserAdvancement.java index f51e7b2ab..7d48b90af 100644 --- a/core/src/main/java/org/geysermc/geyser/level/GeyserAdvancement.java +++ b/core/src/main/java/org/geysermc/geyser/level/GeyserAdvancement.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.level; -import com.github.steveice10.mc.protocol.data.game.advancement.Advancement; -import com.github.steveice10.mc.protocol.data.game.advancement.Advancement.DisplayData; -import com.github.steveice10.mc.protocol.data.game.advancement.Advancement.DisplayData.AdvancementType; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.session.cache.AdvancementsCache; import org.geysermc.geyser.text.ChatColor; +import org.geysermc.mcprotocollib.protocol.data.game.advancement.Advancement; +import org.geysermc.mcprotocollib.protocol.data.game.advancement.Advancement.DisplayData; +import org.geysermc.mcprotocollib.protocol.data.game.advancement.Advancement.DisplayData.AdvancementType; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java b/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java index 9a9eac2df..08611a5e1 100644 --- a/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java +++ b/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.level; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo; import it.unimi.dsi.fastutil.objects.Object2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -36,15 +33,14 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; -import org.geysermc.erosion.packet.backendbound.BackendboundBatchBlockEntityPacket; -import org.geysermc.erosion.packet.backendbound.BackendboundBatchBlockRequestPacket; -import org.geysermc.erosion.packet.backendbound.BackendboundBlockEntityPacket; -import org.geysermc.erosion.packet.backendbound.BackendboundBlockRequestPacket; -import org.geysermc.erosion.packet.backendbound.BackendboundPickBlockPacket; +import org.geysermc.erosion.packet.backendbound.*; import org.geysermc.erosion.util.BlockPositionIterator; import org.geysermc.erosion.util.LecternUtils; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.BlockEntityUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityInfo; import java.util.List; import java.util.concurrent.CompletableFuture; diff --git a/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java b/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java index 4babc3af0..27b2430bd 100644 --- a/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java +++ b/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.level; -import com.github.steveice10.mc.protocol.data.game.RegistryEntry; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/level/PaintingType.java b/core/src/main/java/org/geysermc/geyser/level/PaintingType.java index 5c0cbf643..643fd735d 100644 --- a/core/src/main/java/org/geysermc/geyser/level/PaintingType.java +++ b/core/src/main/java/org/geysermc/geyser/level/PaintingType.java @@ -75,7 +75,7 @@ public enum PaintingType { return KEBAB; } - public static PaintingType getByPaintingType(com.github.steveice10.mc.protocol.data.game.entity.type.PaintingType paintingType) { + public static PaintingType getByPaintingType(org.geysermc.mcprotocollib.protocol.data.game.entity.type.PaintingType paintingType) { return getByName(paintingType.name()); } } diff --git a/core/src/main/java/org/geysermc/geyser/level/WorldManager.java b/core/src/main/java/org/geysermc/geyser/level/WorldManager.java index aa0b43b80..a1b16a1d5 100644 --- a/core/src/main/java/org/geysermc/geyser/level/WorldManager.java +++ b/core/src/main/java/org/geysermc/geyser/level/WorldManager.java @@ -25,15 +25,15 @@ package org.geysermc.geyser.level; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo; -import com.github.steveice10.mc.protocol.data.game.setting.Difficulty; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3i; import org.geysermc.erosion.util.BlockPositionIterator; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityInfo; +import org.geysermc.mcprotocollib.protocol.data.game.setting.Difficulty; import java.util.List; import java.util.Locale; diff --git a/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockComponents.java b/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockComponents.java index dfcb548ee..979d3bc7d 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockComponents.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockComponents.java @@ -32,18 +32,9 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import lombok.Value; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; -import org.geysermc.geyser.api.block.custom.component.BoxComponent; -import org.geysermc.geyser.api.block.custom.component.CustomBlockComponents; -import org.geysermc.geyser.api.block.custom.component.GeometryComponent; -import org.geysermc.geyser.api.block.custom.component.MaterialInstance; -import org.geysermc.geyser.api.block.custom.component.PlacementConditions; -import org.geysermc.geyser.api.block.custom.component.TransformationComponent; +import org.geysermc.geyser.api.block.custom.component.*; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.Objects; +import java.util.*; @Value public class GeyserCustomBlockComponents implements CustomBlockComponents { diff --git a/core/src/main/java/org/geysermc/geyser/level/chunk/GeyserChunk.java b/core/src/main/java/org/geysermc/geyser/level/chunk/GeyserChunk.java index ca8c4db1d..c76c1994b 100644 --- a/core/src/main/java/org/geysermc/geyser/level/chunk/GeyserChunk.java +++ b/core/src/main/java/org/geysermc/geyser/level/chunk/GeyserChunk.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.level.chunk; -import com.github.steveice10.mc.protocol.data.game.chunk.DataPalette; +import org.geysermc.mcprotocollib.protocol.data.game.chunk.DataPalette; /** * Acts as a lightweight chunk class that doesn't store biomes, heightmaps or block entities. diff --git a/core/src/main/java/org/geysermc/geyser/level/physics/BoundingBox.java b/core/src/main/java/org/geysermc/geyser/level/physics/BoundingBox.java index 8343babd0..b1a93d8ee 100644 --- a/core/src/main/java/org/geysermc/geyser/level/physics/BoundingBox.java +++ b/core/src/main/java/org/geysermc/geyser/level/physics/BoundingBox.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.level.physics; -import org.cloudburstmc.math.vector.Vector3d; import lombok.AllArgsConstructor; import lombok.Data; import lombok.SneakyThrows; +import org.cloudburstmc.math.vector.Vector3d; @Data @AllArgsConstructor diff --git a/core/src/main/java/org/geysermc/geyser/level/physics/CollisionManager.java b/core/src/main/java/org/geysermc/geyser/level/physics/CollisionManager.java index 2c3da3c41..ce89689eb 100644 --- a/core/src/main/java/org/geysermc/geyser/level/physics/CollisionManager.java +++ b/core/src/main/java/org/geysermc/geyser/level/physics/CollisionManager.java @@ -25,6 +25,8 @@ package org.geysermc.geyser.level.physics; +import lombok.Getter; +import lombok.Setter; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.GenericMath; import org.cloudburstmc.math.vector.Vector3d; @@ -32,8 +34,6 @@ import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.MovePlayerPacket; -import lombok.Getter; -import lombok.Setter; import org.geysermc.erosion.util.BlockPositionIterator; import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.type.Entity; diff --git a/core/src/main/java/org/geysermc/geyser/level/physics/Direction.java b/core/src/main/java/org/geysermc/geyser/level/physics/Direction.java index 09ff89800..f14a46999 100644 --- a/core/src/main/java/org/geysermc/geyser/level/physics/Direction.java +++ b/core/src/main/java/org/geysermc/geyser/level/physics/Direction.java @@ -30,12 +30,12 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3i; public enum Direction { - DOWN(1, Vector3i.from(0, -1, 0), Axis.Y, com.github.steveice10.mc.protocol.data.game.entity.object.Direction.DOWN), - UP(0, Vector3i.UNIT_Y, Axis.Y, com.github.steveice10.mc.protocol.data.game.entity.object.Direction.UP), - NORTH(3, Vector3i.from(0, 0, -1), Axis.Z, com.github.steveice10.mc.protocol.data.game.entity.object.Direction.NORTH), - SOUTH(2, Vector3i.UNIT_Z, Axis.Z, com.github.steveice10.mc.protocol.data.game.entity.object.Direction.SOUTH), - WEST(5, Vector3i.from(-1, 0, 0), Axis.X, com.github.steveice10.mc.protocol.data.game.entity.object.Direction.WEST), - EAST(4, Vector3i.UNIT_X, Axis.X, com.github.steveice10.mc.protocol.data.game.entity.object.Direction.EAST); + DOWN(1, Vector3i.from(0, -1, 0), Axis.Y, org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction.DOWN), + UP(0, Vector3i.UNIT_Y, Axis.Y, org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction.UP), + NORTH(3, Vector3i.from(0, 0, -1), Axis.Z, org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction.NORTH), + SOUTH(2, Vector3i.UNIT_Z, Axis.Z, org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction.SOUTH), + WEST(5, Vector3i.from(-1, 0, 0), Axis.X, org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction.WEST), + EAST(4, Vector3i.UNIT_X, Axis.X, org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction.EAST); public static final Direction[] VALUES = values(); @@ -44,9 +44,9 @@ public enum Direction { private final Vector3i unitVector; @Getter private final Axis axis; - private final com.github.steveice10.mc.protocol.data.game.entity.object.Direction pistonValue; + private final org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction pistonValue; - Direction(int reversedId, Vector3i unitVector, Axis axis, com.github.steveice10.mc.protocol.data.game.entity.object.Direction pistonValue) { + Direction(int reversedId, Vector3i unitVector, Axis axis, org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction pistonValue) { this.reversedId = reversedId; this.unitVector = unitVector; this.axis = axis; @@ -65,7 +65,7 @@ public enum Direction { return axis == Axis.X || axis == Axis.Z; } - public static @NonNull Direction fromPistonValue(com.github.steveice10.mc.protocol.data.game.entity.object.Direction pistonValue) { + public static @NonNull Direction fromPistonValue(org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction pistonValue) { for (Direction direction : VALUES) { if (direction.pistonValue == pistonValue) { return direction; diff --git a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java index b5fc4440c..cf80e8c6e 100644 --- a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java +++ b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.network; -import com.github.steveice10.mc.protocol.codec.MinecraftCodec; -import com.github.steveice10.mc.protocol.codec.PacketCodec; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec; import org.cloudburstmc.protocol.bedrock.codec.v622.Bedrock_v622; @@ -36,6 +34,8 @@ import org.cloudburstmc.protocol.bedrock.codec.v662.Bedrock_v662; import org.cloudburstmc.protocol.bedrock.codec.v671.Bedrock_v671; import org.cloudburstmc.protocol.bedrock.netty.codec.packet.BedrockPacketCodec; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodec; +import org.geysermc.mcprotocollib.protocol.codec.PacketCodec; import java.util.ArrayList; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java b/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java index 121c70f90..19b0b423f 100644 --- a/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java +++ b/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java @@ -25,19 +25,19 @@ package org.geysermc.geyser.network.netty; -import com.github.steveice10.mc.protocol.codec.MinecraftCodecHelper; -import com.github.steveice10.packetlib.BuiltinFlags; -import com.github.steveice10.packetlib.codec.PacketCodecHelper; -import com.github.steveice10.packetlib.packet.PacketProtocol; -import com.github.steveice10.packetlib.tcp.TcpPacketCodec; -import com.github.steveice10.packetlib.tcp.TcpPacketSizer; -import com.github.steveice10.packetlib.tcp.TcpSession; import io.netty.bootstrap.Bootstrap; import io.netty.buffer.ByteBufAllocator; import io.netty.channel.*; import io.netty.channel.unix.PreferredDirectByteBufAllocator; import io.netty.handler.codec.haproxy.*; import org.checkerframework.checker.nullness.qual.NonNull; +import org.geysermc.mcprotocollib.network.BuiltinFlags; +import org.geysermc.mcprotocollib.network.codec.PacketCodecHelper; +import org.geysermc.mcprotocollib.network.packet.PacketProtocol; +import org.geysermc.mcprotocollib.network.tcp.TcpPacketCodec; +import org.geysermc.mcprotocollib.network.tcp.TcpPacketSizer; +import org.geysermc.mcprotocollib.network.tcp.TcpSession; +import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodecHelper; import java.net.Inet4Address; import java.net.InetSocketAddress; diff --git a/core/src/main/java/org/geysermc/geyser/pack/SkullResourcePackManager.java b/core/src/main/java/org/geysermc/geyser/pack/SkullResourcePackManager.java index f6c5140d8..f0faa4244 100644 --- a/core/src/main/java/org/geysermc/geyser/pack/SkullResourcePackManager.java +++ b/core/src/main/java/org/geysermc/geyser/pack/SkullResourcePackManager.java @@ -48,7 +48,9 @@ import java.nio.file.StandardOpenOption; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.List; -import java.util.*; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; import java.util.function.UnaryOperator; import java.util.stream.Stream; import java.util.zip.ZipEntry; diff --git a/core/src/main/java/org/geysermc/geyser/ping/GeyserLegacyPingPassthrough.java b/core/src/main/java/org/geysermc/geyser/ping/GeyserLegacyPingPassthrough.java index 6bbca11ca..320334ee5 100644 --- a/core/src/main/java/org/geysermc/geyser/ping/GeyserLegacyPingPassthrough.java +++ b/core/src/main/java/org/geysermc/geyser/ping/GeyserLegacyPingPassthrough.java @@ -27,11 +27,11 @@ package org.geysermc.geyser.ping; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonMappingException; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.cloudburstmc.nbt.util.VarInts; import io.netty.handler.codec.haproxy.HAProxyCommand; import io.netty.handler.codec.haproxy.HAProxyProxiedProtocol; import io.netty.util.NetUtil; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.cloudburstmc.nbt.util.VarInts; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.network.GameProtocol; diff --git a/core/src/main/java/org/geysermc/geyser/ping/IGeyserPingPassthrough.java b/core/src/main/java/org/geysermc/geyser/ping/IGeyserPingPassthrough.java index 318035e32..69ac974cc 100644 --- a/core/src/main/java/org/geysermc/geyser/ping/IGeyserPingPassthrough.java +++ b/core/src/main/java/org/geysermc/geyser/ping/IGeyserPingPassthrough.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.ping; import org.checkerframework.checker.nullness.qual.Nullable; + import java.net.InetSocketAddress; /** diff --git a/core/src/main/java/org/geysermc/geyser/registry/PacketTranslatorRegistry.java b/core/src/main/java/org/geysermc/geyser/registry/PacketTranslatorRegistry.java index e37f8aa64..9a5b43816 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/PacketTranslatorRegistry.java +++ b/core/src/main/java/org/geysermc/geyser/registry/PacketTranslatorRegistry.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.registry; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundDelimiterPacket; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundTabListPacket; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundChunkBatchStartPacket; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundLightUpdatePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundDelimiterPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundTabListPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundChunkBatchStartPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLightUpdatePacket; import io.netty.channel.EventLoop; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.registry.loader.RegistryLoaders; diff --git a/core/src/main/java/org/geysermc/geyser/registry/Registries.java b/core/src/main/java/org/geysermc/geyser/registry/Registries.java index 9b5ed8ae6..f19898016 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/Registries.java +++ b/core/src/main/java/org/geysermc/geyser/registry/Registries.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.registry; -import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; -import com.github.steveice10.mc.protocol.data.game.level.event.LevelEvent; -import com.github.steveice10.mc.protocol.data.game.level.particle.ParticleType; -import com.github.steveice10.mc.protocol.data.game.recipe.RecipeType; -import com.github.steveice10.packetlib.packet.Packet; +import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.event.LevelEvent; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ParticleType; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.RecipeType; +import org.geysermc.mcprotocollib.network.packet.Packet; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2IntMap; diff --git a/core/src/main/java/org/geysermc/geyser/registry/loader/BlockEntityRegistryLoader.java b/core/src/main/java/org/geysermc/geyser/registry/loader/BlockEntityRegistryLoader.java index f47273827..a813ee458 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/loader/BlockEntityRegistryLoader.java +++ b/core/src/main/java/org/geysermc/geyser/registry/loader/BlockEntityRegistryLoader.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.registry.loader; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import it.unimi.dsi.fastutil.objects.Object2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import org.geysermc.geyser.translator.level.block.entity.BlockEntity; diff --git a/core/src/main/java/org/geysermc/geyser/registry/loader/ParticleTypesRegistryLoader.java b/core/src/main/java/org/geysermc/geyser/registry/loader/ParticleTypesRegistryLoader.java index 677806b3f..a09d6d6d3 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/loader/ParticleTypesRegistryLoader.java +++ b/core/src/main/java/org/geysermc/geyser/registry/loader/ParticleTypesRegistryLoader.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.registry.loader; import com.fasterxml.jackson.databind.JsonNode; -import com.github.steveice10.mc.protocol.data.game.level.particle.ParticleType; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ParticleType; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; import org.cloudburstmc.protocol.bedrock.data.LevelEventType; diff --git a/core/src/main/java/org/geysermc/geyser/registry/loader/SoundEventsRegistryLoader.java b/core/src/main/java/org/geysermc/geyser/registry/loader/SoundEventsRegistryLoader.java index c0600b878..4e3fbe40a 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/loader/SoundEventsRegistryLoader.java +++ b/core/src/main/java/org/geysermc/geyser/registry/loader/SoundEventsRegistryLoader.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.registry.loader; import com.fasterxml.jackson.databind.JsonNode; -import com.github.steveice10.mc.protocol.data.game.level.event.LevelEvent; +import org.geysermc.mcprotocollib.protocol.data.game.level.event.LevelEvent; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import org.cloudburstmc.protocol.bedrock.data.LevelEventType; import org.geysermc.geyser.GeyserImpl; @@ -58,20 +58,20 @@ public class SoundEventsRegistryLoader extends EffectRegistryLoader { - javaEffect = com.github.steveice10.mc.protocol.data.game.level.event.LevelEventType.valueOf(entry.getKey()); + javaEffect = org.geysermc.mcprotocollib.protocol.data.game.level.event.LevelEventType.valueOf(entry.getKey()); LevelEventType levelEventType = org.cloudburstmc.protocol.bedrock.data.LevelEvent.valueOf(node.get("name").asText()); int data = node.has("data") ? node.get("data").intValue() : 0; transformer = new SoundLevelEventTranslator(levelEventType, data); } case "soundEvent" -> { - javaEffect = com.github.steveice10.mc.protocol.data.game.level.event.LevelEventType.valueOf(entry.getKey()); + javaEffect = org.geysermc.mcprotocollib.protocol.data.game.level.event.LevelEventType.valueOf(entry.getKey()); org.cloudburstmc.protocol.bedrock.data.SoundEvent soundEvent = org.cloudburstmc.protocol.bedrock.data.SoundEvent.valueOf(node.get("name").asText()); String identifier = node.has("identifier") ? node.get("identifier").asText() : ""; int extraData = node.has("extraData") ? node.get("extraData").intValue() : -1; transformer = new SoundEventEventTranslator(soundEvent, identifier, extraData); } case "playSound" -> { - javaEffect = com.github.steveice10.mc.protocol.data.game.level.event.LevelEventType.valueOf(entry.getKey()); + javaEffect = org.geysermc.mcprotocollib.protocol.data.game.level.event.LevelEventType.valueOf(entry.getKey()); String name = node.get("name").asText(); float volume = node.has("volume") ? node.get("volume").floatValue() : 1.0f; boolean pitchSub = node.has("pitch_sub") && node.get("pitch_sub").booleanValue(); diff --git a/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java b/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java index e8901a550..d32d5bc09 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java +++ b/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java @@ -27,7 +27,7 @@ package org.geysermc.geyser.registry.mappings.versions; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; -import com.github.steveice10.mc.protocol.data.game.Identifier; +import org.geysermc.mcprotocollib.protocol.data.game.Identifier; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import org.checkerframework.checker.nullness.qual.Nullable; diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/PacketRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/PacketRegistryPopulator.java index d055f7b28..9be00732c 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/PacketRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/PacketRegistryPopulator.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.registry.populator; -import com.github.steveice10.packetlib.packet.Packet; import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.FileUtils; +import org.geysermc.mcprotocollib.network.packet.Packet; public class PacketRegistryPopulator { diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java index 34e855212..928ab8df9 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java @@ -26,9 +26,9 @@ package org.geysermc.geyser.registry.populator; import com.fasterxml.jackson.databind.JsonNode; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; -import com.github.steveice10.mc.protocol.data.game.recipe.RecipeType; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.Ingredient; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.RecipeType; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectArrayList; diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java b/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java index 199481cbc..f3cfa3f0f 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java +++ b/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.registry.type; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2ObjectMap; import lombok.Builder; diff --git a/core/src/main/java/org/geysermc/geyser/scoreboard/Objective.java b/core/src/main/java/org/geysermc/geyser/scoreboard/Objective.java index c00c69660..6c1389ef5 100644 --- a/core/src/main/java/org/geysermc/geyser/scoreboard/Objective.java +++ b/core/src/main/java/org/geysermc/geyser/scoreboard/Objective.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.scoreboard; -import com.github.steveice10.mc.protocol.data.game.chat.numbers.NumberFormat; -import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition; -import com.github.steveice10.mc.protocol.data.game.scoreboard.TeamColor; import lombok.Getter; import lombok.Setter; import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.Nullable; +import org.geysermc.mcprotocollib.protocol.data.game.chat.numbers.NumberFormat; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.ScoreboardPosition; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.TeamColor; import java.util.Map; import java.util.Objects; diff --git a/core/src/main/java/org/geysermc/geyser/scoreboard/Score.java b/core/src/main/java/org/geysermc/geyser/scoreboard/Score.java index ec17818c4..9a26b7f77 100644 --- a/core/src/main/java/org/geysermc/geyser/scoreboard/Score.java +++ b/core/src/main/java/org/geysermc/geyser/scoreboard/Score.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.scoreboard; -import com.github.steveice10.mc.protocol.data.game.chat.numbers.FixedFormat; -import com.github.steveice10.mc.protocol.data.game.chat.numbers.NumberFormat; +import org.geysermc.mcprotocollib.protocol.data.game.chat.numbers.FixedFormat; +import org.geysermc.mcprotocollib.protocol.data.game.chat.numbers.NumberFormat; import net.kyori.adventure.text.Component; import org.cloudburstmc.protocol.bedrock.data.ScoreInfo; import lombok.Getter; diff --git a/core/src/main/java/org/geysermc/geyser/scoreboard/Scoreboard.java b/core/src/main/java/org/geysermc/geyser/scoreboard/Scoreboard.java index dfd74a79e..acce86f4d 100644 --- a/core/src/main/java/org/geysermc/geyser/scoreboard/Scoreboard.java +++ b/core/src/main/java/org/geysermc/geyser/scoreboard/Scoreboard.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.scoreboard; -import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import lombok.Getter; import org.checkerframework.checker.nullness.qual.Nullable; @@ -40,6 +39,7 @@ import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.player.PlayerEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.GeyserLocale; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.ScoreboardPosition; import org.jetbrains.annotations.Contract; import java.util.*; @@ -48,10 +48,7 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.function.Function; import java.util.stream.Collectors; -import static org.geysermc.geyser.scoreboard.UpdateType.ADD; -import static org.geysermc.geyser.scoreboard.UpdateType.NOTHING; -import static org.geysermc.geyser.scoreboard.UpdateType.REMOVE; -import static org.geysermc.geyser.scoreboard.UpdateType.UPDATE; +import static org.geysermc.geyser.scoreboard.UpdateType.*; public final class Scoreboard { private static final boolean SHOW_SCOREBOARD_LOGS = Boolean.parseBoolean(System.getProperty("Geyser.ShowScoreboardLogs", "true")); diff --git a/core/src/main/java/org/geysermc/geyser/scoreboard/Team.java b/core/src/main/java/org/geysermc/geyser/scoreboard/Team.java index 9164fec1d..cdf2e247e 100644 --- a/core/src/main/java/org/geysermc/geyser/scoreboard/Team.java +++ b/core/src/main/java/org/geysermc/geyser/scoreboard/Team.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.scoreboard; -import com.github.steveice10.mc.protocol.data.game.scoreboard.NameTagVisibility; -import com.github.steveice10.mc.protocol.data.game.scoreboard.TeamColor; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.NameTagVisibility; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.TeamColor; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import lombok.AccessLevel; import lombok.Getter; diff --git a/core/src/main/java/org/geysermc/geyser/session/DownstreamSession.java b/core/src/main/java/org/geysermc/geyser/session/DownstreamSession.java index 40b685783..8845cdbea 100644 --- a/core/src/main/java/org/geysermc/geyser/session/DownstreamSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/DownstreamSession.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.session; -import com.github.steveice10.mc.protocol.codec.MinecraftCodecHelper; -import com.github.steveice10.packetlib.packet.Packet; -import com.github.steveice10.packetlib.tcp.TcpSession; import lombok.Getter; import lombok.RequiredArgsConstructor; import org.checkerframework.checker.nullness.qual.NonNull; +import org.geysermc.mcprotocollib.network.packet.Packet; +import org.geysermc.mcprotocollib.network.tcp.TcpSession; +import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodecHelper; @Getter @RequiredArgsConstructor diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 9ae1f6f49..82717050f 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -28,35 +28,35 @@ package org.geysermc.geyser.session; import com.github.steveice10.mc.auth.data.GameProfile; import com.github.steveice10.mc.auth.exception.request.RequestException; import com.github.steveice10.mc.auth.service.MsaAuthenticationService; -import com.github.steveice10.mc.protocol.MinecraftConstants; -import com.github.steveice10.mc.protocol.MinecraftProtocol; -import com.github.steveice10.mc.protocol.data.ProtocolState; -import com.github.steveice10.mc.protocol.data.UnexpectedEncryptionException; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; -import com.github.steveice10.mc.protocol.data.game.entity.object.Direction; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; -import com.github.steveice10.mc.protocol.data.game.entity.player.HandPreference; -import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction; -import com.github.steveice10.mc.protocol.data.game.setting.ChatVisibility; -import com.github.steveice10.mc.protocol.data.game.setting.SkinPart; -import com.github.steveice10.mc.protocol.data.game.statistic.CustomStatistic; -import com.github.steveice10.mc.protocol.data.game.statistic.Statistic; -import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundClientInformationPacket; -import com.github.steveice10.mc.protocol.packet.handshake.serverbound.ClientIntentionPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatCommandSignedPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerAbilitiesPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerActionPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundUseItemPacket; -import com.github.steveice10.mc.protocol.packet.login.serverbound.ServerboundCustomQueryAnswerPacket; -import com.github.steveice10.packetlib.BuiltinFlags; -import com.github.steveice10.packetlib.Session; -import com.github.steveice10.packetlib.event.session.*; -import com.github.steveice10.packetlib.packet.Packet; -import com.github.steveice10.packetlib.tcp.TcpClientSession; -import com.github.steveice10.packetlib.tcp.TcpSession; +import org.geysermc.mcprotocollib.protocol.MinecraftConstants; +import org.geysermc.mcprotocollib.protocol.MinecraftProtocol; +import org.geysermc.mcprotocollib.protocol.data.ProtocolState; +import org.geysermc.mcprotocollib.protocol.data.UnexpectedEncryptionException; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.HandPreference; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerAction; +import org.geysermc.mcprotocollib.protocol.data.game.setting.ChatVisibility; +import org.geysermc.mcprotocollib.protocol.data.game.setting.SkinPart; +import org.geysermc.mcprotocollib.protocol.data.game.statistic.CustomStatistic; +import org.geysermc.mcprotocollib.protocol.data.game.statistic.Statistic; +import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundClientInformationPacket; +import org.geysermc.mcprotocollib.protocol.packet.handshake.serverbound.ClientIntentionPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundChatCommandSignedPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundChatPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundPlayerAbilitiesPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundPlayerActionPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundUseItemPacket; +import org.geysermc.mcprotocollib.protocol.packet.login.serverbound.ServerboundCustomQueryAnswerPacket; +import org.geysermc.mcprotocollib.network.BuiltinFlags; +import org.geysermc.mcprotocollib.network.Session; +import org.geysermc.mcprotocollib.network.event.session.*; +import org.geysermc.mcprotocollib.network.packet.Packet; +import org.geysermc.mcprotocollib.network.tcp.TcpClientSession; +import org.geysermc.mcprotocollib.network.tcp.TcpSession; import io.netty.channel.Channel; import io.netty.channel.EventLoop; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java index 3bc661c16..da3c83ed4 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.session.cache; -import com.github.steveice10.mc.protocol.data.game.advancement.Advancement; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSeenAdvancementsPacket; +import org.geysermc.mcprotocollib.protocol.data.game.advancement.Advancement; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSeenAdvancementsPacket; import lombok.Getter; import lombok.Setter; import org.geysermc.cumulus.form.SimpleForm; diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/BookEditCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/BookEditCache.java index 6a9025bc0..90f22afd6 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/BookEditCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/BookEditCache.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.session.cache; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundEditBookPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundEditBookPacket; import lombok.Setter; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/ChunkCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/ChunkCache.java index d2c1415a3..e3a9cba89 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/ChunkCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/ChunkCache.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.session.cache; -import com.github.steveice10.mc.protocol.data.game.chunk.DataPalette; +import org.geysermc.mcprotocollib.protocol.data.game.chunk.DataPalette; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import lombok.Getter; diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/EntityEffectCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/EntityEffectCache.java index a7693e516..a9679f6ef 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/EntityEffectCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/EntityEffectCache.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.session.cache; -import com.github.steveice10.mc.protocol.data.game.entity.Effect; +import org.geysermc.mcprotocollib.protocol.data.game.entity.Effect; import lombok.Getter; import java.util.EnumSet; diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java index eced0e50b..f9515dbb4 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.session.cache; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.GlobalPos; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.LodestoneTracker; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.GlobalPos; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.LodestoneTracker; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import org.checkerframework.checker.nullness.qual.Nullable; diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java index d6d5ae292..7ad2afec7 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.session.cache; -import com.github.steveice10.mc.protocol.data.game.RegistryEntry; -import com.github.steveice10.mc.protocol.packet.configuration.clientbound.ClientboundRegistryDataPacket; import it.unimi.dsi.fastutil.ints.Int2IntMap; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; @@ -44,6 +42,8 @@ import org.geysermc.geyser.level.JavaDimension; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.TextDecoration; import org.geysermc.geyser.translator.level.BiomeTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; +import org.geysermc.mcprotocollib.protocol.packet.configuration.clientbound.ClientboundRegistryDataPacket; import java.util.HashMap; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java index b2f43f180..38ac32214 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.session.cache; -import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundUpdateTagsPacket; +import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundUpdateTagsPacket; import it.unimi.dsi.fastutil.ints.IntList; import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.inventory.GeyserItemStack; diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/TeleportCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/TeleportCache.java index 8d243d3fa..80139a988 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/TeleportCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/TeleportCache.java @@ -33,7 +33,7 @@ import lombok.RequiredArgsConstructor; * Represents a teleport ID and corresponding coordinates that need to be confirmed.
* * The vanilla Java client, after getting a - * {@link com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.player.ClientboundPlayerPositionPacket}, + * {@link org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.player.ClientboundPlayerPositionPacket}, * adjusts the player's positions and immediately sends a teleport back. However, we want to acknowledge that the * Bedrock player actually moves close to that point, so we store the teleport until we get a movement packet from * Bedrock that the teleport was successful. diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/WorldCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/WorldCache.java index 6be57670c..c84126608 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/WorldCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/WorldCache.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.session.cache; -import com.github.steveice10.mc.protocol.data.game.setting.Difficulty; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntMaps; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; @@ -37,6 +36,7 @@ import org.geysermc.geyser.scoreboard.Scoreboard; import org.geysermc.geyser.scoreboard.ScoreboardUpdater.ScoreboardSession; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.ChunkUtils; +import org.geysermc.mcprotocollib.protocol.data.game.setting.Difficulty; import java.util.Iterator; diff --git a/core/src/main/java/org/geysermc/geyser/skin/FakeHeadProvider.java b/core/src/main/java/org/geysermc/geyser/skin/FakeHeadProvider.java index 2d6345bfa..d2a45b614 100644 --- a/core/src/main/java/org/geysermc/geyser/skin/FakeHeadProvider.java +++ b/core/src/main/java/org/geysermc/geyser/skin/FakeHeadProvider.java @@ -30,8 +30,6 @@ import com.github.steveice10.mc.auth.data.GameProfile.Texture; import com.github.steveice10.mc.auth.data.GameProfile.TextureModel; import com.github.steveice10.mc.auth.data.GameProfile.TextureType; import com.github.steveice10.mc.auth.exception.property.PropertyException; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; @@ -45,6 +43,8 @@ import org.geysermc.geyser.entity.type.player.PlayerEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.skin.SkinManager.GameProfileData; import org.geysermc.geyser.text.GeyserLocale; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import java.awt.*; import java.awt.image.BufferedImage; diff --git a/core/src/main/java/org/geysermc/geyser/text/ChatTypeEntry.java b/core/src/main/java/org/geysermc/geyser/text/ChatTypeEntry.java index 500f44d0b..f139b0bba 100644 --- a/core/src/main/java/org/geysermc/geyser/text/ChatTypeEntry.java +++ b/core/src/main/java/org/geysermc/geyser/text/ChatTypeEntry.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.text; -import com.github.steveice10.mc.protocol.data.game.chat.BuiltinChatType; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.protocol.bedrock.packet.TextPacket; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import org.geysermc.mcprotocollib.protocol.data.game.chat.BuiltinChatType; public record ChatTypeEntry(TextPacket.@NonNull Type bedrockChatType, @Nullable TextDecoration textDecoration) { private static final ChatTypeEntry CHAT = new ChatTypeEntry(TextPacket.Type.CHAT, null); diff --git a/core/src/main/java/org/geysermc/geyser/text/MinecraftLocale.java b/core/src/main/java/org/geysermc/geyser/text/MinecraftLocale.java index 692a05110..94d8b254f 100644 --- a/core/src/main/java/org/geysermc/geyser/text/MinecraftLocale.java +++ b/core/src/main/java/org/geysermc/geyser/text/MinecraftLocale.java @@ -32,7 +32,9 @@ import org.geysermc.geyser.util.AssetUtils; import org.geysermc.geyser.util.FileUtils; import org.geysermc.geyser.util.WebUtils; -import java.io.*; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; diff --git a/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java b/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java index bad55a5ca..a85153d13 100644 --- a/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java +++ b/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.text; -import com.github.steveice10.mc.protocol.data.game.RegistryEntry; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.Style; +import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; import java.util.EnumSet; import java.util.Locale; diff --git a/core/src/main/java/org/geysermc/geyser/translator/collision/BlockCollision.java b/core/src/main/java/org/geysermc/geyser/translator/collision/BlockCollision.java index e82b994c7..a2615deb1 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/collision/BlockCollision.java +++ b/core/src/main/java/org/geysermc/geyser/translator/collision/BlockCollision.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.translator.collision; -import org.cloudburstmc.math.vector.Vector3d; -import org.cloudburstmc.math.vector.Vector3i; import lombok.EqualsAndHashCode; import lombok.Getter; +import org.cloudburstmc.math.vector.Vector3d; +import org.cloudburstmc.math.vector.Vector3i; import org.geysermc.geyser.level.physics.Axis; import org.geysermc.geyser.level.physics.BoundingBox; import org.geysermc.geyser.level.physics.CollisionManager; diff --git a/core/src/main/java/org/geysermc/geyser/translator/entity/EntityMetadataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/entity/EntityMetadataTranslator.java index dd53e4c5b..194194501 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/entity/EntityMetadataTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/entity/EntityMetadataTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.entity; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.MetadataType; import org.geysermc.geyser.entity.type.Entity; import java.util.function.BiConsumer; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/AnvilInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/AnvilInventoryTranslator.java index 31a0b7b11..2da51a0eb 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/AnvilInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/AnvilInventoryTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequest; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData; @@ -39,6 +38,7 @@ import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.PlayerInventory; import org.geysermc.geyser.inventory.updater.AnvilInventoryUpdater; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import java.util.Objects; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/BaseInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/BaseInventoryTranslator.java index 0f8fa4ca7..f70bad9ea 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/BaseInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/BaseInventoryTranslator.java @@ -25,15 +25,11 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData; -import org.geysermc.geyser.inventory.BedrockContainerSlot; -import org.geysermc.geyser.inventory.Container; -import org.geysermc.geyser.inventory.Inventory; -import org.geysermc.geyser.inventory.PlayerInventory; -import org.geysermc.geyser.inventory.SlotType; +import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; public abstract class BaseInventoryTranslator extends InventoryTranslator { public BaseInventoryTranslator(int size) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/BeaconInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/BeaconInventoryTranslator.java index 00323ce83..9aeeff007 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/BeaconInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/BeaconInventoryTranslator.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetBeaconPacket; import it.unimi.dsi.fastutil.ints.IntSets; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; @@ -47,6 +45,8 @@ import org.geysermc.geyser.inventory.holder.BlockInventoryHolder; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InventoryUtils; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSetBeaconPacket; import java.util.OptionalInt; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/CartographyInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/CartographyInventoryTranslator.java index 95f227ed7..a115bd953 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/CartographyInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/CartographyInventoryTranslator.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData; import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; public class CartographyInventoryTranslator extends AbstractBlockInventoryTranslator { public CartographyInventoryTranslator() { diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/CrafterInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/CrafterInventoryTranslator.java index 97398a207..2a2f5beb5 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/CrafterInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/CrafterInventoryTranslator.java @@ -25,19 +25,15 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData; -import org.geysermc.geyser.inventory.BedrockContainerSlot; -import org.geysermc.geyser.inventory.CrafterContainer; -import org.geysermc.geyser.inventory.Inventory; -import org.geysermc.geyser.inventory.PlayerInventory; -import org.geysermc.geyser.inventory.SlotType; +import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.updater.CrafterInventoryUpdater; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.BlockEntityUtils; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; /** * Translates the Crafter. Most important thing to know about this class is that diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/EnchantingInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/EnchantingInventoryTranslator.java index 0085a7550..8fee2a391 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/EnchantingInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/EnchantingInventoryTranslator.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; import it.unimi.dsi.fastutil.ints.IntSets; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.EnchantOptionData; @@ -41,6 +39,8 @@ import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.item.Enchantment; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; import java.util.Arrays; import java.util.Locale; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/Generic3X3InventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/Generic3X3InventoryTranslator.java index 369a80282..2a80161c0 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/Generic3X3InventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/Generic3X3InventoryTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.packet.ContainerOpenPacket; import org.geysermc.geyser.inventory.BedrockContainerSlot; @@ -34,6 +33,7 @@ import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.PlayerInventory; import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; /** * Droppers and dispensers diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java index 4a3e31b30..0914aeba8 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java @@ -25,11 +25,6 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; import it.unimi.dsi.fastutil.ints.*; import lombok.AllArgsConstructor; import org.checkerframework.checker.nullness.qual.Nullable; @@ -59,6 +54,11 @@ import org.geysermc.geyser.translator.inventory.furnace.FurnaceInventoryTranslat import org.geysermc.geyser.translator.inventory.furnace.SmokerInventoryTranslator; import org.geysermc.geyser.util.InventoryUtils; import org.geysermc.geyser.util.ItemUtils; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.Ingredient; import java.util.*; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java index 7dff2647c..f3bbc9b87 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java @@ -25,12 +25,6 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.WritableBookContent; -import com.github.steveice10.mc.protocol.data.game.item.component.WrittenBookContent; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -38,16 +32,18 @@ import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.erosion.util.LecternUtils; import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.inventory.Container; -import org.geysermc.geyser.inventory.GeyserItemStack; -import org.geysermc.geyser.inventory.Inventory; -import org.geysermc.geyser.inventory.LecternContainer; -import org.geysermc.geyser.inventory.PlayerInventory; +import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater; import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.BlockEntityUtils; import org.geysermc.geyser.util.InventoryUtils; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.WritableBookContent; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.WrittenBookContent; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; import java.util.Collections; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java index 636a7982a..e8571c8fb 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java @@ -25,10 +25,6 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.item.component.BannerPatternLayer; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import org.cloudburstmc.nbt.NbtMap; @@ -50,6 +46,10 @@ import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; import org.geysermc.geyser.item.type.BannerItem; import org.geysermc.geyser.item.type.DyeItem; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; import java.util.ArrayList; import java.util.HashMap; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/MerchantInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/MerchantInventoryTranslator.java index c4f958ba1..7a7646503 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/MerchantInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/MerchantInventoryTranslator.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSelectTradePacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData; @@ -44,6 +42,8 @@ import org.geysermc.geyser.inventory.updater.InventoryUpdater; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InventoryUtils; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSelectTradePacket; import java.util.concurrent.TimeUnit; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/OldSmithingTableTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/OldSmithingTableTranslator.java index 5f08f1b8a..201c900d6 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/OldSmithingTableTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/OldSmithingTableTranslator.java @@ -31,11 +31,7 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequest; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData; -import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.DropAction; -import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.ItemStackRequestAction; -import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.PlaceAction; -import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.SwapAction; -import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.TakeAction; +import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.*; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.response.ItemStackResponse; import org.cloudburstmc.protocol.bedrock.packet.InventorySlotPacket; import org.geysermc.geyser.inventory.BedrockContainerSlot; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java index 36d10aa54..142651eb4 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java @@ -25,10 +25,6 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetCreativeModeSlotPacket; import it.unimi.dsi.fastutil.ints.IntIterator; import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import it.unimi.dsi.fastutil.ints.IntSet; @@ -37,12 +33,7 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequest; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData; -import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.CraftCreativeAction; -import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.DestroyAction; -import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.DropAction; -import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.ItemStackRequestAction; -import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.SwapAction; -import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.TransferItemStackRequestAction; +import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.*; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.response.ItemStackResponse; import org.cloudburstmc.protocol.bedrock.packet.ContainerClosePacket; import org.cloudburstmc.protocol.bedrock.packet.ContainerOpenPacket; @@ -55,6 +46,10 @@ import org.geysermc.geyser.skin.FakeHeadProvider; import org.geysermc.geyser.text.GeyserLocale; import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.util.InventoryUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSetCreativeModeSlotPacket; import java.util.Arrays; import java.util.Collections; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java index b8bb2bee4..543f519c9 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -39,6 +38,7 @@ import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; public class ShulkerInventoryTranslator extends AbstractBlockInventoryTranslator { public ShulkerInventoryTranslator() { diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java index d3d15680a..54f2f447b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.translator.inventory; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequest; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData; @@ -39,6 +36,9 @@ import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.recipe.GeyserStonecutterData; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; public class StonecutterInventoryTranslator extends AbstractBlockInventoryTranslator { public StonecutterInventoryTranslator() { diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java index 8a541fb9b..91eee3895 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.item; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import it.unimi.dsi.fastutil.Pair; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index a8e9e1c52..24362f800 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -29,13 +29,13 @@ import com.github.steveice10.mc.auth.data.GameProfile; import com.github.steveice10.mc.auth.data.GameProfile.Texture; import com.github.steveice10.mc.auth.data.GameProfile.TextureType; import com.github.steveice10.mc.auth.exception.property.PropertyException; -import com.github.steveice10.mc.protocol.data.game.Identifier; -import com.github.steveice10.mc.protocol.data.game.entity.attribute.ModifierOperation; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.AdventureModePredicate; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.ItemAttributeModifiers; +import org.geysermc.mcprotocollib.protocol.data.game.Identifier; +import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.ModifierOperation; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.AdventureModePredicate; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemAttributeModifiers; import com.github.steveice10.opennbt.tag.builtin.*; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java index 450c786f2..d70f53e2c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.translator.level; -import com.github.steveice10.mc.protocol.data.game.RegistryEntry; -import com.github.steveice10.mc.protocol.data.game.chunk.BitStorage; -import com.github.steveice10.mc.protocol.data.game.chunk.DataPalette; -import com.github.steveice10.mc.protocol.data.game.chunk.palette.GlobalPalette; -import com.github.steveice10.mc.protocol.data.game.chunk.palette.Palette; -import com.github.steveice10.mc.protocol.data.game.chunk.palette.SingletonPalette; +import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; +import org.geysermc.mcprotocollib.protocol.data.game.chunk.BitStorage; +import org.geysermc.mcprotocollib.protocol.data.game.chunk.DataPalette; +import org.geysermc.mcprotocollib.protocol.data.game.chunk.palette.GlobalPalette; +import org.geysermc.mcprotocollib.protocol.data.game.chunk.palette.Palette; +import org.geysermc.mcprotocollib.protocol.data.game.chunk.palette.SingletonPalette; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.ints.IntLists; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java index e0e0130c5..bc08dd93b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.Tag; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BeaconBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BeaconBlockEntityTranslator.java index 12b050236..0db362949 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BeaconBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BeaconBlockEntityTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.cloudburstmc.nbt.NbtMapBuilder; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedBlockEntityTranslator.java index 58d36af56..1c46edf0a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedBlockEntityTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.block.BlockStateValues; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntity.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntity.java index 3e320029b..e6ce287c1 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntity.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntity.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java index 053e2c8f3..5f6487a24 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.nbt.NbtMap; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java index 9a2b9d8e1..d2777d372 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CampfireBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CampfireBlockEntityTranslator.java index 5a15ebbb7..390615b9e 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CampfireBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CampfireBlockEntityTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.Tag; @@ -34,6 +33,7 @@ import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.ItemMapping; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.CAMPFIRE) public class CampfireBlockEntityTranslator extends BlockEntityTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CommandBlockBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CommandBlockBlockEntityTranslator.java index 36345394b..31a7dbc69 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CommandBlockBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CommandBlockBlockEntityTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.*; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.block.BlockStateValues; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java index 1774d9c76..3ab61c489 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import java.util.ArrayList; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java index 567d3a5e1..141520ed9 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -33,6 +32,7 @@ import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.DoubleChestValue; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.BlockEntityUtils; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; /** * Chests have more block entity properties in Bedrock, which is solved by implementing the BedrockOnlyBlockEntity diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EndGatewayBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EndGatewayBlockEntityTranslator.java index da992d0ad..633992431 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EndGatewayBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EndGatewayBlockEntityTranslator.java @@ -25,16 +25,16 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.LongTag; import com.github.steveice10.opennbt.tag.builtin.Tag; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; import org.cloudburstmc.nbt.NbtList; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; -import it.unimi.dsi.fastutil.ints.IntArrayList; -import it.unimi.dsi.fastutil.ints.IntList; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import java.util.LinkedHashMap; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/HangingSignBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/HangingSignBlockEntityTranslator.java index ea11dcf48..3c09c0499 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/HangingSignBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/HangingSignBlockEntityTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import org.geysermc.geyser.util.SignUtils; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.HANGING_SIGN) public class HangingSignBlockEntityTranslator extends SignBlockEntityTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java index c8dcbc008..34c051a34 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.JIGSAW) public class JigsawBlockBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java index 634b7c6f1..78e71000a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.value.PistonValueType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.PistonValueType; import org.cloudburstmc.math.vector.Vector3d; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/ShulkerBoxBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/ShulkerBoxBlockEntityTranslator.java index bbe6a0725..529ed731e 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/ShulkerBoxBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/ShulkerBoxBlockEntityTranslator.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.translator.inventory.ShulkerInventoryTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.SHULKER_BOX) public class ShulkerBoxBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SignBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SignBlockEntityTranslator.java index 238b136ff..38a4f59c5 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SignBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SignBlockEntityTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.Tag; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java index e9aceece5..61c922528 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntArrayTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java index f2b0f5a78..5611bf90c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java index a24d010b7..40b10de40 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/TrialSpawnerBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/TrialSpawnerBlockEntityTranslator.java index a6a99d868..da013cf3c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/TrialSpawnerBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/TrialSpawnerBlockEntityTranslator.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.cloudburstmc.nbt.NbtMapBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.TRIAL_SPAWNER) public class TrialSpawnerBlockEntityTranslator extends BlockEntityTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/event/LevelEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/event/LevelEventTranslator.java index 03c40c796..311ae0acf 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/event/LevelEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/event/LevelEventTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.event; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundLevelEventPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLevelEventPacket; import org.geysermc.geyser.session.GeyserSession; /** diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/event/PlaySoundEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/event/PlaySoundEventTranslator.java index 22d5c953d..774060a4c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/event/PlaySoundEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/event/PlaySoundEventTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.event; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundLevelEventPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLevelEventPacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.packet.PlaySoundPacket; import org.geysermc.geyser.session.GeyserSession; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/event/SoundEventEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/event/SoundEventEventTranslator.java index d1695303d..d7a58fe48 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/event/SoundEventEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/event/SoundEventEventTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.event; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundLevelEventPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLevelEventPacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/event/SoundLevelEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/event/SoundLevelEventTranslator.java index 67d43e6a8..e5b20493b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/event/SoundLevelEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/event/SoundLevelEventTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.level.event; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundLevelEventPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLevelEventPacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.LevelEventType; import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockAnimateTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockAnimateTranslator.java index 33fbaed30..79e013246 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockAnimateTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockAnimateTranslator.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.level.ServerboundPaddleBoatPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundSwingPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.level.ServerboundPaddleBoatPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundSwingPacket; import org.cloudburstmc.protocol.bedrock.packet.AnimatePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockEntityDataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockEntityDataTranslator.java index 239bf9616..b5e923ee6 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockEntityDataTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockEntityDataTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetJigsawBlockPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.level.ServerboundSignUpdatePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSetJigsawBlockPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.level.ServerboundSignUpdatePacket; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.protocol.bedrock.packet.BlockEntityDataPacket; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java index f4116ec0c..35c46ffd2 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.packet.BlockPickRequestPacket; import org.geysermc.geyser.entity.EntityDefinitions; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java index 10024c02f..456b6507f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBookEditTranslator.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.Filterable; -import com.github.steveice10.mc.protocol.data.game.item.component.WritableBookContent; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundEditBookPacket; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.Filterable; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.WritableBookContent; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundEditBookPacket; import org.cloudburstmc.protocol.bedrock.packet.BookEditPacket; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.type.WrittenBookItem; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandBlockUpdateTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandBlockUpdateTranslator.java index b9561518e..401ece6ca 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandBlockUpdateTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandBlockUpdateTranslator.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.level.block.CommandBlockMode; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetCommandBlockPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetCommandMinecartPacket; import org.cloudburstmc.protocol.bedrock.packet.CommandBlockUpdatePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.CommandBlockMode; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSetCommandBlockPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSetCommandMinecartPacket; @Translator(packet = CommandBlockUpdatePacket.class) public class BedrockCommandBlockUpdateTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockContainerCloseTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockContainerCloseTranslator.java index e2552802f..d675a07e9 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockContainerCloseTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockContainerCloseTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; import org.cloudburstmc.protocol.bedrock.packet.ContainerClosePacket; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.MerchantContainer; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java index 8d005e515..c4a00e41f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java @@ -25,14 +25,6 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.entity.object.Direction; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; -import com.github.steveice10.mc.protocol.data.game.entity.player.InteractAction; -import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClickPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.*; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; import org.cloudburstmc.math.vector.Vector3d; @@ -73,11 +65,15 @@ import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; -import org.geysermc.geyser.util.BlockUtils; -import org.geysermc.geyser.util.CooldownUtils; -import org.geysermc.geyser.util.EntityUtils; -import org.geysermc.geyser.util.InteractionResult; -import org.geysermc.geyser.util.InventoryUtils; +import org.geysermc.geyser.util.*; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.InteractAction; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerAction; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClickPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.*; import java.util.List; import java.util.concurrent.TimeUnit; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockItemFrameDropItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockItemFrameDropItemTranslator.java index 4a5145ead..dff4631b0 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockItemFrameDropItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockItemFrameDropItemTranslator.java @@ -25,15 +25,15 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; -import com.github.steveice10.mc.protocol.data.game.entity.player.InteractAction; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket; import org.cloudburstmc.protocol.bedrock.packet.ItemFrameDropItemPacket; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.ItemFrameEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.InteractAction; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket; /** * Pre-1.16.210: used for both survival and creative item frame item removal diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockLecternUpdateTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockLecternUpdateTranslator.java index 6bac96206..e6d3d4dce 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockLecternUpdateTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockLecternUpdateTranslator.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.entity.object.Direction; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundUseItemOnPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundUseItemOnPacket; import org.cloudburstmc.protocol.bedrock.packet.LecternUpdatePacket; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.LecternContainer; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMobEquipmentTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMobEquipmentTranslator.java index f5086e29a..030c6580f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMobEquipmentTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMobEquipmentTranslator.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundSetCarriedItemPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundUseItemPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundSetCarriedItemPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundUseItemPacket; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerId; import org.cloudburstmc.protocol.bedrock.packet.MobEquipmentPacket; import org.geysermc.geyser.inventory.GeyserItemStack; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMoveEntityAbsoluteTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMoveEntityAbsoluteTranslator.java index 8a8749e34..f8f31d67f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMoveEntityAbsoluteTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMoveEntityAbsoluteTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.level.ServerboundMoveVehiclePacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.packet.MoveEntityAbsolutePacket; import org.geysermc.geyser.entity.EntityDefinitions; @@ -34,6 +33,7 @@ import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.level.ServerboundMoveVehiclePacket; /** * Sent by the client when moving a horse or boat. diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockNetworkStackLatencyTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockNetworkStackLatencyTranslator.java index 412a97e3a..6ca0f3500 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockNetworkStackLatencyTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockNetworkStackLatencyTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundKeepAlivePacket; import org.cloudburstmc.protocol.bedrock.data.AttributeData; import org.cloudburstmc.protocol.bedrock.packet.NetworkStackLatencyPacket; import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket; @@ -33,6 +32,7 @@ import org.geysermc.geyser.entity.attribute.GeyserAttributeType; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundKeepAlivePacket; import java.util.Collections; import java.util.concurrent.TimeUnit; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockPlayerInputTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockPlayerInputTranslator.java index 1737364ff..beb724ffb 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockPlayerInputTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockPlayerInputTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.level.ServerboundMoveVehiclePacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.level.ServerboundPlayerInputPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.level.ServerboundMoveVehiclePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.level.ServerboundPlayerInputPacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.packet.PlayerInputPacket; import org.geysermc.geyser.entity.EntityDefinitions; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockRequestAbilityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockRequestAbilityTranslator.java index be2b1f28a..d0c29c6a9 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockRequestAbilityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockRequestAbilityTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerAbilitiesPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundPlayerAbilitiesPacket; import org.cloudburstmc.protocol.bedrock.data.Ability; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.RequestAbilityPacket; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockRespawnTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockRespawnTranslator.java index 7c4798f80..878f00443 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockRespawnTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockRespawnTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.ClientCommand; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket; +import org.geysermc.mcprotocollib.protocol.data.game.ClientCommand; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket; import org.cloudburstmc.protocol.bedrock.packet.RespawnPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockShowCreditsTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockShowCreditsTranslator.java index 3314975ef..06f680ca6 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockShowCreditsTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockShowCreditsTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.ClientCommand; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket; +import org.geysermc.mcprotocollib.protocol.data.game.ClientCommand; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket; import org.cloudburstmc.protocol.bedrock.packet.ShowCreditsPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureBlockUpdateTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureBlockUpdateTranslator.java index 84b7ffdd2..1434a6d99 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureBlockUpdateTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureBlockUpdateTranslator.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.inventory.UpdateStructureBlockAction; -import com.github.steveice10.mc.protocol.data.game.inventory.UpdateStructureBlockMode; import org.cloudburstmc.protocol.bedrock.data.structure.StructureBlockType; import org.cloudburstmc.protocol.bedrock.data.structure.StructureEditorData; import org.cloudburstmc.protocol.bedrock.packet.StructureBlockUpdatePacket; @@ -34,6 +32,8 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.StructureBlockUtils; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.UpdateStructureBlockAction; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.UpdateStructureBlockMode; @Translator(packet = StructureBlockUpdatePacket.class) public class BedrockStructureBlockUpdateTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureTemplateDataRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureTemplateDataRequestTranslator.java index 947946f36..026d257ab 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureTemplateDataRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockStructureTemplateDataRequestTranslator.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.data.game.inventory.UpdateStructureBlockAction; -import com.github.steveice10.mc.protocol.data.game.inventory.UpdateStructureBlockMode; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.structure.StructureSettings; import org.cloudburstmc.protocol.bedrock.data.structure.StructureTemplateRequestOperation; @@ -35,6 +33,8 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.StructureBlockUtils; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.UpdateStructureBlockAction; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.UpdateStructureBlockMode; /** * Packet used in Bedrock to load structure size into the structure block GUI. It is sent every time the GUI is opened. diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockToggleCrafterSlotRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockToggleCrafterSlotRequestTranslator.java index 5c494cd88..980e8ac00 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockToggleCrafterSlotRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockToggleCrafterSlotRequestTranslator.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerSlotStateChangedPacket; import org.cloudburstmc.protocol.bedrock.packet.ToggleCrafterSlotRequestPacket; import org.geysermc.geyser.inventory.CrafterContainer; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerSlotStateChangedPacket; @Translator(packet = ToggleCrafterSlotRequestPacket.class) public class BedrockToggleCrafterSlotRequestTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/BedrockEntityEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/BedrockEntityEventTranslator.java index 17a80aa39..6b7510d8b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/BedrockEntityEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/BedrockEntityEventTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.bedrock.entity; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSelectTradePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSelectTradePacket; import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.MerchantContainer; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java index 2fd9ce405..887ea3c09 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java @@ -25,13 +25,6 @@ package org.geysermc.geyser.translator.protocol.bedrock.entity.player; -import com.github.steveice10.mc.protocol.data.game.entity.object.Direction; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; -import com.github.steveice10.mc.protocol.data.game.entity.player.InteractAction; -import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction; -import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerState; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.*; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; @@ -57,6 +50,9 @@ import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.BlockUtils; import org.geysermc.geyser.util.CooldownUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.*; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.*; @Translator(packet = PlayerActionPacket.class) public class BedrockActionTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockInteractTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockInteractTranslator.java index a45690ab1..20c1b055d 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockInteractTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockInteractTranslator.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.translator.protocol.bedrock.entity.player; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; -import com.github.steveice10.mc.protocol.data.game.entity.player.InteractAction; -import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerState; -import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerCommandPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.InteractAction; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerState; +import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundPlayerCommandPacket; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData; import org.cloudburstmc.protocol.bedrock.packet.InteractPacket; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockMovePlayerTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockMovePlayerTranslator.java index d81c0abab..cae12170d 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockMovePlayerTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockMovePlayerTranslator.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.translator.protocol.bedrock.entity.player; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosRotPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerRotPacket; -import com.github.steveice10.packetlib.packet.Packet; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosRotPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerRotPacket; +import org.geysermc.mcprotocollib.network.packet.Packet; import org.cloudburstmc.math.vector.Vector3d; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.packet.MovePlayerPacket; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockRiderJumpTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockRiderJumpTranslator.java index f7ac81219..76b95103e 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockRiderJumpTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockRiderJumpTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.protocol.bedrock.entity.player; -import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerState; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerCommandPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerState; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundPlayerCommandPacket; import org.cloudburstmc.protocol.bedrock.packet.RiderJumpPacket; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.living.animal.horse.AbstractHorseEntity; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetDefaultGameTypeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetDefaultGameTypeTranslator.java index df28f7ca7..aa815fab7 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetDefaultGameTypeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetDefaultGameTypeTranslator.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.translator.protocol.bedrock.entity.player; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import org.cloudburstmc.protocol.bedrock.packet.SetDefaultGameTypePacket; import org.cloudburstmc.protocol.bedrock.packet.SetPlayerGameTypePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.EntityUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; @Translator(packet = SetDefaultGameTypePacket.class) public class BedrockSetDefaultGameTypeTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetDifficultyTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetDifficultyTranslator.java index b996a96b1..176f00b8f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetDifficultyTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetDifficultyTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.bedrock.entity.player; -import com.github.steveice10.mc.protocol.data.game.setting.Difficulty; +import org.geysermc.mcprotocollib.protocol.data.game.setting.Difficulty; import org.cloudburstmc.protocol.bedrock.packet.SetDifficultyPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetPlayerGameTypeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetPlayerGameTypeTranslator.java index 2d8d420f8..f00156268 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetPlayerGameTypeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetPlayerGameTypeTranslator.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.translator.protocol.bedrock.entity.player; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import org.cloudburstmc.protocol.bedrock.packet.SetPlayerGameTypePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.EntityUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; /** * In vanilla Bedrock, if you have operator status, this sets the player's gamemode without confirmation from the server. diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetPlayerInventoryOptionsTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetPlayerInventoryOptionsTranslator.java index 0f07d84da..7e23c2e4c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetPlayerInventoryOptionsTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetPlayerInventoryOptionsTranslator.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.translator.protocol.bedrock.entity.player; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.inventory.CraftingBookStateType; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundRecipeBookChangeSettingsPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.CraftingBookStateType; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundRecipeBookChangeSettingsPacket; import org.cloudburstmc.protocol.bedrock.data.inventory.InventoryTabLeft; import org.cloudburstmc.protocol.bedrock.data.inventory.InventoryTabRight; import org.cloudburstmc.protocol.bedrock.packet.SetPlayerInventoryOptionsPacket; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/world/BedrockLevelSoundEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/world/BedrockLevelSoundEventTranslator.java index ec8a18edb..822d8f6ba 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/world/BedrockLevelSoundEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/world/BedrockLevelSoundEventTranslator.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.translator.protocol.bedrock.world; -import com.github.steveice10.mc.protocol.data.game.entity.object.Direction; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundSwingPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundUseItemOnPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundSwingPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundUseItemOnPacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaAwardStatsTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaAwardStatsTranslator.java index 4f4c2e549..4f0f1f587 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaAwardStatsTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaAwardStatsTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundAwardStatsPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundAwardStatsPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaBossEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaBossEventTranslator.java index 30d6aa017..c1e0b9a3a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaBossEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaBossEventTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundBossEventPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundBossEventPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.BossBar; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaChangeDifficultyTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaChangeDifficultyTranslator.java index 970c49e23..996dc9d84 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaChangeDifficultyTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaChangeDifficultyTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundChangeDifficultyPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundChangeDifficultyPacket; import org.cloudburstmc.protocol.bedrock.packet.SetDifficultyPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaClientboundRecipesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaClientboundRecipesTranslator.java index 3fe5abff8..9eb69183d 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaClientboundRecipesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaClientboundRecipesTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundRecipePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundRecipePacket; import org.cloudburstmc.protocol.bedrock.packet.UnlockedRecipesPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaClientboundResourcePackPushPacket.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaClientboundResourcePackPushPacket.java index b84c7a55b..9e7306ab1 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaClientboundResourcePackPushPacket.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaClientboundResourcePackPushPacket.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.data.game.ResourcePackStatus; -import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundResourcePackPushPacket; -import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundResourcePackPacket; +import org.geysermc.mcprotocollib.protocol.data.game.ResourcePackStatus; +import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundResourcePackPushPacket; +import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundResourcePackPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java index 9d3351217..706997402 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.data.game.command.CommandNode; -import com.github.steveice10.mc.protocol.data.game.command.CommandParser; -import com.github.steveice10.mc.protocol.data.game.command.properties.ResourceProperties; -import com.github.steveice10.mc.protocol.data.game.entity.attribute.AttributeType; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundCommandsPacket; +import org.geysermc.mcprotocollib.protocol.data.game.command.CommandNode; +import org.geysermc.mcprotocollib.protocol.data.game.command.CommandParser; +import org.geysermc.mcprotocollib.protocol.data.game.command.properties.ResourceProperties; +import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.AttributeType; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundCommandsPacket; import it.unimi.dsi.fastutil.Hash; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCustomPayloadTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCustomPayloadTranslator.java index 2a7202b0c..f8a21f904 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCustomPayloadTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCustomPayloadTranslator.java @@ -25,13 +25,11 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundCustomPayloadPacket; -import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket; import com.google.common.base.Charsets; -import org.cloudburstmc.protocol.bedrock.packet.TransferPacket; -import org.cloudburstmc.protocol.bedrock.packet.UnknownPacket; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; +import org.cloudburstmc.protocol.bedrock.packet.TransferPacket; +import org.cloudburstmc.protocol.bedrock.packet.UnknownPacket; import org.geysermc.cumulus.Forms; import org.geysermc.cumulus.form.Form; import org.geysermc.cumulus.form.util.FormType; @@ -45,6 +43,8 @@ import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundCustomPayloadPacket; +import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket; import java.nio.charset.StandardCharsets; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCustomQueryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCustomQueryTranslator.java index 6096af12d..1e448c48e 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCustomQueryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCustomQueryTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.login.clientbound.ClientboundCustomQueryPacket; -import com.github.steveice10.mc.protocol.packet.login.serverbound.ServerboundCustomQueryAnswerPacket; +import org.geysermc.mcprotocollib.protocol.packet.login.clientbound.ClientboundCustomQueryPacket; +import org.geysermc.mcprotocollib.protocol.packet.login.serverbound.ServerboundCustomQueryAnswerPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaDisconnectTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaDisconnectTranslator.java index 8bf5ae4ba..2eb08fb92 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaDisconnectTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaDisconnectTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundDisconnectPacket; +import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundDisconnectPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaDisguisedChatTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaDisguisedChatTranslator.java index 2ad45fe52..67bdb6f9a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaDisguisedChatTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaDisguisedChatTranslator.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundDisguisedChatPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.translator.text.MessageTranslator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundDisguisedChatPacket; @Translator(packet = ClientboundDisguisedChatPacket.class) public class JavaDisguisedChatTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaGameProfileTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaGameProfileTranslator.java index 12f96360b..96bab0bfa 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaGameProfileTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaGameProfileTranslator.java @@ -26,8 +26,6 @@ package org.geysermc.geyser.translator.protocol.java; import com.github.steveice10.mc.auth.data.GameProfile; -import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket; -import com.github.steveice10.mc.protocol.packet.login.clientbound.ClientboundGameProfilePacket; import org.geysermc.geyser.api.network.AuthType; import org.geysermc.geyser.entity.type.player.PlayerEntity; import org.geysermc.geyser.session.GeyserSession; @@ -35,6 +33,8 @@ import org.geysermc.geyser.skin.SkinManager; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.PluginMessageUtils; +import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket; +import org.geysermc.mcprotocollib.protocol.packet.login.clientbound.ClientboundGameProfilePacket; /** * ClientboundGameProfilePacket triggers protocol change LOGIN -> CONFIGURATION diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaKeepAliveTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaKeepAliveTranslator.java index da8358da2..399c23080 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaKeepAliveTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaKeepAliveTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundKeepAlivePacket; +import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundKeepAlivePacket; import org.cloudburstmc.protocol.bedrock.packet.NetworkStackLatencyPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginDisconnectTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginDisconnectTranslator.java index c0be2c624..e92ae1bbd 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginDisconnectTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginDisconnectTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.login.clientbound.ClientboundLoginDisconnectPacket; +import org.geysermc.mcprotocollib.protocol.packet.login.clientbound.ClientboundLoginDisconnectPacket; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.TranslatableComponent; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java index ebf99fb65..fe4401dca 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerSpawnInfo; -import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundLoginPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerSpawnInfo; +import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundLoginPacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.GameRuleData; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaPingTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaPingTranslator.java index c966f3abb..fa7175003 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaPingTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaPingTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundPingPacket; -import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundPongPacket; +import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundPingPacket; +import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundPongPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaPlayerChatTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaPlayerChatTranslator.java index e06182b8d..f8d392dd5 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaPlayerChatTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaPlayerChatTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundPlayerChatPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundPlayerChatPacket; import net.kyori.adventure.text.Component; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRegistryDataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRegistryDataTranslator.java index ddb9c76b7..6af94001e 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRegistryDataTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRegistryDataTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.configuration.clientbound.ClientboundRegistryDataPacket; +import org.geysermc.mcprotocollib.protocol.packet.configuration.clientbound.ClientboundRegistryDataPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java index bfb590247..fe0868253 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerSpawnInfo; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundRespawnPacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; @@ -40,6 +38,8 @@ import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.ChunkUtils; import org.geysermc.geyser.util.DimensionUtils; import org.geysermc.geyser.util.EntityUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerSpawnInfo; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundRespawnPacket; @Translator(packet = ClientboundRespawnPacket.class) public class JavaRespawnTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSelectAdvancementsTabTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSelectAdvancementsTabTranslator.java index e33863244..04c018472 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSelectAdvancementsTabTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSelectAdvancementsTabTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundSelectAdvancementsTabPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundSelectAdvancementsTabPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.AdvancementsCache; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSystemChatTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSystemChatTranslator.java index e400773c8..0a0f2832c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSystemChatTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSystemChatTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundSystemChatPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundSystemChatPacket; import net.kyori.adventure.text.TranslatableComponent; import org.cloudburstmc.protocol.bedrock.packet.TextPacket; import org.geysermc.geyser.session.GeyserSession; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateAdvancementsTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateAdvancementsTranslator.java index a7efdbefa..8bf520da0 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateAdvancementsTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateAdvancementsTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.data.game.advancement.Advancement; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundUpdateAdvancementsPacket; +import org.geysermc.mcprotocollib.protocol.data.game.advancement.Advancement; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundUpdateAdvancementsPacket; import org.cloudburstmc.protocol.bedrock.packet.ToastRequestPacket; import org.geysermc.geyser.level.GeyserAdvancement; import org.geysermc.geyser.session.GeyserSession; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java index 20b223248..0db62f21d 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java @@ -25,15 +25,6 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; -import com.github.steveice10.mc.protocol.data.game.recipe.Recipe; -import com.github.steveice10.mc.protocol.data.game.recipe.RecipeType; -import com.github.steveice10.mc.protocol.data.game.recipe.data.ShapedRecipeData; -import com.github.steveice10.mc.protocol.data.game.recipe.data.ShapelessRecipeData; -import com.github.steveice10.mc.protocol.data.game.recipe.data.SmithingTransformRecipeData; -import com.github.steveice10.mc.protocol.data.game.recipe.data.StoneCuttingRecipeData; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundUpdateRecipesPacket; import it.unimi.dsi.fastutil.ints.*; import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; @@ -48,11 +39,7 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.descriptor.ItemTagDescri import org.cloudburstmc.protocol.bedrock.packet.CraftingDataPacket; import org.cloudburstmc.protocol.bedrock.packet.TrimDataPacket; import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.inventory.recipe.GeyserRecipe; -import org.geysermc.geyser.inventory.recipe.GeyserShapedRecipe; -import org.geysermc.geyser.inventory.recipe.GeyserShapelessRecipe; -import org.geysermc.geyser.inventory.recipe.GeyserStonecutterData; -import org.geysermc.geyser.inventory.recipe.TrimRecipe; +import org.geysermc.geyser.inventory.recipe.*; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; @@ -60,6 +47,15 @@ import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.InventoryUtils; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.Ingredient; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.Recipe; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.RecipeType; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.data.ShapedRecipeData; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.data.ShapelessRecipeData; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.data.SmithingTransformRecipeData; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.data.StoneCuttingRecipeData; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundUpdateRecipesPacket; import java.util.*; import java.util.stream.Collectors; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateTagsTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateTagsTranslator.java index ae59cf0f8..4df73b4c2 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateTagsTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateTagsTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; -import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundUpdateTagsPacket; +import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundUpdateTagsPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaAnimateTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaAnimateTranslator.java index 1aa147314..8bd4bad10 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaAnimateTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaAnimateTranslator.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.data.game.entity.player.Animation; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundAnimatePacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.packet.AnimateEntityPacket; import org.cloudburstmc.protocol.bedrock.packet.AnimatePacket; @@ -36,6 +34,8 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.DimensionUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Animation; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundAnimatePacket; import java.util.Optional; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaDamageEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaDamageEventTranslator.java index 19a6e25c0..9d491f92c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaDamageEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaDamageEventTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundDamageEventPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundDamageEventPacket; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket; import org.geysermc.geyser.entity.type.Entity; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java index 4b1483bbf..fbabd4afa 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundEntityEventPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundEntityEventPacket; import org.cloudburstmc.protocol.bedrock.data.ParticleType; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveEntityPosRotTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveEntityPosRotTranslator.java index 2ad1503a8..31d46f096 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveEntityPosRotTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveEntityPosRotTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundMoveEntityPosRotPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundMoveEntityPosRotPacket; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveEntityPosTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveEntityPosTranslator.java index cbb3cecc2..638828a2b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveEntityPosTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveEntityPosTranslator.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundMoveEntityPosPacket; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundMoveEntityPosPacket; @Translator(packet = ClientboundMoveEntityPosPacket.class) public class JavaMoveEntityPosTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveEntityRotTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveEntityRotTranslator.java index 75d4c6189..b48b801f3 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveEntityRotTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveEntityRotTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundMoveEntityRotPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundMoveEntityRotPacket; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveVehicleTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveVehicleTranslator.java index bdb159633..111b72c4f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveVehicleTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaMoveVehicleTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundMoveVehiclePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundMoveVehiclePacket; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRemoveEntitiesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRemoveEntitiesTranslator.java index 776cfb4d7..0148b1e05 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRemoveEntitiesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRemoveEntitiesTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundRemoveEntitiesPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundRemoveEntitiesPacket; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRemoveMobEffectTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRemoveMobEffectTranslator.java index 52b771caa..dafa5aec1 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRemoveMobEffectTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRemoveMobEffectTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundRemoveMobEffectPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundRemoveMobEffectPacket; import org.cloudburstmc.protocol.bedrock.packet.MobEffectPacket; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRotateHeadTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRotateHeadTranslator.java index 65e529792..dc03a76e9 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRotateHeadTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaRotateHeadTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundRotateHeadPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundRotateHeadPacket; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityDataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityDataTranslator.java index 54c14f7f0..2dc780c66 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityDataTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityDataTranslator.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundSetEntityDataPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundSetEntityDataPacket; @Translator(packet = ClientboundSetEntityDataPacket.class) public class JavaSetEntityDataTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityLinkTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityLinkTranslator.java index 720f03779..d595e928f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityLinkTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityLinkTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundSetEntityLinkPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundSetEntityLinkPacket; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityMotionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityMotionTranslator.java index 62e1d200e..6bbc59e8b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityMotionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityMotionTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundSetEntityMotionPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundSetEntityMotionPacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.packet.SetEntityMotionPacket; import org.geysermc.geyser.entity.type.Entity; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java index 7c93725e0..cc71cca0a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEquipmentTranslator.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.Equipment; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundSetEquipmentPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Equipment; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundSetEquipmentPacket; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.LivingEntity; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetPassengersTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetPassengersTranslator.java index 14d6127ad..9895a248c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetPassengersTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetPassengersTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundSetPassengersPacket; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData; import org.cloudburstmc.protocol.bedrock.packet.SetEntityLinkPacket; @@ -35,6 +34,7 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.EntityUtils; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundSetPassengersPacket; import java.util.ArrayList; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSoundEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSoundEntityTranslator.java index 68f310db4..d6e70b3f3 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSoundEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSoundEntityTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundSoundEntityPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundSoundEntityPacket; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaTakeItemEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaTakeItemEntityTranslator.java index cc2b4b030..7722459d4 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaTakeItemEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaTakeItemEntityTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundTakeItemEntityPacket; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; import org.cloudburstmc.protocol.bedrock.packet.TakeItemEntityPacket; @@ -34,6 +33,7 @@ import org.geysermc.geyser.entity.type.ExpOrbEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundTakeItemEntityPacket; /** * This packet is called whenever a player picks up an item. diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaTeleportEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaTeleportEntityTranslator.java index 9925bf432..8b3a06d7c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaTeleportEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaTeleportEntityTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundTeleportEntityPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundTeleportEntityPacket; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaUpdateAttributesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaUpdateAttributesTranslator.java index a42f2d5dd..31c9c7df3 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaUpdateAttributesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaUpdateAttributesTranslator.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundUpdateAttributesPacket; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.LivingEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundUpdateAttributesPacket; @Translator(packet = ClientboundUpdateAttributesPacket.class) public class JavaUpdateAttributesTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaUpdateMobEffectTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaUpdateMobEffectTranslator.java index e56a272ab..7638df8be 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaUpdateMobEffectTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaUpdateMobEffectTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundUpdateMobEffectPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundUpdateMobEffectPacket; import org.cloudburstmc.protocol.bedrock.packet.MobEffectPacket; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.session.GeyserSession; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaBlockChangedAckTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaBlockChangedAckTranslator.java index 523d0fdc4..c48c040a2 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaBlockChangedAckTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaBlockChangedAckTranslator.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.player.ClientboundBlockChangedAckPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.player.ClientboundBlockChangedAckPacket; @Translator(packet = ClientboundBlockChangedAckPacket.class) public class JavaBlockChangedAckTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerAbilitiesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerAbilitiesTranslator.java index 783f4e824..6f41603a4 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerAbilitiesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerAbilitiesTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.player.ClientboundPlayerAbilitiesPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.player.ClientboundPlayerAbilitiesPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerCombatKillTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerCombatKillTranslator.java index 4b0cafed3..6f719b762 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerCombatKillTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerCombatKillTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.player.ClientboundPlayerCombatKillPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.player.ClientboundPlayerCombatKillPacket; import org.cloudburstmc.protocol.bedrock.packet.DeathInfoPacket; import net.kyori.adventure.text.Component; import org.geysermc.geyser.session.GeyserSession; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerInfoRemoveTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerInfoRemoveTranslator.java index f5c4b1398..60a245111 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerInfoRemoveTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerInfoRemoveTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundPlayerInfoRemovePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundPlayerInfoRemovePacket; import org.cloudburstmc.protocol.bedrock.packet.PlayerListPacket; import org.geysermc.geyser.entity.type.player.PlayerEntity; import org.geysermc.geyser.session.GeyserSession; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerInfoUpdateTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerInfoUpdateTranslator.java index 3debb7f5f..f5ea4c08d 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerInfoUpdateTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerInfoUpdateTranslator.java @@ -26,9 +26,6 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; import com.github.steveice10.mc.auth.data.GameProfile; -import com.github.steveice10.mc.protocol.data.game.PlayerListEntry; -import com.github.steveice10.mc.protocol.data.game.PlayerListEntryAction; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundPlayerInfoUpdatePacket; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.packet.PlayerListPacket; @@ -38,6 +35,9 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.skin.SkinManager; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.data.game.PlayerListEntry; +import org.geysermc.mcprotocollib.protocol.data.game.PlayerListEntryAction; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundPlayerInfoUpdatePacket; import java.util.ArrayList; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerLookAtTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerLookAtTranslator.java index 7814a6719..b1413542b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerLookAtTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerLookAtTranslator.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.player.ClientboundPlayerLookAtPacket; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.MathUtils; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.player.ClientboundPlayerLookAtPacket; @Translator(packet = ClientboundPlayerLookAtPacket.class) public class JavaPlayerLookAtTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerPositionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerPositionTranslator.java index f2c566a23..413833acf 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerPositionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerPositionTranslator.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; -import com.github.steveice10.mc.protocol.data.game.entity.player.PositionElement; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.player.ClientboundPlayerPositionPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.level.ServerboundAcceptTeleportationPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosRotPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PositionElement; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.player.ClientboundPlayerPositionPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.level.ServerboundAcceptTeleportationPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosRotPacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.packet.ChunkRadiusUpdatedPacket; import org.cloudburstmc.protocol.bedrock.packet.MovePlayerPacket; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetCarriedItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetCarriedItemTranslator.java index 97a9e0aae..e590b5658 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetCarriedItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetCarriedItemTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.player.ClientboundSetCarriedItemPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.player.ClientboundSetCarriedItemPacket; import org.cloudburstmc.protocol.bedrock.packet.PlayerHotbarPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetExperienceTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetExperienceTranslator.java index 80dd08eaa..3e3550415 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetExperienceTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetExperienceTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.player.ClientboundSetExperiencePacket; import org.cloudburstmc.protocol.bedrock.data.AttributeData; import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket; import org.geysermc.geyser.entity.attribute.GeyserAttributeType; @@ -33,6 +32,7 @@ import org.geysermc.geyser.entity.type.player.SessionPlayerEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.player.ClientboundSetExperiencePacket; import java.util.Arrays; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetHealthTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetHealthTranslator.java index decf910ca..1f8992e54 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetHealthTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetHealthTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.player.ClientboundSetHealthPacket; import org.cloudburstmc.protocol.bedrock.data.AttributeData; import org.cloudburstmc.protocol.bedrock.packet.RespawnPacket; import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket; @@ -34,6 +33,7 @@ import org.geysermc.geyser.entity.type.player.SessionPlayerEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.player.ClientboundSetHealthPacket; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/spawn/JavaAddEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/spawn/JavaAddEntityTranslator.java index e058594c3..572d233d0 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/spawn/JavaAddEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/spawn/JavaAddEntityTranslator.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.translator.protocol.java.entity.spawn; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; -import com.github.steveice10.mc.protocol.data.game.entity.object.Direction; -import com.github.steveice10.mc.protocol.data.game.entity.object.FallingBlockData; -import com.github.steveice10.mc.protocol.data.game.entity.object.ProjectileData; -import com.github.steveice10.mc.protocol.data.game.entity.object.WardenData; -import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.spawn.ClientboundAddEntityPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.FallingBlockData; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.ProjectileData; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.WardenData; +import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.spawn.ClientboundAddEntityPacket; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.entity.EntityDefinition; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/spawn/JavaAddExperienceOrbTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/spawn/JavaAddExperienceOrbTranslator.java index 2d5e8fb08..8f37eb4d4 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/spawn/JavaAddExperienceOrbTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/spawn/JavaAddExperienceOrbTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.entity.spawn; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.spawn.ClientboundAddExperienceOrbPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.spawn.ClientboundAddExperienceOrbPacket; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.ExpOrbEntity; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerCloseTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerCloseTranslator.java index 9f687f046..c5786d9aa 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerCloseTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerCloseTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.inventory; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundContainerClosePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundContainerClosePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetContentTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetContentTranslator.java index 2f8204871..44bd7171f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetContentTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetContentTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.inventory; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundContainerSetContentPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundContainerSetContentPacket; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.inventory.GeyserItemStack; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetDataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetDataTranslator.java index 923b10a26..0b8d8c5ab 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetDataTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetDataTranslator.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.translator.protocol.java.inventory; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundContainerSetDataPacket; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.InventoryUtils; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundContainerSetDataPacket; @Translator(packet = ClientboundContainerSetDataPacket.class) public class JavaContainerSetDataTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java index 594c99291..4372b5ea5 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.translator.protocol.java.inventory; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundContainerSetSlotPacket; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.Ingredient; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundContainerSetSlotPacket; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerId; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapedRecipeData; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaHorseScreenOpenTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaHorseScreenOpenTranslator.java index d2abcb5e3..23b79ba67 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaHorseScreenOpenTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaHorseScreenOpenTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.inventory; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundHorseScreenOpenPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundHorseScreenOpenPacket; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaMerchantOffersTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaMerchantOffersTranslator.java index 68d2bcab3..970061436 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaMerchantOffersTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaMerchantOffersTranslator.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.translator.protocol.java.inventory; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.inventory.VillagerTrade; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundMerchantOffersPacket; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.VillagerTrade; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundMerchantOffersPacket; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenBookTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenBookTranslator.java index 24b964b7c..539cce06d 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenBookTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenBookTranslator.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.translator.protocol.java.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundOpenBookPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.LecternContainer; @@ -38,6 +35,9 @@ import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.InventoryUtils; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundOpenBookPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; import java.util.Objects; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenScreenTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenScreenTranslator.java index 1d0b4bf63..31894339c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenScreenTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaOpenScreenTranslator.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.translator.protocol.java.inventory; -import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundOpenScreenPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundOpenScreenPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; import net.kyori.adventure.text.Component; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.network.GameProtocol; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockDestructionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockDestructionTranslator.java index 2fdba716b..1b23066cc 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockDestructionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockDestructionTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundBlockDestructionPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundBlockDestructionPacket; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; import org.geysermc.geyser.registry.BlockRegistries; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java index 325bae593..ca746f79b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundBlockEntityDataPacket; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.math.vector.Vector3i; @@ -46,6 +43,9 @@ import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.BlockEntityUtils; import org.geysermc.geyser.util.StructureBlockUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundBlockEntityDataPacket; @Translator(packet = ClientboundBlockEntityDataPacket.class) public class JavaBlockEntityDataTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEventTranslator.java index 28fd2401b..8f6c69a29 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEventTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.data.game.level.block.value.*; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundBlockEventPacket; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.*; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundBlockEventPacket; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockUpdateTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockUpdateTranslator.java index 4ccc2b4d4..ac8bd8eb0 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockUpdateTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockUpdateTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundBlockUpdatePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundBlockUpdatePacket; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaChunkBatchFinishedTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaChunkBatchFinishedTranslator.java index 115222c6c..c93ebd530 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaChunkBatchFinishedTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaChunkBatchFinishedTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundChunkBatchFinishedPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.level.ServerboundChunkBatchReceivedPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundChunkBatchFinishedPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.level.ServerboundChunkBatchReceivedPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaCooldownTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaCooldownTranslator.java index 4249be6fc..8e07a7d89 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaCooldownTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaCooldownTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundCooldownPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundCooldownPacket; import org.cloudburstmc.protocol.bedrock.packet.PlayerStartItemCooldownPacket; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaExplodeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaExplodeTranslator.java index c5dba39ae..7b6d4e264 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaExplodeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaExplodeTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundExplodePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundExplodePacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaForgetLevelChunkTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaForgetLevelChunkTranslator.java index 4cc0af6e7..b0abe0f59 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaForgetLevelChunkTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaForgetLevelChunkTranslator.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundForgetLevelChunkPacket; import org.cloudburstmc.math.vector.Vector3i; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.ChunkUtils; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundForgetLevelChunkPacket; import java.util.ArrayList; import java.util.Iterator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaGameEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaGameEventTranslator.java index f2d60fe34..3aa343cf5 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaGameEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaGameEventTranslator.java @@ -25,14 +25,14 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.data.game.ClientCommand; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.level.notify.EnterCreditsValue; -import com.github.steveice10.mc.protocol.data.game.level.notify.RainStrengthValue; -import com.github.steveice10.mc.protocol.data.game.level.notify.RespawnScreenValue; -import com.github.steveice10.mc.protocol.data.game.level.notify.ThunderStrengthValue; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundGameEventPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket; +import org.geysermc.mcprotocollib.protocol.data.game.ClientCommand; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.level.notify.EnterCreditsValue; +import org.geysermc.mcprotocollib.protocol.data.game.level.notify.RainStrengthValue; +import org.geysermc.mcprotocollib.protocol.data.game.level.notify.RespawnScreenValue; +import org.geysermc.mcprotocollib.protocol.data.game.level.notify.ThunderStrengthValue; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundGameEventPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.GameRuleData; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java index 1e6534130..4fd581d84 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java @@ -25,26 +25,12 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.data.game.chunk.BitStorage; -import com.github.steveice10.mc.protocol.data.game.chunk.ChunkSection; -import com.github.steveice10.mc.protocol.data.game.chunk.DataPalette; -import com.github.steveice10.mc.protocol.data.game.chunk.palette.GlobalPalette; -import com.github.steveice10.mc.protocol.data.game.chunk.palette.Palette; -import com.github.steveice10.mc.protocol.data.game.chunk.palette.SingletonPalette; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundLevelChunkWithLightPacket; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufOutputStream; import io.netty.buffer.Unpooled; -import it.unimi.dsi.fastutil.ints.IntArrayList; -import it.unimi.dsi.fastutil.ints.IntImmutableList; -import it.unimi.dsi.fastutil.ints.IntList; -import it.unimi.dsi.fastutil.ints.IntLists; -import it.unimi.dsi.fastutil.ints.IntOpenHashSet; -import it.unimi.dsi.fastutil.ints.IntSet; +import it.unimi.dsi.fastutil.ints.*; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NBTOutputStream; @@ -73,15 +59,22 @@ import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.BlockEntityUtils; import org.geysermc.geyser.util.ChunkUtils; import org.geysermc.geyser.util.DimensionUtils; +import org.geysermc.mcprotocollib.protocol.data.game.chunk.BitStorage; +import org.geysermc.mcprotocollib.protocol.data.game.chunk.ChunkSection; +import org.geysermc.mcprotocollib.protocol.data.game.chunk.DataPalette; +import org.geysermc.mcprotocollib.protocol.data.game.chunk.palette.GlobalPalette; +import org.geysermc.mcprotocollib.protocol.data.game.chunk.palette.Palette; +import org.geysermc.mcprotocollib.protocol.data.game.chunk.palette.SingletonPalette; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityInfo; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLevelChunkWithLightPacket; import java.io.IOException; import java.util.BitSet; import java.util.List; import java.util.Map; -import static org.geysermc.geyser.util.ChunkUtils.EMPTY_BLOCK_STORAGE; -import static org.geysermc.geyser.util.ChunkUtils.EMPTY_CHUNK_SECTION_SIZE; -import static org.geysermc.geyser.util.ChunkUtils.indexYZXtoXZY; +import static org.geysermc.geyser.util.ChunkUtils.*; @Translator(packet = ClientboundLevelChunkWithLightPacket.class) public class JavaLevelChunkWithLightTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelEventTranslator.java index 843f3d514..cb8a8e60f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelEventTranslator.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.data.game.entity.object.Direction; -import com.github.steveice10.mc.protocol.data.game.level.event.*; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundLevelEventPacket; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; +import org.geysermc.mcprotocollib.protocol.data.game.level.event.*; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLevelEventPacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelParticlesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelParticlesTranslator.java index 7d9b81d29..bedddbc6e 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelParticlesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelParticlesTranslator.java @@ -25,15 +25,15 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.level.particle.BlockParticleData; -import com.github.steveice10.mc.protocol.data.game.level.particle.DustParticleData; -import com.github.steveice10.mc.protocol.data.game.level.particle.ItemParticleData; -import com.github.steveice10.mc.protocol.data.game.level.particle.Particle; -import com.github.steveice10.mc.protocol.data.game.level.particle.VibrationParticleData; -import com.github.steveice10.mc.protocol.data.game.level.particle.positionsource.BlockPositionSource; -import com.github.steveice10.mc.protocol.data.game.level.particle.positionsource.EntityPositionSource; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundLevelParticlesPacket; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.BlockParticleData; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.DustParticleData; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ItemParticleData; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.Particle; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.VibrationParticleData; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.positionsource.BlockPositionSource; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.positionsource.EntityPositionSource; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLevelParticlesPacket; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.math.vector.Vector3f; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaMapItemDataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaMapItemDataTranslator.java index 01b0f324f..1591b4952 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaMapItemDataTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaMapItemDataTranslator.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.data.game.level.map.MapData; -import com.github.steveice10.mc.protocol.data.game.level.map.MapIcon; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundMapItemDataPacket; +import org.geysermc.mcprotocollib.protocol.data.game.level.map.MapData; +import org.geysermc.mcprotocollib.protocol.data.game.level.map.MapIcon; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundMapItemDataPacket; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.MapDecoration; import org.cloudburstmc.protocol.bedrock.data.MapTrackedObject; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaOpenSignEditorTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaOpenSignEditorTranslator.java index d044ac034..99a32c0c1 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaOpenSignEditorTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaOpenSignEditorTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundOpenSignEditorPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundOpenSignEditorPacket; import org.cloudburstmc.protocol.bedrock.packet.OpenSignPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSectionBlocksUpdateTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSectionBlocksUpdateTranslator.java index abc9a6c21..a52bb33b0 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSectionBlocksUpdateTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSectionBlocksUpdateTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockChangeEntry; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundSectionBlocksUpdatePacket; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockChangeEntry; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundSectionBlocksUpdatePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetChunkCacheCenterTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetChunkCacheCenterTranslator.java index baec29d47..e75b6c022 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetChunkCacheCenterTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetChunkCacheCenterTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundSetChunkCacheCenterPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundSetChunkCacheCenterPacket; import org.cloudburstmc.math.vector.Vector3i; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetChunkCacheRadiusTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetChunkCacheRadiusTranslator.java index 3a0a77cc0..59402325c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetChunkCacheRadiusTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetChunkCacheRadiusTranslator.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundSetChunkCacheRadiusPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundSetChunkCacheRadiusPacket; @Translator(packet = ClientboundSetChunkCacheRadiusPacket.class) public class JavaSetChunkCacheRadiusTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetDefaultSpawnPositionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetDefaultSpawnPositionTranslator.java index 9662fdd81..da751419e 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetDefaultSpawnPositionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetDefaultSpawnPositionTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundSetDefaultSpawnPositionPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundSetDefaultSpawnPositionPacket; import org.cloudburstmc.protocol.bedrock.packet.SetSpawnPositionPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetTimeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetTimeTranslator.java index b86b4247c..1e398ad9b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetTimeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetTimeTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundSetTimePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundSetTimePacket; import org.cloudburstmc.protocol.bedrock.packet.SetTimePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSoundTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSoundTranslator.java index ceb2d989d..ad07d8537 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSoundTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSoundTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundSoundPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundSoundPacket; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaStopSoundTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaStopSoundTranslator.java index 7320b7637..99e076ad2 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaStopSoundTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaStopSoundTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundStopSoundPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundStopSoundPacket; import org.cloudburstmc.protocol.bedrock.packet.StopSoundPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaInitializeBorderTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaInitializeBorderTranslator.java index 857997170..9f1f5b434 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaInitializeBorderTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaInitializeBorderTranslator.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.translator.protocol.java.level.border; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.border.ClientboundInitializeBorderPacket; import org.cloudburstmc.math.vector.Vector2d; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.WorldBorder; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.border.ClientboundInitializeBorderPacket; @Translator(packet = ClientboundInitializeBorderPacket.class) public class JavaInitializeBorderTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderCenterTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderCenterTranslator.java index ebcef08a7..28f7a6faa 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderCenterTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderCenterTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level.border; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.border.ClientboundSetBorderCenterPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.border.ClientboundSetBorderCenterPacket; import org.cloudburstmc.math.vector.Vector2d; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.WorldBorder; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderLerpSizeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderLerpSizeTranslator.java index a41c90f04..b676523c9 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderLerpSizeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderLerpSizeTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level.border; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.border.ClientboundSetBorderLerpSizePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.border.ClientboundSetBorderLerpSizePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.WorldBorder; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderSizeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderSizeTranslator.java index 51cd17278..deec4b7a2 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderSizeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderSizeTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level.border; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.border.ClientboundSetBorderSizePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.border.ClientboundSetBorderSizePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.WorldBorder; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderWarningDelayTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderWarningDelayTranslator.java index 912ca9a09..e92ab34ad 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderWarningDelayTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderWarningDelayTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.level.border; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.border.ClientboundSetBorderWarningDelayPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.border.ClientboundSetBorderWarningDelayPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.WorldBorder; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderWarningDistanceTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderWarningDistanceTranslator.java index 14badb565..4d862163e 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderWarningDistanceTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/border/JavaSetBorderWarningDistanceTranslator.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.translator.protocol.java.level.border; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.border.ClientboundSetBorderWarningDistancePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.WorldBorder; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.border.ClientboundSetBorderWarningDistancePacket; @Translator(packet = ClientboundSetBorderWarningDistancePacket.class) public class JavaSetBorderWarningDistanceTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaResetScorePacket.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaResetScorePacket.java index 01b4fddea..e8d307c90 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaResetScorePacket.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaResetScorePacket.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.translator.protocol.java.scoreboard; -import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.scoreboard.ClientboundResetScorePacket; import org.geysermc.geyser.scoreboard.Objective; import org.geysermc.geyser.scoreboard.Scoreboard; import org.geysermc.geyser.scoreboard.ScoreboardUpdater; @@ -34,6 +32,8 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.WorldCache; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.ScoreboardPosition; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.scoreboard.ClientboundResetScorePacket; @Translator(packet = ClientboundResetScorePacket.class) public class JavaResetScorePacket extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetDisplayObjectiveTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetDisplayObjectiveTranslator.java index 74f063e44..4ce971cdf 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetDisplayObjectiveTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetDisplayObjectiveTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.scoreboard; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.scoreboard.ClientboundSetDisplayObjectivePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.scoreboard.ClientboundSetDisplayObjectivePacket; import org.geysermc.geyser.scoreboard.Scoreboard; import org.geysermc.geyser.scoreboard.ScoreboardUpdater; import org.geysermc.geyser.session.GeyserSession; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetObjectiveTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetObjectiveTranslator.java index 75f7d38f2..85d93c0b5 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetObjectiveTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetObjectiveTranslator.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.translator.protocol.java.scoreboard; -import com.github.steveice10.mc.protocol.data.game.scoreboard.ObjectiveAction; -import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.scoreboard.ClientboundSetObjectivePacket; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.ObjectiveAction; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.ScoreboardPosition; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.scoreboard.ClientboundSetObjectivePacket; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.entity.type.player.PlayerEntity; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetPlayerTeamTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetPlayerTeamTranslator.java index f942b6f09..999edcc8c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetPlayerTeamTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetPlayerTeamTranslator.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.translator.protocol.java.scoreboard; -import com.github.steveice10.mc.protocol.data.game.scoreboard.NameTagVisibility; -import com.github.steveice10.mc.protocol.data.game.scoreboard.TeamAction; -import com.github.steveice10.mc.protocol.data.game.scoreboard.TeamColor; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.scoreboard.ClientboundSetPlayerTeamPacket; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.NameTagVisibility; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.TeamAction; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.TeamColor; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.scoreboard.ClientboundSetPlayerTeamPacket; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.scoreboard.Scoreboard; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetScoreTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetScoreTranslator.java index 6bffee3d3..d1645b496 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetScoreTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/scoreboard/JavaSetScoreTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.protocol.java.scoreboard; -import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.scoreboard.ClientboundSetScorePacket; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.ScoreboardPosition; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.scoreboard.ClientboundSetScorePacket; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserLogger; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaClearTitlesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaClearTitlesTranslator.java index 968845e92..8601ec7e9 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaClearTitlesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaClearTitlesTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.title; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.title.ClientboundClearTitlesPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.title.ClientboundClearTitlesPacket; import org.cloudburstmc.protocol.bedrock.packet.SetTitlePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetActionBarTextTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetActionBarTextTranslator.java index c2dfc85ff..5e3ba834b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetActionBarTextTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetActionBarTextTranslator.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.translator.protocol.java.title; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.title.ClientboundSetActionBarTextPacket; import org.cloudburstmc.protocol.bedrock.packet.SetTitlePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.translator.text.MessageTranslator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.title.ClientboundSetActionBarTextPacket; @Translator(packet = ClientboundSetActionBarTextPacket.class) public class JavaSetActionBarTextTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetSubtitleTextTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetSubtitleTextTranslator.java index ba0407dcb..44d0a1e63 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetSubtitleTextTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetSubtitleTextTranslator.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.translator.protocol.java.title; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.title.ClientboundSetSubtitleTextPacket; import org.cloudburstmc.protocol.bedrock.packet.SetTitlePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.translator.text.MessageTranslator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.title.ClientboundSetSubtitleTextPacket; @Translator(packet = ClientboundSetSubtitleTextPacket.class) public class JavaSetSubtitleTextTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetTitleTextTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetTitleTextTranslator.java index 1aa789ad4..d0ac15a73 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetTitleTextTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetTitleTextTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.title; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.title.ClientboundSetTitleTextPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.title.ClientboundSetTitleTextPacket; import org.cloudburstmc.protocol.bedrock.packet.SetTitlePacket; import net.kyori.adventure.text.Component; import org.geysermc.geyser.session.GeyserSession; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetTitlesAnimationTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetTitlesAnimationTranslator.java index 4299a0596..4bc5ba0c5 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetTitlesAnimationTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/title/JavaSetTitlesAnimationTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.protocol.java.title; -import com.github.steveice10.mc.protocol.packet.ingame.clientbound.title.ClientboundSetTitlesAnimationPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.title.ClientboundSetTitlesAnimationPacket; import org.cloudburstmc.protocol.bedrock.packet.SetTitlePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; diff --git a/core/src/main/java/org/geysermc/geyser/translator/sound/BlockSoundInteractionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/sound/BlockSoundInteractionTranslator.java index ef6be0e9d..ead619b68 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/sound/BlockSoundInteractionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/sound/BlockSoundInteractionTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.translator.sound; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; diff --git a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java index 604e34945..612b9c38b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.text; -import com.github.steveice10.mc.protocol.data.DefaultComponentSerializer; -import com.github.steveice10.mc.protocol.data.game.scoreboard.TeamColor; +import org.geysermc.mcprotocollib.protocol.data.DefaultComponentSerializer; +import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.TeamColor; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.ScoreComponent; import net.kyori.adventure.text.TranslatableComponent; diff --git a/core/src/main/java/org/geysermc/geyser/util/AttributeUtils.java b/core/src/main/java/org/geysermc/geyser/util/AttributeUtils.java index d79d606b4..af2faab94 100644 --- a/core/src/main/java/org/geysermc/geyser/util/AttributeUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/AttributeUtils.java @@ -25,9 +25,9 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.data.game.entity.attribute.Attribute; -import com.github.steveice10.mc.protocol.data.game.entity.attribute.AttributeModifier; -import com.github.steveice10.mc.protocol.data.game.entity.attribute.ModifierOperation; +import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.Attribute; +import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.AttributeModifier; +import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.ModifierOperation; public class AttributeUtils { /** diff --git a/core/src/main/java/org/geysermc/geyser/util/BlockEntityUtils.java b/core/src/main/java/org/geysermc/geyser/util/BlockEntityUtils.java index 31a2ddee9..ec7f45c8d 100644 --- a/core/src/main/java/org/geysermc/geyser/util/BlockEntityUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/BlockEntityUtils.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; @@ -35,6 +34,7 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.level.block.entity.BedrockOnlyBlockEntity; import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator; import org.geysermc.geyser.translator.level.block.entity.FlowerPotBlockEntityTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import java.util.List; import java.util.Locale; diff --git a/core/src/main/java/org/geysermc/geyser/util/BlockUtils.java b/core/src/main/java/org/geysermc/geyser/util/BlockUtils.java index 8392f9fcd..0fc7a39e7 100644 --- a/core/src/main/java/org/geysermc/geyser/util/BlockUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/BlockUtils.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3i; import org.geysermc.geyser.inventory.GeyserItemStack; @@ -38,6 +37,7 @@ import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.BlockTag; import org.geysermc.geyser.translator.collision.BlockCollision; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; public final class BlockUtils { @@ -181,7 +181,7 @@ public final class BlockUtils { /** * Given a position, return the position if a block were located on the specified block face. * @param blockPos the block position - * @param face the face of the block - see {@link com.github.steveice10.mc.protocol.data.game.entity.object.Direction} + * @param face the face of the block - see {@link org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction} * @return the block position with the block face accounted for */ public static Vector3i getBlockPosition(Vector3i blockPos, int face) { diff --git a/core/src/main/java/org/geysermc/geyser/util/CooldownUtils.java b/core/src/main/java/org/geysermc/geyser/util/CooldownUtils.java index 60838686f..c020e96b2 100644 --- a/core/src/main/java/org/geysermc/geyser/util/CooldownUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/CooldownUtils.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.util; -import org.cloudburstmc.protocol.bedrock.packet.SetTitlePacket; import lombok.Getter; +import org.cloudburstmc.protocol.bedrock.packet.SetTitlePacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.PreferencesCache; import org.geysermc.geyser.text.ChatColor; diff --git a/core/src/main/java/org/geysermc/geyser/util/DimensionUtils.java b/core/src/main/java/org/geysermc/geyser/util/DimensionUtils.java index 469accd40..54e1cc34a 100644 --- a/core/src/main/java/org/geysermc/geyser/util/DimensionUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/DimensionUtils.java @@ -25,18 +25,14 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.data.game.entity.Effect; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.PlayerActionType; -import org.cloudburstmc.protocol.bedrock.packet.ChangeDimensionPacket; -import org.cloudburstmc.protocol.bedrock.packet.ChunkRadiusUpdatedPacket; -import org.cloudburstmc.protocol.bedrock.packet.MobEffectPacket; -import org.cloudburstmc.protocol.bedrock.packet.PlayerActionPacket; -import org.cloudburstmc.protocol.bedrock.packet.StopSoundPacket; +import org.cloudburstmc.protocol.bedrock.packet.*; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.level.BedrockDimension; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.Effect; import java.util.Set; diff --git a/core/src/main/java/org/geysermc/geyser/util/EntityUtils.java b/core/src/main/java/org/geysermc/geyser/util/EntityUtils.java index f040fd0ba..d11c1f9e4 100644 --- a/core/src/main/java/org/geysermc/geyser/util/EntityUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/EntityUtils.java @@ -25,10 +25,6 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.data.game.entity.Effect; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; -import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.GameType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; @@ -41,6 +37,10 @@ import org.geysermc.geyser.entity.type.living.animal.AnimalEntity; import org.geysermc.geyser.entity.type.living.animal.horse.CamelEntity; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; +import org.geysermc.mcprotocollib.protocol.data.game.entity.Effect; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; import java.util.Locale; diff --git a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java index 2b619714e..63644d5fc 100644 --- a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java @@ -25,12 +25,6 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.item.ItemStack; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundPickItemPacket; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetCreativeModeSlotPacket; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; @@ -58,6 +52,12 @@ import org.geysermc.geyser.text.GeyserLocale; import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.geyser.translator.inventory.LecternInventoryTranslator; import org.geysermc.geyser.translator.inventory.chest.DoubleChestInventoryTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.Ingredient; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundPickItemPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSetCreativeModeSlotPacket; import org.jetbrains.annotations.Contract; import java.util.Arrays; diff --git a/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java b/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java index b1591e911..1b47c3a00 100644 --- a/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java @@ -25,14 +25,14 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType; -import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents; -import com.github.steveice10.mc.protocol.data.game.item.component.ItemEnchantments; import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.FishingRodItem; import org.geysermc.geyser.item.type.Item; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments; public class ItemUtils { diff --git a/core/src/main/java/org/geysermc/geyser/util/PluginMessageUtils.java b/core/src/main/java/org/geysermc/geyser/util/PluginMessageUtils.java index f6b91388f..09543baca 100644 --- a/core/src/main/java/org/geysermc/geyser/util/PluginMessageUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/PluginMessageUtils.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket; import com.google.common.base.Charsets; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket; import java.nio.ByteBuffer; diff --git a/core/src/main/java/org/geysermc/geyser/util/SoundUtils.java b/core/src/main/java/org/geysermc/geyser/util/SoundUtils.java index 4c5f6b68f..85f8fc704 100644 --- a/core/src/main/java/org/geysermc/geyser/util/SoundUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/SoundUtils.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.data.game.level.sound.Sound; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; @@ -39,6 +38,7 @@ import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.SoundMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.level.sound.Sound; import java.util.Locale; diff --git a/core/src/main/java/org/geysermc/geyser/util/StatisticFormatters.java b/core/src/main/java/org/geysermc/geyser/util/StatisticFormatters.java index d46a759fe..589bac043 100644 --- a/core/src/main/java/org/geysermc/geyser/util/StatisticFormatters.java +++ b/core/src/main/java/org/geysermc/geyser/util/StatisticFormatters.java @@ -25,7 +25,7 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.data.game.statistic.StatisticFormat; +import org.geysermc.mcprotocollib.protocol.data.game.statistic.StatisticFormat; import java.text.DecimalFormat; import java.text.NumberFormat; diff --git a/core/src/main/java/org/geysermc/geyser/util/StatisticsUtils.java b/core/src/main/java/org/geysermc/geyser/util/StatisticsUtils.java index aa174497b..96328bcdd 100644 --- a/core/src/main/java/org/geysermc/geyser/util/StatisticsUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/StatisticsUtils.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.data.game.statistic.*; import it.unimi.dsi.fastutil.objects.Object2IntMap; import org.geysermc.cumulus.form.SimpleForm; import org.geysermc.cumulus.util.FormImage; @@ -35,6 +34,7 @@ import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.GeyserLocale; import org.geysermc.geyser.text.MinecraftLocale; +import org.geysermc.mcprotocollib.protocol.data.game.statistic.*; import java.util.ArrayList; import java.util.List; diff --git a/core/src/main/java/org/geysermc/geyser/util/StructureBlockUtils.java b/core/src/main/java/org/geysermc/geyser/util/StructureBlockUtils.java index 9b3cfb53f..c1ccf9d5b 100644 --- a/core/src/main/java/org/geysermc/geyser/util/StructureBlockUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/StructureBlockUtils.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.util; -import com.github.steveice10.mc.protocol.data.game.inventory.UpdateStructureBlockAction; -import com.github.steveice10.mc.protocol.data.game.inventory.UpdateStructureBlockMode; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetStructureBlockPacket; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtList; import org.cloudburstmc.nbt.NbtMap; @@ -39,6 +36,9 @@ import org.cloudburstmc.protocol.bedrock.data.structure.StructureSettings; import org.cloudburstmc.protocol.bedrock.data.structure.StructureTemplateResponseType; import org.cloudburstmc.protocol.bedrock.packet.StructureTemplateDataResponsePacket; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.UpdateStructureBlockAction; +import org.geysermc.mcprotocollib.protocol.data.game.inventory.UpdateStructureBlockMode; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSetStructureBlockPacket; public class StructureBlockUtils { @@ -124,17 +124,17 @@ public class StructureBlockUtils { public static void sendJavaStructurePacket(GeyserSession session, Vector3i blockPosition, Vector3i size, UpdateStructureBlockMode mode, UpdateStructureBlockAction action, StructureSettings settings, boolean boundingBoxVisible, String structureName) { - com.github.steveice10.mc.protocol.data.game.level.block.StructureMirror mirror = switch (settings.getMirror()) { - case X -> com.github.steveice10.mc.protocol.data.game.level.block.StructureMirror.FRONT_BACK; - case Z -> com.github.steveice10.mc.protocol.data.game.level.block.StructureMirror.LEFT_RIGHT; - default -> com.github.steveice10.mc.protocol.data.game.level.block.StructureMirror.NONE; + org.geysermc.mcprotocollib.protocol.data.game.level.block.StructureMirror mirror = switch (settings.getMirror()) { + case X -> org.geysermc.mcprotocollib.protocol.data.game.level.block.StructureMirror.FRONT_BACK; + case Z -> org.geysermc.mcprotocollib.protocol.data.game.level.block.StructureMirror.LEFT_RIGHT; + default -> org.geysermc.mcprotocollib.protocol.data.game.level.block.StructureMirror.NONE; }; - com.github.steveice10.mc.protocol.data.game.level.block.StructureRotation rotation = switch (settings.getRotation()) { - case ROTATE_90 -> com.github.steveice10.mc.protocol.data.game.level.block.StructureRotation.CLOCKWISE_90; - case ROTATE_180 -> com.github.steveice10.mc.protocol.data.game.level.block.StructureRotation.CLOCKWISE_180; - case ROTATE_270 -> com.github.steveice10.mc.protocol.data.game.level.block.StructureRotation.COUNTERCLOCKWISE_90; - default -> com.github.steveice10.mc.protocol.data.game.level.block.StructureRotation.NONE; + org.geysermc.mcprotocollib.protocol.data.game.level.block.StructureRotation rotation = switch (settings.getRotation()) { + case ROTATE_90 -> org.geysermc.mcprotocollib.protocol.data.game.level.block.StructureRotation.CLOCKWISE_90; + case ROTATE_180 -> org.geysermc.mcprotocollib.protocol.data.game.level.block.StructureRotation.CLOCKWISE_180; + case ROTATE_270 -> org.geysermc.mcprotocollib.protocol.data.game.level.block.StructureRotation.COUNTERCLOCKWISE_90; + default -> org.geysermc.mcprotocollib.protocol.data.game.level.block.StructureRotation.NONE; }; Vector3i offset = settings.getOffset(); diff --git a/core/src/test/java/org/geysermc/geyser/network/translators/chat/MessageTranslatorTest.java b/core/src/test/java/org/geysermc/geyser/network/translators/chat/MessageTranslatorTest.java index 5e5c3af7a..85d7ffa9a 100644 --- a/core/src/test/java/org/geysermc/geyser/network/translators/chat/MessageTranslatorTest.java +++ b/core/src/test/java/org/geysermc/geyser/network/translators/chat/MessageTranslatorTest.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.network.translators.chat; -import com.github.steveice10.mc.protocol.data.DefaultComponentSerializer; import org.geysermc.geyser.translator.text.MessageTranslator; +import org.geysermc.mcprotocollib.protocol.data.DefaultComponentSerializer; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; diff --git a/core/src/test/java/org/geysermc/geyser/registry/loader/ResourcePackLoaderTest.java b/core/src/test/java/org/geysermc/geyser/registry/loader/ResourcePackLoaderTest.java index b66fd0811..ce2fd2a6f 100644 --- a/core/src/test/java/org/geysermc/geyser/registry/loader/ResourcePackLoaderTest.java +++ b/core/src/test/java/org/geysermc/geyser/registry/loader/ResourcePackLoaderTest.java @@ -34,9 +34,7 @@ import java.nio.file.Path; import java.nio.file.PathMatcher; import java.util.Objects; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; public class ResourcePackLoaderTest { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2b6df11a6..3cb136683 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "3c81cc80" # Revert from jitpack after release +mcprotocollib = "1ca8808" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From 9d540fe672e6f0887a58695ef870e3c2e8fe8eff Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Wed, 24 Apr 2024 16:41:02 -0400 Subject: [PATCH 102/272] Shulker box NPE fix --- .../main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java index 4108d0fa0..2f2f45c5b 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java @@ -59,7 +59,7 @@ public class ShulkerBoxItem extends BlockItem { List itemsList = new ArrayList<>(); for (int slot = 0; slot < contents.size(); slot++) { ItemStack item = contents.get(slot); - if (item.getId() == Items.AIR_ID) { + if (item == null || item.getId() == Items.AIR_ID) { continue; } ItemMapping boxMapping = session.getItemMappings().getMapping(item.getId()); From 652f6af7849d05ecbe6d3028eff77646b68d6301 Mon Sep 17 00:00:00 2001 From: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> Date: Wed, 24 Apr 2024 18:13:07 -0700 Subject: [PATCH 103/272] Fix custom skulls 1.20.5 Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> --- .../entity/SkullBlockEntityTranslator.java | 32 +++++++++---------- .../level/JavaBlockEntityDataTranslator.java | 2 +- .../JavaLevelChunkWithLightTranslator.java | 3 +- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java index 61c922528..38a056bd0 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java @@ -66,8 +66,8 @@ public class SkullBlockEntityTranslator extends BlockEntityTranslator implements } } - private static UUID getUUID(CompoundTag owner) { - if (owner.get("Id") instanceof IntArrayTag uuidTag && uuidTag.length() == 4) { + private static UUID getUUID(CompoundTag profile) { + if (profile.get("id") instanceof IntArrayTag uuidTag && uuidTag.length() == 4) { int[] uuidAsArray = uuidTag.getValue(); // thank u viaversion return new UUID((long) uuidAsArray[0] << 32 | ((long) uuidAsArray[1] & 0xFFFFFFFFL), @@ -75,46 +75,44 @@ public class SkullBlockEntityTranslator extends BlockEntityTranslator implements } // Convert username to an offline UUID String username = null; - if (owner.get("Name") instanceof StringTag nameTag) { + if (profile.get("name") instanceof StringTag nameTag) { username = nameTag.getValue().toLowerCase(Locale.ROOT); } return UUID.nameUUIDFromBytes(("OfflinePlayer:" + username).getBytes(StandardCharsets.UTF_8)); } - private static CompletableFuture getTextures(CompoundTag owner, UUID uuid) { - CompoundTag properties = owner.get("Properties"); + private static CompletableFuture getTextures(CompoundTag profile, UUID uuid) { + ListTag properties = profile.get("properties"); if (properties == null) { if (uuid != null && uuid.version() == 4) { String uuidString = uuid.toString().replace("-", ""); return SkinProvider.requestTexturesFromUUID(uuidString); - } else if (owner.get("Name") instanceof StringTag nameTag) { + } else if (profile.get("name") instanceof StringTag nameTag) { // Fall back to username if UUID was missing or was an offline mode UUID return SkinProvider.requestTexturesFromUsername(nameTag.getValue()); } return CompletableFuture.completedFuture(null); } - ListTag textures = properties.get("textures"); - LinkedHashMap tag1 = (LinkedHashMap) textures.get(0).getValue(); - StringTag texture = (StringTag) tag1.get("Value"); + LinkedHashMap tag1 = (LinkedHashMap) properties.get(0).getValue(); + StringTag texture = (StringTag) tag1.get("value"); return CompletableFuture.completedFuture(texture.getValue()); } public static @Nullable BlockDefinition translateSkull(GeyserSession session, CompoundTag tag, Vector3i blockPosition, int blockState) { - // TODO: The tag layout follows new format (profille, etc...) - CompoundTag owner = tag.get("SkullOwner"); - if (owner == null) { + CompoundTag profile = tag.get("profile"); + if (profile == null) { session.getSkullCache().removeSkull(blockPosition); return null; } - UUID uuid = getUUID(owner); + UUID uuid = getUUID(profile); - CompletableFuture texturesFuture = getTextures(owner, uuid); + CompletableFuture texturesFuture = getTextures(profile, uuid); if (texturesFuture.isDone()) { try { String texture = texturesFuture.get(); if (texture == null) { - session.getGeyser().getLogger().debug("Custom skull with invalid SkullOwner tag: " + blockPosition + " " + tag); + session.getGeyser().getLogger().debug("Custom skull with invalid profile tag: " + blockPosition + " " + tag); return null; } SkullCache.Skull skull = session.getSkullCache().putSkull(blockPosition, uuid, texture, blockState); @@ -128,10 +126,10 @@ public class SkullBlockEntityTranslator extends BlockEntityTranslator implements return null; } - // SkullOwner contained a username, so we have to wait for it to be retrieved + // profile contained a username, so we have to wait for it to be retrieved texturesFuture.whenComplete((texturesProperty, throwable) -> { if (texturesProperty == null) { - session.getGeyser().getLogger().debug("Custom skull with invalid SkullOwner tag: " + blockPosition + " " + tag); + session.getGeyser().getLogger().debug("Custom skull with invalid profile tag: " + blockPosition + " " + tag); return; } if (session.getEventLoop().inEventLoop()) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java index ca746f79b..82b51dfdd 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java @@ -71,7 +71,7 @@ public class JavaBlockEntityDataTranslator extends PacketTranslator> 4) - (bedrockDimension.minY() >> 4); From 99e6a2981da27a9ec8f09c04cfc8e73a296e4263 Mon Sep 17 00:00:00 2001 From: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> Date: Thu, 25 Apr 2024 01:33:18 -0700 Subject: [PATCH 104/272] Entity properties Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> --- .../geyser/entity/EntityDefinition.java | 19 +- .../geyser/entity/EntityDefinitions.java | 15 +- .../properties/GeyserEntityProperties.java | 165 ++++++++++++++++++ .../GeyserEntityPropertyManager.java | 98 +++++++++++ .../properties/type/BooleanProperty.java | 44 +++++ .../entity/properties/type/EnumProperty.java | 61 +++++++ .../entity/properties/type/FloatProperty.java | 50 ++++++ .../entity/properties/type/IntProperty.java | 50 ++++++ .../entity/properties/type/PropertyType.java | 32 ++++ .../geysermc/geyser/entity/type/Entity.java | 22 +++ .../type/living/animal/ArmadilloEntity.java | 18 +- .../entity/type/living/animal/BeeEntity.java | 3 +- .../geysermc/geyser/registry/Registries.java | 5 + .../geyser/session/GeyserSession.java | 12 ++ 14 files changed, 587 insertions(+), 7 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/entity/properties/GeyserEntityProperties.java create mode 100644 core/src/main/java/org/geysermc/geyser/entity/properties/GeyserEntityPropertyManager.java create mode 100644 core/src/main/java/org/geysermc/geyser/entity/properties/type/BooleanProperty.java create mode 100644 core/src/main/java/org/geysermc/geyser/entity/properties/type/EnumProperty.java create mode 100644 core/src/main/java/org/geysermc/geyser/entity/properties/type/FloatProperty.java create mode 100644 core/src/main/java/org/geysermc/geyser/entity/properties/type/IntProperty.java create mode 100644 core/src/main/java/org/geysermc/geyser/entity/properties/type/PropertyType.java diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinition.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinition.java index f0e221bad..31aa7cc73 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinition.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinition.java @@ -33,6 +33,7 @@ import lombok.Setter; import lombok.experimental.Accessors; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.entity.factory.EntityFactory; +import org.geysermc.geyser.entity.properties.GeyserEntityProperties; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.translator.entity.EntityMetadataTranslator; @@ -49,10 +50,10 @@ import java.util.function.BiConsumer; * @param the entity type this definition represents */ public record EntityDefinition(EntityFactory factory, EntityType entityType, String identifier, - float width, float height, float offset, List> translators) { + float width, float height, float offset, GeyserEntityProperties registeredProperties, List> translators) { public static Builder inherited(EntityFactory factory, EntityDefinition parent) { - return new Builder<>(factory, parent.entityType, parent.identifier, parent.width, parent.height, parent.offset, new ObjectArrayList<>(parent.translators)); + return new Builder<>(factory, parent.entityType, parent.identifier, parent.width, parent.height, parent.offset, parent.registeredProperties, new ObjectArrayList<>(parent.translators)); } public static Builder builder(EntityFactory factory) { @@ -87,6 +88,7 @@ public record EntityDefinition(EntityFactory factory, Entit private float width; private float height; private float offset = 0.00001f; + private GeyserEntityProperties registeredProperties; private final List> translators; private Builder(EntityFactory factory) { @@ -94,13 +96,14 @@ public record EntityDefinition(EntityFactory factory, Entit translators = new ObjectArrayList<>(); } - public Builder(EntityFactory factory, EntityType type, String identifier, float width, float height, float offset, List> translators) { + public Builder(EntityFactory factory, EntityType type, String identifier, float width, float height, float offset, GeyserEntityProperties registeredProperties, List> translators) { this.factory = factory; this.type = type; this.identifier = identifier; this.width = width; this.height = height; this.offset = offset; + this.registeredProperties = registeredProperties; this.translators = translators; } @@ -127,6 +130,11 @@ public record EntityDefinition(EntityFactory factory, Entit return this; } + public Builder properties(GeyserEntityProperties registeredProperties) { + this.registeredProperties = registeredProperties; + return this; + } + public >> Builder addTranslator(MetadataType type, BiConsumer translateFunction) { translators.add(new EntityMetadataTranslator<>(type, translateFunction)); return this; @@ -149,10 +157,13 @@ public record EntityDefinition(EntityFactory factory, Entit if (identifier == null && type != null) { identifier = "minecraft:" + type.name().toLowerCase(Locale.ROOT); } - EntityDefinition definition = new EntityDefinition<>(factory, type, identifier, width, height, offset, translators); + EntityDefinition definition = new EntityDefinition<>(factory, type, identifier, width, height, offset, registeredProperties, translators); if (register && definition.entityType() != null) { Registries.ENTITY_DEFINITIONS.get().putIfAbsent(definition.entityType(), definition); Registries.JAVA_ENTITY_IDENTIFIERS.get().putIfAbsent("minecraft:" + type.name().toLowerCase(Locale.ROOT), definition); + if (definition.registeredProperties() != null) { + Registries.BEDROCK_ENTITY_PROPERTIES.get().add(definition.registeredProperties().toNbtMap(identifier)); + } } return definition; } diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index 328dd4bbf..317892676 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -31,6 +31,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatE import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; +import org.geysermc.geyser.entity.properties.GeyserEntityProperties; import org.geysermc.geyser.entity.type.*; import org.geysermc.geyser.entity.type.living.*; import org.geysermc.geyser.entity.type.living.animal.*; @@ -774,7 +775,16 @@ public final class EntityDefinitions { ARMADILLO = EntityDefinition.inherited(ArmadilloEntity::new, ageableEntityBase) .type(EntityType.ARMADILLO) .height(0.65f).width(0.7f) - .addTranslator(null) + .properties(new GeyserEntityProperties.Builder() + .addEnum( + "minecraft:armadillo_state", + "unrolled", + "rolled_up", + "rolled_up_peeking", + "rolled_up_relaxing", + "rolled_up_unrolling") + .build()) + .addTranslator(MetadataType.ARMADILLO_STATE, ArmadilloEntity::setArmadilloState) .build(); AXOLOTL = EntityDefinition.inherited(AxolotlEntity::new, ageableEntityBase) .type(EntityType.AXOLOTL) @@ -786,6 +796,9 @@ public final class EntityDefinitions { BEE = EntityDefinition.inherited(BeeEntity::new, ageableEntityBase) .type(EntityType.BEE) .heightAndWidth(0.6f) + .properties(new GeyserEntityProperties.Builder() + .addBoolean("minecraft:has_nectar") + .build()) .addTranslator(MetadataType.BYTE, BeeEntity::setBeeFlags) .addTranslator(MetadataType.INT, BeeEntity::setAngerTime) .build(); diff --git a/core/src/main/java/org/geysermc/geyser/entity/properties/GeyserEntityProperties.java b/core/src/main/java/org/geysermc/geyser/entity/properties/GeyserEntityProperties.java new file mode 100644 index 000000000..1729b0583 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/entity/properties/GeyserEntityProperties.java @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.entity.properties; + +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.nbt.NbtType; +import org.geysermc.geyser.entity.properties.type.BooleanProperty; +import org.geysermc.geyser.entity.properties.type.EnumProperty; +import org.geysermc.geyser.entity.properties.type.FloatProperty; +import org.geysermc.geyser.entity.properties.type.IntProperty; +import org.geysermc.geyser.entity.properties.type.PropertyType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +@EqualsAndHashCode +@ToString +public class GeyserEntityProperties { + private final ObjectArrayList properties; + private final Object2IntMap propertyIndices; + + private GeyserEntityProperties(ObjectArrayList properties, + Object2IntMap propertyIndices) { + this.properties = properties; + this.propertyIndices = propertyIndices; + } + + public NbtMap toNbtMap(String entityType) { + NbtMapBuilder mapBuilder = NbtMap.builder(); + List nbtProperties = new ArrayList<>(); + + for (PropertyType property : properties) { + nbtProperties.add(property.nbtMap()); + } + mapBuilder.putList("properties", NbtType.COMPOUND, nbtProperties); + + return mapBuilder.putString("type", entityType).build(); + } + + public @NonNull List getProperties() { + return properties; + } + + public int getPropertyIndex(String name) { + return propertyIndices.getOrDefault(name, -1); + } + + public static class Builder { + private final ObjectArrayList properties = new ObjectArrayList<>(); + private final Object2IntMap propertyIndices = new Object2IntOpenHashMap<>(); + + public Builder addInt(@NonNull String name, int min, int max) { + if (propertyIndices.containsKey(name)) { + throw new IllegalArgumentException( + "Property with name " + name + " already exists on builder!"); + } + PropertyType property = new IntProperty(name, min, max); + this.properties.add(property); + propertyIndices.put(name, properties.size() - 1); + return this; + } + + public Builder addInt(@NonNull String name) { + if (propertyIndices.containsKey(name)) { + throw new IllegalArgumentException( + "Property with name " + name + " already exists on builder!"); + } + PropertyType property = new IntProperty(name, Integer.MIN_VALUE, Integer.MAX_VALUE); + this.properties.add(property); + propertyIndices.put(name, properties.size() - 1); + return this; + } + + public Builder addFloat(@NonNull String name, float min, float max) { + if (propertyIndices.containsKey(name)) { + throw new IllegalArgumentException( + "Property with name " + name + " already exists on builder!"); + } + PropertyType property = new FloatProperty(name, min, max); + this.properties.add(property); + propertyIndices.put(name, properties.size() - 1); + return this; + } + + public Builder addFloat(@NonNull String name) { + if (propertyIndices.containsKey(name)) { + throw new IllegalArgumentException( + "Property with name " + name + " already exists on builder!"); + } + PropertyType property = new FloatProperty(name, Float.MIN_NORMAL, Float.MAX_VALUE); + this.properties.add(property); + propertyIndices.put(name, properties.size() - 1); + return this; + } + + public Builder addBoolean(@NonNull String name) { + if (propertyIndices.containsKey(name)) { + throw new IllegalArgumentException( + "Property with name " + name + " already exists on builder!"); + } + PropertyType property = new BooleanProperty(name); + this.properties.add(property); + propertyIndices.put(name, properties.size() - 1); + return this; + } + + public Builder addEnum(@NonNull String name, List values) { + if (propertyIndices.containsKey(name)) { + throw new IllegalArgumentException( + "Property with name " + name + " already exists on builder!"); + } + PropertyType property = new EnumProperty(name, values); + this.properties.add(property); + propertyIndices.put(name, properties.size() - 1); + return this; + } + + public Builder addEnum(@NonNull String name, String... values) { + if (propertyIndices.containsKey(name)) { + throw new IllegalArgumentException( + "Property with name " + name + " already exists on builder!"); + } + List valuesList = Arrays.asList(values); // Convert array to list + PropertyType property = new EnumProperty(name, valuesList); + this.properties.add(property); + propertyIndices.put(name, properties.size() - 1); + return this; + } + + public GeyserEntityProperties build() { + return new GeyserEntityProperties(properties, propertyIndices); + } + } +} \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/entity/properties/GeyserEntityPropertyManager.java b/core/src/main/java/org/geysermc/geyser/entity/properties/GeyserEntityPropertyManager.java new file mode 100644 index 000000000..29026b172 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/entity/properties/GeyserEntityPropertyManager.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.entity.properties; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.cloudburstmc.protocol.bedrock.data.entity.FloatEntityProperty; +import org.cloudburstmc.protocol.bedrock.data.entity.IntEntityProperty; +import org.geysermc.geyser.entity.properties.type.EnumProperty; +import org.geysermc.geyser.entity.properties.type.PropertyType; + +import java.util.List; + +public class GeyserEntityPropertyManager { + + private final GeyserEntityProperties properties; + + private final ObjectArrayList intEntityProperties = new ObjectArrayList<>(); + private final ObjectArrayList floatEntityProperties = new ObjectArrayList<>(); + + public GeyserEntityPropertyManager(GeyserEntityProperties properties) { + this.properties = properties; + } + + public void add(String propertyName, int value) { + int index = properties.getPropertyIndex(propertyName); + intEntityProperties.add(new IntEntityProperty(index, value)); + } + + public void add(String propertyName, boolean value) { + int index = properties.getPropertyIndex(propertyName); + intEntityProperties.add(new IntEntityProperty(index, value ? 1 : 0)); + } + + public void add(String propertyName, String value) { + int index = properties.getPropertyIndex(propertyName); + PropertyType property = properties.getProperties().get(index); + int enumIndex = ((EnumProperty) property).getIndex(value); + intEntityProperties.add(new IntEntityProperty(index, enumIndex)); + } + + public void add(String propertyName, float value) { + int index = properties.getPropertyIndex(propertyName); + floatEntityProperties.add(new FloatEntityProperty(index, value)); + } + + public boolean hasFloatProperties() { + return !this.floatEntityProperties.isEmpty(); + } + + public boolean hasIntProperties() { + return !this.intEntityProperties.isEmpty(); + } + + public boolean hasProperties() { + return hasFloatProperties() || hasIntProperties(); + } + + public ObjectArrayList intProperties() { + return this.intEntityProperties; + } + + public void applyIntProperties(List properties) { + properties.addAll(intEntityProperties); + intEntityProperties.clear(); + } + + public ObjectArrayList floatProperties() { + return this.floatEntityProperties; + } + + public void applyFloatProperties(List properties) { + properties.addAll(floatEntityProperties); + floatEntityProperties.clear(); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/entity/properties/type/BooleanProperty.java b/core/src/main/java/org/geysermc/geyser/entity/properties/type/BooleanProperty.java new file mode 100644 index 000000000..6fc64ad4b --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/entity/properties/type/BooleanProperty.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.entity.properties.type; + +import org.cloudburstmc.nbt.NbtMap; + +public class BooleanProperty implements PropertyType { + private final String name; + + public BooleanProperty(String name) { + this.name = name; + } + + @Override + public NbtMap nbtMap() { + return NbtMap.builder() + .putString("name", name) + .putInt("type", 2) + .build(); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/entity/properties/type/EnumProperty.java b/core/src/main/java/org/geysermc/geyser/entity/properties/type/EnumProperty.java new file mode 100644 index 000000000..9bc45f560 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/entity/properties/type/EnumProperty.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.entity.properties.type; + +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtType; + +import java.util.List; + +public class EnumProperty implements PropertyType { + private final String name; + private final List values; + private final Object2IntMap valueIndexMap; + + public EnumProperty(String name, List values) { + this.name = name; + this.values = values; + this.valueIndexMap = new Object2IntOpenHashMap<>(values.size()); + for (int i = 0; i < values.size(); i++) { + valueIndexMap.put(values.get(i), i); + } + } + + @Override + public NbtMap nbtMap() { + return NbtMap.builder() + .putString("name", name) + .putList("values", NbtType.STRING, values) + .putInt("type", 3) + .build(); + } + + public int getIndex(String value) { + return valueIndexMap.getOrDefault(value, -1); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/entity/properties/type/FloatProperty.java b/core/src/main/java/org/geysermc/geyser/entity/properties/type/FloatProperty.java new file mode 100644 index 000000000..8b808ebc3 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/entity/properties/type/FloatProperty.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.entity.properties.type; + +import org.cloudburstmc.nbt.NbtMap; + +public class FloatProperty implements PropertyType { + private final String name; + private final float max; + private final float min; + + public FloatProperty(String name, float min, float max) { + this.name = name; + this.max = max; + this.min = min; + } + + @Override + public NbtMap nbtMap() { + return NbtMap.builder() + .putString("name", name) + .putFloat("max", max) + .putFloat("min", min) + .putInt("type", 1) + .build(); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/entity/properties/type/IntProperty.java b/core/src/main/java/org/geysermc/geyser/entity/properties/type/IntProperty.java new file mode 100644 index 000000000..9e38db7c7 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/entity/properties/type/IntProperty.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.entity.properties.type; + +import org.cloudburstmc.nbt.NbtMap; + +public class IntProperty implements PropertyType { + private final String name; + private final int max; + private final int min; + + public IntProperty(String name, int min, int max) { + this.name = name; + this.max = max; + this.min = min; + } + + @Override + public NbtMap nbtMap() { + return NbtMap.builder() + .putString("name", name) + .putInt("max", max) + .putInt("min", min) + .putInt("type", 0) + .build(); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/entity/properties/type/PropertyType.java b/core/src/main/java/org/geysermc/geyser/entity/properties/type/PropertyType.java new file mode 100644 index 000000000..a64d7246a --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/entity/properties/type/PropertyType.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.entity.properties.type; + +import org.cloudburstmc.nbt.NbtMap; + +public interface PropertyType { + NbtMap nbtMap(); +} \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java index f1d6bfb98..fecd72f67 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java @@ -39,6 +39,7 @@ import org.cloudburstmc.protocol.bedrock.packet.*; import org.geysermc.geyser.api.entity.type.GeyserEntity; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.GeyserDirtyMetadata; +import org.geysermc.geyser.entity.properties.GeyserEntityPropertyManager; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.util.EntityUtils; @@ -117,6 +118,8 @@ public class Entity implements GeyserEntity { @Setter(AccessLevel.PROTECTED) // For players private boolean flagsDirty = false; + protected final GeyserEntityPropertyManager propertyManager; + public Entity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { this.session = session; @@ -131,6 +134,8 @@ public class Entity implements GeyserEntity { this.valid = false; + this.propertyManager = new GeyserEntityPropertyManager(definition.registeredProperties()); + setPosition(position); setAirSupply(getMaxAir()); @@ -348,6 +353,23 @@ public class Entity implements GeyserEntity { } } + /** + * Sends the Bedrock entity properties to the client + */ + public void updateBedrockEntityProperties() { + if (!valid) { + return; + } + + if (propertyManager.hasProperties()) { + SetEntityDataPacket entityDataPacket = new SetEntityDataPacket(); + entityDataPacket.setRuntimeEntityId(geyserId); + propertyManager.applyIntProperties(entityDataPacket.getProperties().getIntProperties()); + propertyManager.applyFloatProperties(entityDataPacket.getProperties().getFloatProperties()); + session.sendUpstreamPacket(entityDataPacket); + } + } + public void setFlags(ByteEntityMetadata entityMetadata) { byte xd = entityMetadata.getPrimitiveValue(); setFlag(EntityFlag.ON_FIRE, ((xd & 0x01) == 0x01) && !getFlag(EntityFlag.FIRE_IMMUNE)); // Otherwise immune entities sometimes flicker onfire diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java index d89b4e3f7..205c8cbd9 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java @@ -28,11 +28,27 @@ package org.geysermc.geyser.entity.type.living.animal; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.ArmadilloState; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; import java.util.UUID; public class ArmadilloEntity extends AnimalEntity { - public ArmadilloEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { + public ArmadilloEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, + EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); } + + // TODO: This is completely wrong; probably need to store the previous IDLE/ROLLING/SCARED state and check for transitions (pain) + public void setArmadilloState(ObjectEntityMetadata entityMetadata) { + ArmadilloState armadilloState = entityMetadata.getValue(); + + switch (armadilloState) { + case IDLE -> propertyManager.add("minecraft:armadillo_state", "unrolled"); + case ROLLING -> propertyManager.add("minecraft:armadillo_state", "rolled_up"); + case SCARED -> propertyManager.add("minecraft:armadillo_state", "rolled_up_peeking"); + } + + updateBedrockEntityProperties(); + } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java index d6aa9615d..28ebad473 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java @@ -58,7 +58,8 @@ public class BeeEntity extends AnimalEntity { // If the bee has stung dirtyMetadata.put(EntityDataTypes.MARK_VARIANT, (xd & 0x04) == 0x04 ? 1 : 0); // If the bee has nectar or not - setFlag(EntityFlag.POWERED, (xd & 0x08) == 0x08); + propertyManager.add("minecraft:has_nectar", (xd & 0x08) == 0x08); + updateBedrockEntityProperties(); } public void setAngerTime(IntEntityMetadata entityMetadata) { diff --git a/core/src/main/java/org/geysermc/geyser/registry/Registries.java b/core/src/main/java/org/geysermc/geyser/registry/Registries.java index f19898016..54d013140 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/Registries.java +++ b/core/src/main/java/org/geysermc/geyser/registry/Registries.java @@ -112,6 +112,11 @@ public final class Registries { */ public static final SimpleMappedRegistry> ENTITY_DEFINITIONS = SimpleMappedRegistry.create(RegistryLoaders.empty(() -> new EnumMap<>(EntityType.class))); + /** + * A registry holding a list of all the known entity properties to be sent to the client after start game. + */ + public static final SimpleRegistry> BEDROCK_ENTITY_PROPERTIES = SimpleRegistry.create(RegistryLoaders.empty(HashSet::new)); + /** * A map containing all Java entity identifiers and their respective Geyser definitions */ diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 82717050f..175d9eac2 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -638,6 +638,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { public void connect() { startGame(); sentSpawnPacket = true; + syncEntityProperties(); // Set the hardcoded shield ID to the ID we just defined in StartGamePacket // upstream.getSession().getHardcodedBlockingId().set(this.itemMappings.getStoredItems().shield().getBedrockId()); @@ -1562,9 +1563,20 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { startGamePacket.setRewindHistorySize(0); startGamePacket.setServerAuthoritativeBlockBreaking(false); + // Entity properties for older versions + startGamePacket.getExperiments().add(new ExperimentData("upcoming_creator_features", true)); + upstream.sendPacket(startGamePacket); } + private void syncEntityProperties() { + for (NbtMap nbtMap : Registries.BEDROCK_ENTITY_PROPERTIES.get()) { + SyncEntityPropertyPacket syncEntityPropertyPacket = new SyncEntityPropertyPacket(); + syncEntityPropertyPacket.setData(nbtMap); + upstream.sendPacket(syncEntityPropertyPacket); + } + } + /** * @return the next Bedrock item network ID to use for a new item */ From 16cb76f52338293f0599c682c1a3674d125a832b Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Thu, 25 Apr 2024 17:38:03 +0200 Subject: [PATCH 105/272] neoforge 1.20.5 boots --- .../main/resources/META-INF/{mods.toml => neoforge.mods.toml} | 2 +- build-logic/src/main/kotlin/geyser.base-conventions.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename bootstrap/mod/neoforge/src/main/resources/META-INF/{mods.toml => neoforge.mods.toml} (91%) diff --git a/bootstrap/mod/neoforge/src/main/resources/META-INF/mods.toml b/bootstrap/mod/neoforge/src/main/resources/META-INF/neoforge.mods.toml similarity index 91% rename from bootstrap/mod/neoforge/src/main/resources/META-INF/mods.toml rename to bootstrap/mod/neoforge/src/main/resources/META-INF/neoforge.mods.toml index 1110568e8..ff2823aa2 100644 --- a/bootstrap/mod/neoforge/src/main/resources/META-INF/mods.toml +++ b/bootstrap/mod/neoforge/src/main/resources/META-INF/neoforge.mods.toml @@ -20,6 +20,6 @@ config = "geyser.mixins.json" [[dependencies.geyser_neoforge]] modId="minecraft" type="required" - versionRange="[1.20.4,1.21)" + versionRange="[1.20.5,1.21)" ordering="NONE" side="BOTH" \ No newline at end of file diff --git a/build-logic/src/main/kotlin/geyser.base-conventions.gradle.kts b/build-logic/src/main/kotlin/geyser.base-conventions.gradle.kts index 3d41a3dd6..950c0184b 100644 --- a/build-logic/src/main/kotlin/geyser.base-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/geyser.base-conventions.gradle.kts @@ -23,7 +23,7 @@ indra { tasks { processResources { // Spigot, BungeeCord, Velocity, Fabric, ViaProxy, NeoForge - filesMatching(listOf("plugin.yml", "bungee.yml", "velocity-plugin.json", "fabric.mod.json", "viaproxy.yml", "META-INF/mods.toml")) { + filesMatching(listOf("plugin.yml", "bungee.yml", "velocity-plugin.json", "fabric.mod.json", "viaproxy.yml", "META-INF/neoforge.mods.toml")) { expand( "id" to "geyser", "name" to "Geyser", From 8e3a3ea45337d44bec2b3af8dbfaa615c9a01a7a Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Fri, 26 Apr 2024 01:00:14 +0200 Subject: [PATCH 106/272] implement curse of binding check for wolf armor removal --- .../geyser/entity/type/LivingEntity.java | 38 +++++++++++++++++-- .../entity/type/living/ArmorStandEntity.java | 17 +++++---- .../living/animal/tameable/WolfEntity.java | 15 +++++++- .../type/living/monster/PiglinEntity.java | 2 +- .../living/monster/raid/PillagerEntity.java | 2 +- .../translator/item/ItemTranslator.java | 8 ++-- .../entity/JavaEntityEventTranslator.java | 7 +--- .../entity/JavaSetEquipmentTranslator.java | 22 +++++------ .../org/geysermc/geyser/util/BlockUtils.java | 4 +- .../org/geysermc/geyser/util/ItemUtils.java | 5 ++- 10 files changed, 81 insertions(+), 39 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java index 5823ba3b2..b1e97a0d6 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java @@ -47,6 +47,7 @@ import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.util.AttributeUtils; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.Attribute; @@ -57,6 +58,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEn import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import java.util.*; @@ -69,7 +71,7 @@ public class LivingEntity extends Entity { protected ItemData leggings = ItemData.AIR; protected ItemData boots = ItemData.AIR; protected ItemData hand = ItemData.AIR; - protected ItemData offHand = ItemData.AIR; + protected ItemData offhand = ItemData.AIR; @Getter(value = AccessLevel.NONE) protected float health = 1f; // The default value in Java Edition before any entity metadata is sent @@ -85,6 +87,36 @@ public class LivingEntity extends Entity { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); } + public void setHelmet(ItemStack stack) { + this.helmet = ItemTranslator.translateToBedrock(session, stack); + } + + public void setChestplate(ItemStack stack) { + this.chestplate = ItemTranslator.translateToBedrock(session, stack); + } + + public void setLeggings(ItemStack stack) { + this.leggings = ItemTranslator.translateToBedrock(session, stack); + } + + public void setBoots(ItemStack stack) { + this.boots = ItemTranslator.translateToBedrock(session, stack); + } + + public void setHand(ItemStack stack) { + this.hand = ItemTranslator.translateToBedrock(session, stack); + } + + public void setOffhand(ItemStack stack) { + this.offhand = ItemTranslator.translateToBedrock(session, stack); + } + + public void switchHands() { + ItemData offhand = this.offhand; + this.offhand = this.hand; + this.hand = offhand; + } + @Override protected void initializeMetadata() { super.initializeMetadata(); @@ -135,7 +167,7 @@ public class LivingEntity extends Entity { protected boolean hasShield(boolean offhand) { ItemMapping shieldMapping = session.getItemMappings().getStoredItems().shield(); if (offhand) { - return offHand.getDefinition().equals(shieldMapping.getBedrockDefinition()); + return this.offhand.getDefinition().equals(shieldMapping.getBedrockDefinition()); } else { return hand.getDefinition().equals(shieldMapping.getBedrockDefinition()); } @@ -247,7 +279,7 @@ public class LivingEntity extends Entity { MobEquipmentPacket offHandPacket = new MobEquipmentPacket(); offHandPacket.setRuntimeEntityId(geyserId); - offHandPacket.setItem(offHand); + offHandPacket.setItem(offhand); offHandPacket.setHotbarSlot(-1); offHandPacket.setInventorySlot(0); offHandPacket.setContainerId(ContainerId.OFFHAND); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java index c64f2f218..fce51e741 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java @@ -43,6 +43,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetad import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import java.util.Optional; import java.util.UUID; @@ -257,38 +258,38 @@ public class ArmorStandEntity extends LivingEntity { } @Override - public void setHelmet(ItemData helmet) { + public void setHelmet(ItemStack helmet) { super.setHelmet(helmet); updateSecondEntityStatus(true); } @Override - public void setChestplate(ItemData chestplate) { + public void setChestplate(ItemStack chestplate) { super.setChestplate(chestplate); updateSecondEntityStatus(true); } @Override - public void setLeggings(ItemData leggings) { + public void setLeggings(ItemStack leggings) { super.setLeggings(leggings); updateSecondEntityStatus(true); } @Override - public void setBoots(ItemData boots) { + public void setBoots(ItemStack boots) { super.setBoots(boots); updateSecondEntityStatus(true); } @Override - public void setHand(ItemData hand) { + public void setHand(ItemStack hand) { super.setHand(hand); updateSecondEntityStatus(true); } @Override - public void setOffHand(ItemData offHand) { - super.setOffHand(offHand); + public void setOffhand(ItemStack offHand) { + super.setOffhand(offHand); updateSecondEntityStatus(true); } @@ -324,7 +325,7 @@ public class ArmorStandEntity extends LivingEntity { } boolean isNametagEmpty = nametag.isEmpty(); if (!isNametagEmpty && (!helmet.equals(ItemData.AIR) || !chestplate.equals(ItemData.AIR) || !leggings.equals(ItemData.AIR) - || !boots.equals(ItemData.AIR) || !hand.equals(ItemData.AIR) || !offHand.equals(ItemData.AIR))) { + || !boots.equals(ItemData.AIR) || !hand.equals(ItemData.AIR) || !offhand.equals(ItemData.AIR))) { // Reset scale of the proper armor stand this.dirtyMetadata.put(EntityDataTypes.SCALE, getScale()); // Set the proper armor stand to invisible to show armor diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java index 29c3526fe..833d0e175 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java @@ -33,15 +33,19 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; +import org.geysermc.geyser.inventory.item.Enchantment; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.DyeItem; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.geyser.util.ItemUtils; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import java.util.Collections; import java.util.Locale; @@ -60,6 +64,8 @@ public class WolfEntity extends TameableEntity { private byte collarColor = 14; // Red - default + private boolean isCurseOfBinding = false; + public WolfEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); } @@ -119,6 +125,12 @@ public class WolfEntity extends TameableEntity { return WOLF_FOODS.contains(item) && !isBaby(); } + @Override + public void setChestplate(ItemStack stack) { + super.setChestplate(stack); + isCurseOfBinding = ItemUtils.getEnchantmentLevel(stack.getDataComponents(), Enchantment.JavaEnchantment.BINDING_CURSE) > 0; + } + @Override protected boolean canBeLeashed() { return !getFlag(EntityFlag.ANGRY) && super.canBeLeashed(); @@ -146,7 +158,8 @@ public class WolfEntity extends TameableEntity { if (itemInHand.asItem() == Items.WOLF_ARMOR && !this.chestplate.isValid() && !getFlag(EntityFlag.BABY)) { return InteractiveTag.EQUIP_WOLF_ARMOR; } - if (itemInHand.asItem() == Items.SHEARS && this.chestplate.isValid()) { // TODO: check curse of binding + if (itemInHand.asItem() == Items.SHEARS && this.chestplate.isValid() + && (!isCurseOfBinding || session.getGameMode().equals(GameMode.CREATIVE))) { return InteractiveTag.REMOVE_WOLF_ARMOR; } if (Items.WOLF_ARMOR.isValidRepairItem(itemInHand.asItem()) && getFlag(EntityFlag.SITTING) && diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java index db2a3ecc3..9c43ab23a 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java @@ -66,7 +66,7 @@ public class PiglinEntity extends BasePiglinEntity { @Override public void updateOffHand(GeyserSession session) { // Check if the Piglin is holding Gold and set the ADMIRING flag accordingly so its pose updates - setFlag(EntityFlag.ADMIRING, session.getTagCache().is(ItemTag.PIGLIN_LOVED, session.getItemMappings().getMapping(this.offHand).getJavaItem())); + setFlag(EntityFlag.ADMIRING, session.getTagCache().is(ItemTag.PIGLIN_LOVED, session.getItemMappings().getMapping(this.offhand).getJavaItem())); super.updateBedrockMetadata(); super.updateOffHand(session); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/PillagerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/PillagerEntity.java index d2f8377d3..1d2d9115b 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/PillagerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/PillagerEntity.java @@ -59,7 +59,7 @@ public class PillagerEntity extends AbstractIllagerEntity { protected void checkForCrossbow() { ItemMapping crossbow = session.getItemMappings().getStoredItems().crossbow(); boolean hasCrossbow = this.hand.getDefinition() == crossbow.getBedrockDefinition() - || this.offHand.getDefinition() == crossbow.getBedrockDefinition(); + || this.offhand.getDefinition() == crossbow.getBedrockDefinition(); setFlag(EntityFlag.USING_ITEM, hasCrossbow); setFlag(EntityFlag.CHARGED, hasCrossbow); diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index 24362f800..a744c4822 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -360,7 +360,7 @@ public final class ItemTranslator { } if (mapping.getJavaItem().equals(Items.PLAYER_HEAD)) { - CustomSkull customSkull = getCustomSkull(session, itemStack.getComponents()); + CustomSkull customSkull = getCustomSkull(itemStack.getComponents()); if (customSkull != null) { itemDefinition = session.getItemMappings().getCustomBlockItemDefinitions().get(customSkull.getCustomBlockData()); } @@ -552,7 +552,7 @@ public final class ItemTranslator { builder.blockDefinition(blockDefinition); } - private static @Nullable CustomSkull getCustomSkull(GeyserSession session, DataComponents components) { + private static @Nullable CustomSkull getCustomSkull(DataComponents components) { if (components == null) { return null; } @@ -563,7 +563,7 @@ public final class ItemTranslator { try { textures = profile.getTextures(false); } catch (PropertyException e) { - session.getGeyser().getLogger().debug("Failed to get textures from GameProfile: " + e); + GeyserImpl.getInstance().getLogger().debug("Failed to get textures from GameProfile: " + e); } if (textures == null || textures.isEmpty()) { @@ -583,7 +583,7 @@ public final class ItemTranslator { } private static void translatePlayerHead(GeyserSession session, DataComponents components, ItemData.Builder builder) { - CustomSkull customSkull = getCustomSkull(session, components); + CustomSkull customSkull = getCustomSkull(components); if (customSkull != null) { CustomBlockData customBlockData = customSkull.getCustomBlockData(); ItemDefinition itemDefinition = session.getItemMappings().getCustomBlockItemDefinitions().get(customBlockData); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java index fbabd4afa..db9874af4 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java @@ -25,12 +25,10 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundEntityEventPacket; import org.cloudburstmc.protocol.bedrock.data.ParticleType; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; -import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket; import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEvent2Packet; @@ -46,6 +44,7 @@ import org.geysermc.geyser.entity.type.living.monster.WardenEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundEntityEventPacket; import java.util.concurrent.ThreadLocalRandom; @@ -223,9 +222,7 @@ public class JavaEntityEventTranslator extends PacketTranslator { @@ -58,7 +56,7 @@ public class JavaSetEquipmentTranslator extends PacketTranslator { ItemStack javaItem = equipment.getItem(); @@ -71,28 +69,28 @@ public class JavaSetEquipmentTranslator extends PacketTranslator { // BODY is sent for llamas with a carpet equipped, as of 1.20.5 - livingEntity.setChestplate(item); + livingEntity.setChestplate(stack); armorUpdated = true; } case LEGGINGS -> { - livingEntity.setLeggings(item); + livingEntity.setLeggings(stack); armorUpdated = true; } case BOOTS -> { - livingEntity.setBoots(item); + livingEntity.setBoots(stack); armorUpdated = true; } case MAIN_HAND -> { - livingEntity.setHand(item); + livingEntity.setHand(stack); mainHandUpdated = true; } case OFF_HAND -> { - livingEntity.setOffHand(item); + livingEntity.setOffhand(stack); offHandUpdated = true; } } diff --git a/core/src/main/java/org/geysermc/geyser/util/BlockUtils.java b/core/src/main/java/org/geysermc/geyser/util/BlockUtils.java index 0fc7a39e7..70102c2b0 100644 --- a/core/src/main/java/org/geysermc/geyser/util/BlockUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/BlockUtils.java @@ -145,7 +145,7 @@ public final class BlockUtils { toolCanBreak = canToolTierBreakBlock(session, blockMapping, toolTier); } - int toolEfficiencyLevel = ItemUtils.getEnchantmentLevel(components, Enchantment.JavaEnchantment.EFFICIENCY.ordinal()); + int toolEfficiencyLevel = ItemUtils.getEnchantmentLevel(components, Enchantment.JavaEnchantment.EFFICIENCY); int hasteLevel = 0; int miningFatigueLevel = 0; @@ -160,7 +160,7 @@ public final class BlockUtils { boolean waterInEyes = session.getCollisionManager().isWaterInEyes(); boolean insideOfWaterWithoutAquaAffinity = waterInEyes && - ItemUtils.getEnchantmentLevel(session.getPlayerInventory().getItem(5).getComponents(), Enchantment.JavaEnchantment.AQUA_AFFINITY.ordinal()) < 1; + ItemUtils.getEnchantmentLevel(session.getPlayerInventory().getItem(5).getComponents(), Enchantment.JavaEnchantment.AQUA_AFFINITY) < 1; return calculateBreakTime(blockMapping.getHardness(), toolTier, canHarvestWithHand, correctTool, toolCanBreak, toolType, isShearsEffective, toolEfficiencyLevel, hasteLevel, miningFatigueLevel, insideOfWaterWithoutAquaAffinity, session.getPlayerEntity().isOnGround()); diff --git a/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java b/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java index 1b47c3a00..c9d9903d4 100644 --- a/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java @@ -27,6 +27,7 @@ package org.geysermc.geyser.util; import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.Nullable; +import org.geysermc.geyser.inventory.item.Enchantment; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.FishingRodItem; import org.geysermc.geyser.item.type.Item; @@ -36,7 +37,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantm public class ItemUtils { - public static int getEnchantmentLevel(@Nullable DataComponents components, int enchantmentId) { + public static int getEnchantmentLevel(@Nullable DataComponents components, Enchantment.JavaEnchantment enchantment) { if (components == null) { return 0; } @@ -46,7 +47,7 @@ public class ItemUtils { return 0; } - return enchantmentData.getEnchantments().getOrDefault(enchantmentId, 0); + return enchantmentData.getEnchantments().getOrDefault(enchantment.ordinal(), 0); } /** From 3656395ce11b028ae3c1c5b8fbe4f783664b846d Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Thu, 25 Apr 2024 21:03:17 -0400 Subject: [PATCH 107/272] Armadillo states --- .../entity/properties/type/EnumProperty.java | 2 +- .../type/living/animal/ArmadilloEntity.java | 25 ++++++++++++++++--- .../entity/JavaEntityEventTranslator.java | 6 +++++ gradle/libs.versions.toml | 2 +- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/properties/type/EnumProperty.java b/core/src/main/java/org/geysermc/geyser/entity/properties/type/EnumProperty.java index 9bc45f560..05e12ba61 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/properties/type/EnumProperty.java +++ b/core/src/main/java/org/geysermc/geyser/entity/properties/type/EnumProperty.java @@ -50,7 +50,7 @@ public class EnumProperty implements PropertyType { public NbtMap nbtMap() { return NbtMap.builder() .putString("name", name) - .putList("values", NbtType.STRING, values) + .putList("enum", NbtType.STRING, values) .putInt("type", 3) .build(); } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java index 205c8cbd9..51fe09383 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java @@ -32,23 +32,42 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.ArmadilloSt import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; import java.util.UUID; +import java.util.concurrent.TimeUnit; public class ArmadilloEntity extends AnimalEntity { + private ArmadilloState armadilloState = ArmadilloState.IDLE; + public ArmadilloEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); } - // TODO: This is completely wrong; probably need to store the previous IDLE/ROLLING/SCARED state and check for transitions (pain) public void setArmadilloState(ObjectEntityMetadata entityMetadata) { - ArmadilloState armadilloState = entityMetadata.getValue(); + armadilloState = entityMetadata.getValue(); switch (armadilloState) { case IDLE -> propertyManager.add("minecraft:armadillo_state", "unrolled"); case ROLLING -> propertyManager.add("minecraft:armadillo_state", "rolled_up"); - case SCARED -> propertyManager.add("minecraft:armadillo_state", "rolled_up_peeking"); + case SCARED -> propertyManager.add("minecraft:armadillo_state", "rolled_up_relaxing"); + case UNROLLING -> propertyManager.add("minecraft:armadillo_state", "rolled_up_unrolling"); } updateBedrockEntityProperties(); } + + public void onPeeking() { + // Technically we should wait if not currently scared + if (armadilloState == ArmadilloState.SCARED) { + propertyManager.add("minecraft:armadillo_state", "rolled_up_peeking"); + updateBedrockEntityProperties(); + + // Needed for consecutive peeks + session.scheduleInEventLoop(() -> { + if (armadilloState == ArmadilloState.SCARED) { + propertyManager.add("minecraft:armadillo_state", "rolled_up_relaxing"); + updateBedrockEntityProperties(); + } + }, 250, TimeUnit.MILLISECONDS); + } + } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java index db9874af4..e119d39ce 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java @@ -40,6 +40,7 @@ import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.EvokerFangsEntity; import org.geysermc.geyser.entity.type.FishingHookEntity; import org.geysermc.geyser.entity.type.LivingEntity; +import org.geysermc.geyser.entity.type.living.animal.ArmadilloEntity; import org.geysermc.geyser.entity.type.living.monster.WardenEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; @@ -257,6 +258,11 @@ public class JavaEntityEventTranslator extends PacketTranslator Date: Fri, 26 Apr 2024 14:50:48 +0200 Subject: [PATCH 108/272] idea: deal with cookies and transfer --- .../api/event/bedrock/SessionLoginEvent.java | 43 ++++++++++- .../api/event/java/ServerTransferEvent.java | 71 +++++++++++++++++++ .../platform/spigot/GeyserSpigotInjector.java | 3 +- .../geyser/item/type/WrittenBookItem.java | 1 - .../geyser/network/netty/LocalSession.java | 7 +- .../geyser/session/GeyserSession.java | 11 ++- .../player/JavaCookieRequestTranslator.java | 42 +++++++++++ .../player/JavaStoreCookieTranslator.java | 37 ++++++++++ .../player/JavaTransferPacketTranslator.java | 43 +++++++++++ 9 files changed, 251 insertions(+), 7 deletions(-) create mode 100644 api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java create mode 100644 core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java create mode 100644 core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java create mode 100644 core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java diff --git a/api/src/main/java/org/geysermc/geyser/api/event/bedrock/SessionLoginEvent.java b/api/src/main/java/org/geysermc/geyser/api/event/bedrock/SessionLoginEvent.java index c3c8198c1..522562d11 100644 --- a/api/src/main/java/org/geysermc/geyser/api/event/bedrock/SessionLoginEvent.java +++ b/api/src/main/java/org/geysermc/geyser/api/event/bedrock/SessionLoginEvent.java @@ -32,6 +32,9 @@ import org.geysermc.geyser.api.connection.GeyserConnection; import org.geysermc.geyser.api.event.connection.ConnectionEvent; import org.geysermc.geyser.api.network.RemoteServer; +import java.util.Map; +import java.util.Objects; + /** * Called when a session has logged in, and is about to connect to a remote java server. * This event is cancellable, and can be used to prevent the player from connecting to the remote server. @@ -40,10 +43,16 @@ public final class SessionLoginEvent extends ConnectionEvent implements Cancella private RemoteServer remoteServer; private boolean cancelled; private String disconnectReason; + private Map cookies; + private boolean transferring; - public SessionLoginEvent(@NonNull GeyserConnection connection, @NonNull RemoteServer remoteServer) { + public SessionLoginEvent(@NonNull GeyserConnection connection, + @NonNull RemoteServer remoteServer, + @NonNull Map cookies) { super(connection); this.remoteServer = remoteServer; + this.cookies = cookies; + this.transferring = false; } /** @@ -106,4 +115,36 @@ public final class SessionLoginEvent extends ConnectionEvent implements Cancella public void remoteServer(@NonNull RemoteServer remoteServer) { this.remoteServer = remoteServer; } + + /** + * Sets a map of cookies from a possible previous session. The Java server can send and request these + * to store information on the client across server transfers. + */ + public void cookies(@NonNull Map cookies) { + Objects.requireNonNull(cookies); + this.cookies = cookies; + } + + /** + * Gets a map of the sessions cookies, if set. + * @return the connections cookies + */ + public @NonNull Map cookies() { + return cookies; + } + + /** + * Determines the connection intent of the connection + */ + public void transferring(boolean transferring) { + this.transferring = transferring; + } + + /** + * Gets whether this login attempt to the Java server + * has the transfer intent + */ + public boolean transferring() { + return this.transferring; + } } diff --git a/api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java b/api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java new file mode 100644 index 000000000..afdf596c2 --- /dev/null +++ b/api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.api.event.java; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.geysermc.geyser.api.connection.GeyserConnection; +import org.geysermc.geyser.api.event.connection.ConnectionEvent; + +import java.util.Map; + +public class ServerTransferEvent extends ConnectionEvent { + + private final String host; + private final int port; + private final Map cookies; + + public ServerTransferEvent(@NonNull GeyserConnection connection, String host, int port, Map cookies) { + super(connection); + this.host = host; + this.port = port; + this.cookies = cookies; + } + + /** + * The host that the Java server requests a transfer to. + * @return the host + */ + public String host() { + return this.host; + } + + /** + * The port that the Java server requests a transfer to. + * @return the port + */ + public int port() { + return this.port; + } + + /** + * Gets a map of the sessions current cookies. + * @return the connections cookies + */ + public @NonNull Map cookies() { + return cookies; + } + +} diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java index 43ecf7154..6aa5d563f 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java @@ -175,8 +175,9 @@ public class GeyserSpigotInjector extends GeyserInjector { MinecraftProtocol protocol = new MinecraftProtocol(); LocalSession session = new LocalSession(bootstrap.getGeyserConfig().getRemote().address(), bootstrap.getGeyserConfig().getRemote().port(), this.serverSocketAddress, - InetAddress.getLoopbackAddress().getHostAddress(), protocol, protocol.createHelper()); + InetAddress.getLoopbackAddress().getHostAddress(), protocol, protocol.createHelper(), false); session.connect(); + session.disconnect(""); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java index a11c4f583..4a2028fc7 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java @@ -70,6 +70,5 @@ public class WrittenBookItem extends Item { builder.putString("title", bookContent.getTitle().getRaw()) .putString("author", bookContent.getAuthor()) .putInt("generation", bookContent.getGeneration()); - // TODO isResolved } } diff --git a/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java b/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java index 19b0b423f..b5598d063 100644 --- a/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java +++ b/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java @@ -54,11 +54,14 @@ public final class LocalSession extends TcpSession { private final String clientIp; private final PacketCodecHelper codecHelper; - public LocalSession(String host, int port, SocketAddress targetAddress, String clientIp, PacketProtocol protocol, MinecraftCodecHelper codecHelper) { + private final boolean transferring; + + public LocalSession(String host, int port, SocketAddress targetAddress, String clientIp, PacketProtocol protocol, MinecraftCodecHelper codecHelper, boolean transferring) { super(host, port, protocol); this.targetAddress = targetAddress; this.clientIp = clientIp; this.codecHelper = codecHelper; + this.transferring = transferring; } @Override @@ -79,7 +82,7 @@ public final class LocalSession extends TcpSession { public void initChannel(@NonNull LocalChannelWithRemoteAddress channel) { channel.spoofedRemoteAddress(new InetSocketAddress(clientIp, 0)); PacketProtocol protocol = getPacketProtocol(); - protocol.newClientSession(LocalSession.this, false); + protocol.newClientSession(LocalSession.this, transferring); refreshReadTimeoutHandler(channel); refreshWriteTimeoutHandler(channel); diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 175d9eac2..869999357 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -569,6 +569,12 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { @Setter private @Nullable ItemData currentBook = null; + /** + * Stores cookies sent by the Java server. + */ + @Setter @Getter + private Map cookies = new Object2ObjectOpenHashMap<>(); + private final GeyserCameraData cameraData; private final GeyserEntityData entityData; @@ -853,7 +859,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { * After getting whatever credentials needed, we attempt to join the Java server. */ private void connectDownstream() { - SessionLoginEvent loginEvent = new SessionLoginEvent(this, remoteServer); + SessionLoginEvent loginEvent = new SessionLoginEvent(this, remoteServer, new Object2ObjectOpenHashMap<>()); GeyserImpl.getInstance().eventBus().fire(loginEvent); if (loginEvent.isCancelled()) { String disconnectReason = loginEvent.disconnectReason() == null ? @@ -862,6 +868,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { return; } + this.cookies = loginEvent.cookies(); this.remoteServer = loginEvent.remoteServer(); boolean floodgate = this.remoteServer.authType() == AuthType.FLOODGATE; @@ -873,7 +880,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { // We're going to connect through the JVM and not through TCP downstream = new LocalSession(this.remoteServer.address(), this.remoteServer.port(), geyser.getBootstrap().getSocketAddress(), upstream.getAddress().getAddress().getHostAddress(), - this.protocol, this.protocol.createHelper()); + this.protocol, this.protocol.createHelper(), loginEvent.transferring()); this.downstream = new DownstreamSession(downstream); } else { downstream = new TcpClientSession(this.remoteServer.address(), this.remoteServer.port(), this.protocol); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java new file mode 100644 index 000000000..06f020423 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.translator.protocol.java.entity.player; + +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.protocol.PacketTranslator; +import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundCookieRequestPacket; +import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ServerboundCookieResponsePacket; + +public class JavaCookieRequestTranslator extends PacketTranslator { + @Override + public void translate(GeyserSession session, ClientboundCookieRequestPacket packet) { + ServerboundCookieResponsePacket responsePacket = new ServerboundCookieResponsePacket( + packet.getKey(), + session.getCookies().get(packet.getKey()) + ); + session.sendDownstreamPacket(responsePacket); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java new file mode 100644 index 000000000..499dfda8d --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.translator.protocol.java.entity.player; + +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.protocol.PacketTranslator; +import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundStoreCookiePacket; + +public class JavaStoreCookieTranslator extends PacketTranslator { + @Override + public void translate(GeyserSession session, ClientboundStoreCookiePacket packet) { + session.getCookies().put(packet.getKey(), packet.getPayload()); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java new file mode 100644 index 000000000..1e9bd1537 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.translator.protocol.java.entity.player; + +import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.api.event.java.ServerTransferEvent; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.protocol.PacketTranslator; +import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundTransferPacket; + +public class JavaTransferPacketTranslator extends PacketTranslator { + @Override + public void translate(GeyserSession session, ClientboundTransferPacket packet) { + GeyserImpl.getInstance().eventBus().fire(new ServerTransferEvent( + session, + packet.getHost(), + packet.getPort(), + session.getCookies())); + } +} From f67c131b8d06f938a10f9eb0f52a6f4ab2b1423a Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Fri, 26 Apr 2024 15:36:26 +0200 Subject: [PATCH 109/272] Forcibly disconnect players even if no server target was set in the JavaTransferEvent --- .../api/event/java/ServerTransferEvent.java | 52 +++++++++++++++++++ .../player/JavaCookieRequestTranslator.java | 2 + .../player/JavaStoreCookieTranslator.java | 2 + .../player/JavaTransferPacketTranslator.java | 15 +++++- 4 files changed, 69 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java b/api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java index afdf596c2..b3b580ec3 100644 --- a/api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java +++ b/api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java @@ -26,15 +26,22 @@ package org.geysermc.geyser.api.event.java; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.common.value.qual.IntRange; import org.geysermc.geyser.api.connection.GeyserConnection; import org.geysermc.geyser.api.event.connection.ConnectionEvent; import java.util.Map; +/** + * Fired when the Java server sends a transfer request to a different Java server. + * Geyser Extensions can listen to this event and set a target server ip/port for Bedrock players to be transferred to. + */ public class ServerTransferEvent extends ConnectionEvent { private final String host; private final int port; + private String bedrockHost; + private int bedrockPort; private final Map cookies; public ServerTransferEvent(@NonNull GeyserConnection connection, String host, int port, Map cookies) { @@ -42,10 +49,13 @@ public class ServerTransferEvent extends ConnectionEvent { this.host = host; this.port = port; this.cookies = cookies; + this.bedrockHost = null; + this.bedrockPort = -1; } /** * The host that the Java server requests a transfer to. + * * @return the host */ public String host() { @@ -54,14 +64,56 @@ public class ServerTransferEvent extends ConnectionEvent { /** * The port that the Java server requests a transfer to. + * * @return the port */ public int port() { return this.port; } + /** + * The host that the Bedrock player should try and connect to. + * If this is not set, the Bedrock player will just be disconnected. + * + * @return the host where the Bedrock client will be transferred to, or null if not set. + */ + public String bedrockHost() { + return this.bedrockHost; + } + + /** + * The port that the Bedrock player should try and connect to. + * If this is not set, the Bedrock player will just be disconnected. + * + * @return the port where the Bedrock client will be transferred to, or -1 if not set. + */ + public int bedrockPort() { + return this.bedrockPort; + } + + /** + * Sets the host for the Bedrock player to be transferred to + */ + public void bedrockHost(@NonNull String host) { + if (host == null || host.isBlank()) { + throw new IllegalArgumentException("Server address cannot be null or blank"); + } + this.bedrockHost = host; + } + + /** + * Sets the port for the Bedrock player to be transferred to + */ + public void bedrockPort(@IntRange(from = 0, to = 65535) int port) { + if (port < 0 || port > 65535) { + throw new IllegalArgumentException("Server port must be between 0 and 65535, was " + port); + } + this.bedrockPort = port; + } + /** * Gets a map of the sessions current cookies. + * * @return the connections cookies */ public @NonNull Map cookies() { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java index 06f020423..5266ebabd 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java @@ -27,9 +27,11 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; +import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundCookieRequestPacket; import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ServerboundCookieResponsePacket; +@Translator(packet = ClientboundCookieRequestPacket.class) public class JavaCookieRequestTranslator extends PacketTranslator { @Override public void translate(GeyserSession session, ClientboundCookieRequestPacket packet) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java index 499dfda8d..19237b646 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java @@ -27,8 +27,10 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; +import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundStoreCookiePacket; +@Translator(packet = ClientboundStoreCookiePacket.class) public class JavaStoreCookieTranslator extends PacketTranslator { @Override public void translate(GeyserSession session, ClientboundStoreCookiePacket packet) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java index 1e9bd1537..86fd70677 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java @@ -28,16 +28,27 @@ package org.geysermc.geyser.translator.protocol.java.entity.player; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.event.java.ServerTransferEvent; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.protocol.PacketTranslator; +import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundTransferPacket; +@Translator(packet = ClientboundTransferPacket.class) public class JavaTransferPacketTranslator extends PacketTranslator { @Override public void translate(GeyserSession session, ClientboundTransferPacket packet) { - GeyserImpl.getInstance().eventBus().fire(new ServerTransferEvent( + ServerTransferEvent event = new ServerTransferEvent( session, packet.getHost(), packet.getPort(), - session.getCookies())); + session.getCookies()); + + GeyserImpl.getInstance().eventBus().fire(event); + + if (event.bedrockHost() != null && !event.bedrockHost().isBlank() && event.bedrockPort() != -1) { + session.transfer(event.bedrockHost(), event.bedrockPort()); + } else { + session.disconnect(MinecraftLocale.getLocaleString("disconnect.transfer", session.locale())); + } } } From 5015a2ef895a2f51a1bc3d08c824d98025d3e8ff Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Fri, 26 Apr 2024 15:41:05 +0200 Subject: [PATCH 110/272] bump project version to 2.3.0 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index a7c0bf93d..dd61d2556 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,5 +7,5 @@ org.gradle.vfs.watch=false group=org.geysermc id=geyser -version=2.2.3-SNAPSHOT +version=2.3.0-SNAPSHOT description=Allows for players from Minecraft: Bedrock Edition to join Minecraft: Java Edition servers. From a57e7b54dc93ad23c82c1c3c4233678b5f16dffe Mon Sep 17 00:00:00 2001 From: chris Date: Fri, 26 Apr 2024 16:36:47 +0200 Subject: [PATCH 111/272] Update ViaVersion api usage to be compatible with ViaVersion 4.10 (#4606) --- .../world/manager/GeyserSpigotLegacyNativeWorldManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotLegacyNativeWorldManager.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotLegacyNativeWorldManager.java index 021db5ec1..d3d492553 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotLegacyNativeWorldManager.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotLegacyNativeWorldManager.java @@ -58,7 +58,7 @@ public class GeyserSpigotLegacyNativeWorldManager extends GeyserSpigotNativeWorl int newBlockId = oldBlockId; // protocolList should *not* be null; we checked for that before initializing this class for (int i = protocolList.size() - 1; i >= 0; i--) { - MappingData mappingData = protocolList.get(i).getProtocol().getMappingData(); + MappingData mappingData = protocolList.get(i).protocol().getMappingData(); if (mappingData != null) { newBlockId = mappingData.getNewBlockStateId(newBlockId); } From 42a9ba617bb11c7da5073eb7c3c8ec60a3102984 Mon Sep 17 00:00:00 2001 From: RK_01 <50594595+RaphiMC@users.noreply.github.com> Date: Fri, 26 Apr 2024 20:06:37 +0200 Subject: [PATCH 112/272] Update ViaProxy platform (#4607) * Update ViaProxy API usage * Don't reference ViaProxy API in dummy application --- .../viaproxy/GeyserViaProxyConfiguration.java | 4 ++-- .../platform/viaproxy/GeyserViaProxyDumpInfo.java | 5 ++--- .../geyser/platform/viaproxy/GeyserViaProxyMain.java | 3 +-- .../platform/viaproxy/GeyserViaProxyPlugin.java | 11 +++++------ bootstrap/viaproxy/src/main/resources/viaproxy.yml | 2 +- gradle/libs.versions.toml | 2 +- 6 files changed, 12 insertions(+), 15 deletions(-) diff --git a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyConfiguration.java b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyConfiguration.java index ad249eb3b..bf9d6816c 100644 --- a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyConfiguration.java +++ b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyConfiguration.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.platform.viaproxy; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import net.raphimc.vialegacy.api.LegacyProtocolVersion; -import net.raphimc.viaproxy.cli.options.Options; +import net.raphimc.viaproxy.ViaProxy; import org.geysermc.geyser.configuration.GeyserJacksonConfiguration; import java.io.File; @@ -43,7 +43,7 @@ public class GeyserViaProxyConfiguration extends GeyserJacksonConfiguration { @Override public int getPingPassthroughInterval() { int interval = super.getPingPassthroughInterval(); - if (interval < 15 && Options.PROTOCOL_VERSION != null && Options.PROTOCOL_VERSION.olderThanOrEqualTo(LegacyProtocolVersion.r1_6_4)) { + if (interval < 15 && ViaProxy.getConfig().getTargetVersion() != null && ViaProxy.getConfig().getTargetVersion().olderThanOrEqualTo(LegacyProtocolVersion.r1_6_4)) { // <= 1.6.4 servers sometimes block incoming connections from an IP address if too many connections are made interval = 15; } diff --git a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyDumpInfo.java b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyDumpInfo.java index 08f3d5371..0bfc9d022 100644 --- a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyDumpInfo.java +++ b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyDumpInfo.java @@ -26,7 +26,6 @@ package org.geysermc.geyser.platform.viaproxy; import lombok.Getter; import net.raphimc.viaproxy.ViaProxy; -import net.raphimc.viaproxy.cli.options.Options; import net.raphimc.viaproxy.plugins.ViaProxyPlugin; import org.geysermc.geyser.dump.BootstrapDumpInfo; import org.geysermc.geyser.text.AsteriskSerializer; @@ -49,8 +48,8 @@ public class GeyserViaProxyDumpInfo extends BootstrapDumpInfo { public GeyserViaProxyDumpInfo() { this.platformVersion = ViaProxy.VERSION; - this.onlineMode = Options.ONLINE_MODE; - if (Options.BIND_ADDRESS instanceof InetSocketAddress inetSocketAddress) { + this.onlineMode = ViaProxy.getConfig().isProxyOnlineMode(); + if (ViaProxy.getConfig().getBindAddress() instanceof InetSocketAddress inetSocketAddress) { this.serverIP = inetSocketAddress.getHostString(); this.serverPort = inetSocketAddress.getPort(); } else { diff --git a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyMain.java b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyMain.java index 675c92534..582a97d78 100644 --- a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyMain.java +++ b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyMain.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.platform.viaproxy; -import net.raphimc.viaproxy.plugins.PluginManager; import org.geysermc.geyser.GeyserMain; public class GeyserViaProxyMain extends GeyserMain { @@ -39,7 +38,7 @@ public class GeyserViaProxyMain extends GeyserMain { } public String getPluginFolder() { - return PluginManager.PLUGINS_DIR.getName(); + return "plugins"; } } diff --git a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyPlugin.java b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyPlugin.java index 47745df7d..30404e705 100644 --- a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyPlugin.java +++ b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyPlugin.java @@ -27,7 +27,6 @@ package org.geysermc.geyser.platform.viaproxy; import net.lenni0451.lambdaevents.EventHandler; import net.raphimc.vialegacy.api.LegacyProtocolVersion; import net.raphimc.viaproxy.ViaProxy; -import net.raphimc.viaproxy.cli.options.Options; import net.raphimc.viaproxy.plugins.PluginManager; import net.raphimc.viaproxy.plugins.ViaProxyPlugin; import net.raphimc.viaproxy.plugins.events.ConsoleCommandEvent; @@ -137,7 +136,7 @@ public class GeyserViaProxyPlugin extends ViaProxyPlugin implements GeyserBootst GeyserImpl.start(); - if (Options.PROTOCOL_VERSION != null && Options.PROTOCOL_VERSION.newerThanOrEqualTo(LegacyProtocolVersion.b1_8tob1_8_1)) { + if (ViaProxy.getConfig().getTargetVersion() != null && ViaProxy.getConfig().getTargetVersion().newerThanOrEqualTo(LegacyProtocolVersion.b1_8tob1_8_1)) { // Only initialize the ping passthrough if the protocol version is above beta 1.7.3, as that's when the status protocol was added this.pingPassthrough = GeyserLegacyPingPassthrough.init(this.geyser); } @@ -186,19 +185,19 @@ public class GeyserViaProxyPlugin extends ViaProxyPlugin implements GeyserBootst @NotNull @Override public String getServerBindAddress() { - if (Options.BIND_ADDRESS instanceof InetSocketAddress socketAddress) { + if (ViaProxy.getConfig().getBindAddress() instanceof InetSocketAddress socketAddress) { return socketAddress.getHostString(); } else { - throw new IllegalStateException("Unsupported bind address type: " + Options.BIND_ADDRESS.getClass().getName()); + throw new IllegalStateException("Unsupported bind address type: " + ViaProxy.getConfig().getBindAddress().getClass().getName()); } } @Override public int getServerPort() { - if (Options.BIND_ADDRESS instanceof InetSocketAddress socketAddress) { + if (ViaProxy.getConfig().getBindAddress() instanceof InetSocketAddress socketAddress) { return socketAddress.getPort(); } else { - throw new IllegalStateException("Unsupported bind address type: " + Options.BIND_ADDRESS.getClass().getName()); + throw new IllegalStateException("Unsupported bind address type: " + ViaProxy.getConfig().getBindAddress().getClass().getName()); } } diff --git a/bootstrap/viaproxy/src/main/resources/viaproxy.yml b/bootstrap/viaproxy/src/main/resources/viaproxy.yml index f42cda77b..66fbdb932 100644 --- a/bootstrap/viaproxy/src/main/resources/viaproxy.yml +++ b/bootstrap/viaproxy/src/main/resources/viaproxy.yml @@ -2,4 +2,4 @@ name: "${name}-ViaProxy" version: "${version}" author: "${author}" main: "org.geysermc.geyser.platform.viaproxy.GeyserViaProxyPlugin" -min-version: "3.2.0" +min-version: "3.2.1" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2d32159f0..b051e8852 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -29,7 +29,7 @@ adapters = "1.11-SNAPSHOT" commodore = "2.2" bungeecord = "a7c6ede" velocity = "3.1.1" -viaproxy = "3.2.0-SNAPSHOT" +viaproxy = "3.2.1" fabric-minecraft = "1.20.4" fabric-loader = "0.15.2" fabric-api = "0.91.2+1.20.4" From 2fa7585db3538ebb386edb861abf792f1f35489c Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Fri, 26 Apr 2024 21:44:59 -0400 Subject: [PATCH 113/272] Switch to Cloudburst NBT only --- .../java/org/geysermc/geyser/GeyserImpl.java | 3 +- .../geyser/entity/type/LivingEntity.java | 7 +- .../entity/type/player/PlayerEntity.java | 18 +- .../geyser/inventory/GeyserItemStack.java | 43 +++-- .../geysermc/geyser/inventory/Inventory.java | 13 +- .../geyser/inventory/item/Potion.java | 6 + .../geyser/inventory/recipe/TrimRecipe.java | 12 +- .../updater/AnvilInventoryUpdater.java | 60 +++---- .../geyser/item/DyeableLeatherItem.java | 15 -- .../geysermc/geyser/item/type/ArmorItem.java | 16 -- .../geysermc/geyser/item/type/ArrowItem.java | 16 +- .../geysermc/geyser/item/type/BannerItem.java | 58 +++---- .../geyser/item/type/CompassItem.java | 4 +- .../geyser/item/type/CrossbowItem.java | 22 --- .../geyser/item/type/DyeableArmorItem.java | 9 - .../item/type/DyeableHorseArmorItem.java | 9 - .../geyser/item/type/EnchantedBookItem.java | 30 ++++ .../geyser/item/type/FireworkRocketItem.java | 69 ++++---- .../geyser/item/type/FireworkStarItem.java | 19 +-- .../geyser/item/type/GoatHornItem.java | 17 +- .../org/geysermc/geyser/item/type/Item.java | 117 +++++++------ .../geysermc/geyser/item/type/MapItem.java | 14 -- .../geysermc/geyser/item/type/PotionItem.java | 10 +- .../geyser/item/type/ShulkerBoxItem.java | 9 - .../item/type/TropicalFishBucketItem.java | 19 +-- .../geyser/item/type/WritableBookItem.java | 25 --- .../geyser/item/type/WrittenBookItem.java | 3 +- .../geysermc/geyser/level/JavaDimension.java | 33 +--- .../geyser/session/cache/LodestoneCache.java | 18 +- .../org/geysermc/geyser/skin/SkinManager.java | 22 +-- .../geysermc/geyser/text/TextDecoration.java | 33 ++-- .../inventory/InventoryTranslator.java | 2 +- .../inventory/PlayerInventoryTranslator.java | 4 +- .../inventory/ShulkerInventoryTranslator.java | 2 +- .../translator/item/ItemTranslator.java | 156 ++---------------- .../entity/BannerBlockEntityTranslator.java | 27 +-- .../entity/BeaconBlockEntityTranslator.java | 15 +- .../entity/BedBlockEntityTranslator.java | 9 +- .../block/entity/BlockEntityTranslator.java | 15 +- .../BrushableBlockEntityTranslator.java | 29 ++-- .../entity/CampfireBlockEntityTranslator.java | 34 ++-- .../CommandBlockBlockEntityTranslator.java | 33 ++-- .../DecoratedPotBlockEntityTranslator.java | 21 +-- .../DoubleChestBlockEntityTranslator.java | 18 +- .../entity/EmptyBlockEntityTranslator.java | 5 +- .../EndGatewayBlockEntityTranslator.java | 34 +--- .../JigsawBlockBlockEntityTranslator.java | 23 ++- .../ShulkerBoxBlockEntityTranslator.java | 7 +- .../entity/SignBlockEntityTranslator.java | 37 ++--- .../entity/SkullBlockEntityTranslator.java | 66 ++++---- .../entity/SpawnerBlockEntityTranslator.java | 64 ++++--- .../StructureBlockBlockEntityTranslator.java | 69 ++++---- .../TrialSpawnerBlockEntityTranslator.java | 11 +- .../level/JavaBlockEntityDataTranslator.java | 27 ++- .../JavaLevelChunkWithLightTranslator.java | 5 +- .../BlockSoundInteractionTranslator.java | 31 +--- .../translator/text/MessageTranslator.java | 18 +- gradle/libs.versions.toml | 2 +- 58 files changed, 586 insertions(+), 927 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java index 5c4313f09..d5635acf9 100644 --- a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java +++ b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java @@ -45,7 +45,6 @@ import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec; import org.geysermc.api.Geyser; import org.geysermc.cumulus.form.Form; import org.geysermc.cumulus.form.util.FormBuilder; -import org.geysermc.erosion.packet.Packets; import org.geysermc.floodgate.crypto.AesCipher; import org.geysermc.floodgate.crypto.AesKeyProducer; import org.geysermc.floodgate.crypto.Base64Topping; @@ -384,7 +383,7 @@ public class GeyserImpl implements GeyserApi { this.newsHandler = new NewsHandler(BRANCH, this.buildNumber()); - Packets.initGeyser(); + //Packets.initGeyser(); if (Epoll.isAvailable()) { this.erosionUnixListener = new UnixSocketClientListener(); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java index 5823ba3b2..baaf91f59 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.entity.type; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; @@ -57,6 +55,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEn import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import java.util.*; @@ -194,9 +193,9 @@ public class LivingEntity extends Entity { /** * Checks to see if a nametag interaction would go through. */ + // Implementation note for 1.20.5: this code was moved to the NameTag item. protected final InteractionResult checkInteractWithNameTag(GeyserItemStack itemStack) { - CompoundTag nbt = itemStack.getNbt(); - if (nbt != null && nbt.get("display") instanceof CompoundTag displayTag && displayTag.get("Name") instanceof StringTag) { + if (itemStack.getComponent(DataComponentType.CUSTOM_NAME) != null) { // The mob shall be named return InteractionResult.SUCCESS; } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java index 1ca387259..25040063e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java @@ -25,14 +25,14 @@ package org.geysermc.geyser.entity.type.player; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; import lombok.Getter; import lombok.Setter; import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.data.Ability; import org.cloudburstmc.protocol.bedrock.data.AbilityLayer; import org.cloudburstmc.protocol.bedrock.data.GameType; @@ -298,11 +298,11 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity { dirtyMetadata.put(EntityDataTypes.MARK_VARIANT, ~entityMetadata.getPrimitiveValue() & 0xff); } - public void setLeftParrot(EntityMetadata entityMetadata) { + public void setLeftParrot(EntityMetadata entityMetadata) { setParrot(entityMetadata.getValue(), true); } - public void setRightParrot(EntityMetadata entityMetadata) { + public void setRightParrot(EntityMetadata entityMetadata) { setParrot(entityMetadata.getValue(), false); } @@ -310,7 +310,7 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity { * Sets the parrot occupying the shoulder. Bedrock Edition requires a full entity whereas Java Edition just * spawns it from the NBT data provided */ - protected void setParrot(CompoundTag tag, boolean isLeft) { + protected void setParrot(NbtMap tag, boolean isLeft) { if (tag != null && !tag.isEmpty()) { if ((isLeft && leftParrot != null) || (!isLeft && rightParrot != null)) { // No need to update a parrot's data when it already exists @@ -320,7 +320,7 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity { ParrotEntity parrot = new ParrotEntity(session, 0, session.getEntityCache().getNextEntityId().incrementAndGet(), null, EntityDefinitions.PARROT, position, motion, getYaw(), getPitch(), getHeadYaw()); parrot.spawnEntity(); - parrot.getDirtyMetadata().put(EntityDataTypes.VARIANT, (Integer) tag.get("Variant").getValue()); + parrot.getDirtyMetadata().put(EntityDataTypes.VARIANT, (Integer) tag.get("Variant")); // Different position whether the parrot is left or right float offset = isLeft ? 0.4f : -0.4f; parrot.getDirtyMetadata().put(EntityDataTypes.SEAT_OFFSET, Vector3f.from(offset, -0.22, -0.1)); @@ -437,11 +437,11 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity { } else if (numberFormat instanceof FixedFormat fixedFormat) { numberString = MessageTranslator.convertMessage(fixedFormat.getValue()); } else if (numberFormat instanceof StyledFormat styledFormat) { - CompoundTag styledAmount = styledFormat.getStyle().clone(); - styledAmount.put(new StringTag("text", String.valueOf(amount))); + NbtMapBuilder styledAmount = styledFormat.getStyle().toBuilder(); + styledAmount.putString("text", String.valueOf(amount)); numberString = MessageTranslator.convertJsonMessage( - NbtComponentSerializer.tagComponentToJson(styledAmount).toString()); + NbtComponentSerializer.tagComponentToJson(styledAmount.build()).toString(), session.locale()); } else { numberString = String.valueOf(amount); } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java b/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java index f75c1fdd9..fa62769fe 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java @@ -25,11 +25,7 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import lombok.AccessLevel; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.Getter; +import lombok.*; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; @@ -43,6 +39,8 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import java.util.HashMap; + @Data public class GeyserItemStack { public static final GeyserItemStack EMPTY = new GeyserItemStack(Items.AIR_ID, 0, null); @@ -52,7 +50,7 @@ public class GeyserItemStack { private DataComponents components; private int netId; - @Getter(AccessLevel.NONE) + @Getter(AccessLevel.NONE) @Setter(AccessLevel.NONE) @EqualsAndHashCode.Exclude private Item item; @@ -67,6 +65,14 @@ public class GeyserItemStack { this.netId = netId; } + public static @NonNull GeyserItemStack of(int javaId, int amount) { + return of(javaId, amount, null); + } + + public static @NonNull GeyserItemStack of(int javaId, int amount, DataComponents components) { + return new GeyserItemStack(javaId, amount, components); + } + public static @NonNull GeyserItemStack from(@Nullable ItemStack itemStack) { return itemStack == null ? EMPTY : new GeyserItemStack(itemStack.getId(), itemStack.getAmount(), itemStack.getDataComponents()); } @@ -79,16 +85,27 @@ public class GeyserItemStack { return isEmpty() ? 0 : amount; } - public @Nullable CompoundTag getNbt() { - Thread.dumpStack(); - return null; - } - public @Nullable DataComponents getComponents() { return isEmpty() ? null : components; } - public boolean getComponent(DataComponentType type, boolean def) { + @NonNull + public DataComponents getOrCreateComponents() { + if (components == null) { + return components = new DataComponents(new HashMap<>()); + } + return components; + } + + @Nullable + public T getComponent(@NonNull DataComponentType type) { + if (components == null) { + return null; + } + return components.get(type); + } + + public boolean getComponent(@NonNull DataComponentType type, boolean def) { if (components == null) { return def; } @@ -100,7 +117,7 @@ public class GeyserItemStack { return def; } - public int getComponent(DataComponentType type, int def) { + public int getComponent(@NonNull DataComponentType type, int def) { if (components == null) { return def; } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java b/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java index 4e8257ff8..09d04f17c 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.inventory; -import com.github.steveice10.opennbt.tag.builtin.ByteTag; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import lombok.Getter; import lombok.Setter; import lombok.ToString; @@ -39,6 +36,7 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.jetbrains.annotations.Range; import java.util.Arrays; @@ -137,12 +135,9 @@ public abstract class Inventory { // Lodestone caching if (newItem.asItem() == Items.COMPASS) { - CompoundTag nbt = newItem.getNbt(); - if (nbt != null) { - Tag lodestoneTag = nbt.get("LodestoneTracked"); - if (lodestoneTag instanceof ByteTag) { - session.getLodestoneCache().cacheInventoryItem(newItem); - } + var tracker = newItem.getComponent(DataComponentType.LODESTONE_TRACKER); + if (tracker != null) { + session.getLodestoneCache().cacheInventoryItem(newItem, tracker); } } } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java b/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java index 7ce0ee278..79b9565fb 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java @@ -25,8 +25,10 @@ package org.geysermc.geyser.inventory.item; +import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; import lombok.Getter; import org.checkerframework.checker.nullness.qual.Nullable; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.PotionContents; import java.util.Locale; @@ -85,6 +87,10 @@ public enum Potion { this.bedrockId = (short) bedrockId; } + public PotionContents toComponent() { + return new PotionContents(this.ordinal(), -1, Int2ObjectMaps.emptyMap()); + } + public static @Nullable Potion getByJavaIdentifier(String javaIdentifier) { for (Potion potion : VALUES) { if (potion.javaIdentifier.equals(javaIdentifier)) { diff --git a/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java b/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java index 860ccfd89..37eb905a4 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java @@ -25,9 +25,6 @@ package org.geysermc.geyser.inventory.recipe; -import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.TextColor; import org.cloudburstmc.protocol.bedrock.data.TrimMaterial; @@ -37,6 +34,7 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.descriptor.ItemTagDescri import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.text.MessageTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; /** * Stores information on trim materials and patterns, including smithing armor hacks for pre-1.20. @@ -54,11 +52,11 @@ public final class TrimRecipe { // Color is used when hovering over the item // Find the nearest legacy color from the RGB Java gives us to work with // Also yes this is a COMPLETE hack but it works ok!!!!! - StringTag colorTag = ((CompoundTag) entry.getData().get("description")).get("color"); - TextColor color = TextColor.fromHexString(colorTag.getValue()); + String colorTag = entry.getData().getCompound("description").getString("color"); + TextColor color = TextColor.fromHexString(colorTag); String legacy = MessageTranslator.convertMessage(Component.space().color(color)); - String itemIdentifier = ((StringTag) entry.getData().get("ingredient")).getValue(); + String itemIdentifier = entry.getData().getString("ingredient"); ItemMapping itemMapping = session.getItemMappings().getMapping(itemIdentifier); if (itemMapping == null) { // This should never happen so not sure what to do here. @@ -71,7 +69,7 @@ public final class TrimRecipe { public static TrimPattern readTrimPattern(GeyserSession session, RegistryEntry entry) { String key = stripNamespace(entry.getId()); - String itemIdentifier = ((StringTag) entry.getData().get("template_item")).getValue(); + String itemIdentifier = entry.getData().getString("template_item"); ItemMapping itemMapping = session.getItemMappings().getMapping(itemIdentifier); if (itemMapping == null) { // This should never happen so not sure what to do here. diff --git a/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java b/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java index d6324ba23..1021a5fb9 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java @@ -25,13 +25,6 @@ package org.geysermc.geyser.inventory.updater; -import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; -import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntMaps; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; @@ -53,7 +46,12 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.util.ItemUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket; +import java.util.Map; import java.util.Objects; public class AnvilInventoryUpdater extends InventoryUpdater { @@ -310,9 +308,9 @@ public class AnvilInventoryUpdater extends InventoryUpdater { */ private int calcMergeEnchantmentCost(GeyserSession session, GeyserItemStack input, GeyserItemStack material, boolean bedrock) { boolean hasCompatible = false; - Object2IntMap combinedEnchantments = getEnchantments(input, bedrock); + Object2IntMap combinedEnchantments = getEnchantments(input); int cost = 0; - for (Object2IntMap.Entry entry : getEnchantments(material, bedrock).object2IntEntrySet()) { + for (Object2IntMap.Entry entry : getEnchantments(material).object2IntEntrySet()) { JavaEnchantment enchantment = entry.getKey(); EnchantmentData data = Registries.ENCHANTMENTS.get(enchantment); if (data == null) { @@ -371,42 +369,26 @@ public class AnvilInventoryUpdater extends InventoryUpdater { return cost; } - private Object2IntMap getEnchantments(GeyserItemStack itemStack, boolean bedrock) { - if (itemStack.getNbt() == null) { - return Object2IntMaps.emptyMap(); - } - Object2IntMap enchantments = new Object2IntOpenHashMap<>(); - Tag enchantmentTag; + private Object2IntMap getEnchantments(GeyserItemStack itemStack) { + ItemEnchantments enchantmentComponent; if (isEnchantedBook(itemStack)) { - enchantmentTag = itemStack.getNbt().get("StoredEnchantments"); + enchantmentComponent = itemStack.getComponent(DataComponentType.STORED_ENCHANTMENTS); } else { - enchantmentTag = itemStack.getNbt().get("Enchantments"); + enchantmentComponent = itemStack.getComponent(DataComponentType.ENCHANTMENTS); } - if (enchantmentTag instanceof ListTag listTag) { - for (Tag tag : listTag.getValue()) { - if (tag instanceof CompoundTag enchantTag) { - if (enchantTag.get("id") instanceof StringTag javaEnchId) { - JavaEnchantment enchantment = JavaEnchantment.getByJavaIdentifier(javaEnchId.getValue()); - if (enchantment == null) { - GeyserImpl.getInstance().getLogger().debug("Unknown Java enchantment in anvil: " + javaEnchId.getValue()); - continue; - } - - Tag javaEnchLvl = enchantTag.get("lvl"); - if (javaEnchLvl == null || !(javaEnchLvl.getValue() instanceof Number number)) - continue; - - // Handle duplicate enchantments - if (bedrock) { - enchantments.putIfAbsent(enchantment, number.intValue()); - } else { - enchantments.mergeInt(enchantment, number.intValue(), Math::max); - } - } + if (enchantmentComponent != null) { + Object2IntMap enchantments = new Object2IntOpenHashMap<>(); + for (Map.Entry entry : enchantmentComponent.getEnchantments().entrySet()) { + JavaEnchantment enchantment = JavaEnchantment.of(entry.getKey()); + if (enchantment == null) { + GeyserImpl.getInstance().getLogger().debug("Unknown Java enchantment in anvil: " + entry.getKey()); + continue; } + enchantments.put(enchantment, entry.getValue().intValue()); } + return enchantments; } - return enchantments; + return Object2IntMaps.emptyMap(); } private boolean isEnchantedBook(GeyserItemStack itemStack) { diff --git a/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java b/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java index e884ecec5..eabdbee87 100644 --- a/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.item; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.IntTag; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; @@ -41,17 +39,4 @@ public interface DyeableLeatherItem { } builder.putInt("customColor", dyedItemColor.getRgb()); } - - static void translateNbtToJava(CompoundTag tag) { - IntTag color = tag.get("customColor"); - if (color == null) { - return; - } - CompoundTag displayTag = tag.get("display"); - if (displayTag == null) { - displayTag = new CompoundTag("display"); - } - displayTag.put(color); - tag.remove("customColor"); - } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java index fb9f35629..76f951c66 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java @@ -25,15 +25,12 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.data.TrimMaterial; import org.cloudburstmc.protocol.bedrock.data.TrimPattern; import org.geysermc.geyser.item.ArmorMaterial; -import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.mcprotocollib.protocol.data.game.item.component.ArmorTrim; @@ -70,19 +67,6 @@ public class ArmorItem extends Item { } } - @Override - public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { - super.translateNbtToJava(tag, mapping); - - if (tag.get("Trim") instanceof CompoundTag trim) { - StringTag material = trim.remove("Material"); - StringTag pattern = trim.remove("Pattern"); - // java has a lowercase key, and namespaced value - trim.put(new StringTag("material", "minecraft:" + material.getValue())); - trim.put(new StringTag("pattern", "minecraft:" + pattern.getValue())); - } - } - @Override public boolean isValidRepairItem(Item other) { return material.getRepairIngredient() == other; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java index f3c832a31..f2548e170 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java @@ -25,14 +25,16 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.StringTag; +import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; +import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.inventory.item.TippedArrowPotion; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; -import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.PotionContents; public class ArrowItem extends Item { public ArrowItem(String javaIdentifier, Builder builder) { @@ -40,13 +42,13 @@ public class ArrowItem extends Item { } @Override - public @NonNull ItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { + public @NonNull GeyserItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { TippedArrowPotion tippedArrowPotion = TippedArrowPotion.getByBedrockId(itemData.getDamage()); - ItemStack itemStack = super.translateToJava(itemData, mapping, mappings); + GeyserItemStack itemStack = super.translateToJava(itemData, mapping, mappings); if (tippedArrowPotion != null) { - itemStack = Items.TIPPED_ARROW.newItemStack(itemStack.getAmount(), itemStack.getDataComponents()); - StringTag potionTag = new StringTag("Potion", tippedArrowPotion.getJavaIdentifier()); - //itemStack.getDataComponents().put(DataComponentType.POTION_CONTENTS, new PotionContents()); + itemStack = Items.TIPPED_ARROW.newItemStack(itemStack.getAmount(), itemStack.getComponents()); + PotionContents contents = new PotionContents(tippedArrowPotion.ordinal(), -1, Int2ObjectMaps.emptyMap()); + itemStack.getOrCreateComponents().put(DataComponentType.POTION_CONTENTS, contents); } return itemStack; } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index 29a98e598..232f340ea 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.*; import it.unimi.dsi.fastutil.Pair; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtList; @@ -52,7 +51,7 @@ public class BannerItem extends BlockItem { * the correct ominous banner pattern if Bedrock pulls the item from creative. */ private static final List> OMINOUS_BANNER_PATTERN; - private static final ListTag OMINOUS_BANNER_PATTERN_BLOCK; + private static final List OMINOUS_BANNER_PATTERN_BLOCK; static { // Construct what an ominous banner is supposed to look like @@ -67,7 +66,7 @@ public class BannerItem extends BlockItem { Pair.of(BannerPattern.BORDER, DyeColor.BLACK) ); - OMINOUS_BANNER_PATTERN_BLOCK = new ListTag("patterns"); + OMINOUS_BANNER_PATTERN_BLOCK = new ArrayList<>(); for (Pair pair : OMINOUS_BANNER_PATTERN) { OMINOUS_BANNER_PATTERN_BLOCK.add(getJavaBannerPatternTag(pair.left(), pair.right())); } @@ -92,7 +91,7 @@ public class BannerItem extends BlockItem { return true; } - public static boolean isOminous(ListTag blockEntityPatterns) { + public static boolean isOminous(List blockEntityPatterns) { return OMINOUS_BANNER_PATTERN_BLOCK.equals(blockEntityPatterns); } @@ -102,10 +101,10 @@ public class BannerItem extends BlockItem { * @param patterns The patterns to convert * @return The new converted patterns */ - public static NbtList convertBannerPattern(ListTag patterns) { + public static NbtList convertBannerPattern(List patterns) { List tagsList = new ArrayList<>(); - for (Tag patternTag : patterns.getValue()) { - NbtMap bedrockBannerPattern = getBedrockBannerPattern((CompoundTag) patternTag); + for (NbtMap patternTag : patterns) { + NbtMap bedrockBannerPattern = getBedrockBannerPattern(patternTag); if (bedrockBannerPattern != null) { tagsList.add(bedrockBannerPattern); } @@ -120,9 +119,9 @@ public class BannerItem extends BlockItem { * @param pattern Java edition pattern nbt * @return The Bedrock edition format pattern nbt */ - private static NbtMap getBedrockBannerPattern(CompoundTag pattern) { - BannerPattern bannerPattern = BannerPattern.getByJavaIdentifier((String) pattern.get("pattern").getValue()); - DyeColor dyeColor = DyeColor.getByJavaIdentifier((String) pattern.get("color").getValue()); + private static NbtMap getBedrockBannerPattern(NbtMap pattern) { + BannerPattern bannerPattern = BannerPattern.getByJavaIdentifier(pattern.getString("pattern")); + DyeColor dyeColor = DyeColor.getByJavaIdentifier(pattern.getString("color")); if (bannerPattern == null || dyeColor == null) { return null; } @@ -133,11 +132,11 @@ public class BannerItem extends BlockItem { .build(); } - public static CompoundTag getJavaBannerPatternTag(BannerPattern bannerPattern, DyeColor dyeColor) { - CompoundTag tag = new CompoundTag(""); - tag.put(new StringTag("pattern", bannerPattern.getJavaIdentifier())); - tag.put(new StringTag("color", dyeColor.getJavaIdentifier())); - return tag; + public static NbtMap getJavaBannerPatternTag(BannerPattern bannerPattern, DyeColor dyeColor) { + return NbtMap.builder() + .putString("pattern", bannerPattern.getJavaIdentifier()) + .putString("color", dyeColor.getJavaIdentifier()) + .build(); } /** @@ -190,31 +189,14 @@ public class BannerItem extends BlockItem { } @Override - public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { // TODO - super.translateNbtToJava(tag, mapping); + public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) { // TODO + super.translateNbtToJava(bedrockTag, components, mapping); - if (tag.get("Type") instanceof IntTag type && type.getValue() == 1) { + if (bedrockTag.getInt("Type") == 1) { // Ominous banner pattern - tag.remove("Type"); - CompoundTag blockEntityTag = new CompoundTag("BlockEntityTag"); - blockEntityTag.put(OMINOUS_BANNER_PATTERN_BLOCK); - - tag.put(blockEntityTag); - } else if (tag.get("Patterns") instanceof ListTag patterns && patterns.getElementType() == CompoundTag.class) { - CompoundTag blockEntityTag = new CompoundTag("BlockEntityTag"); - - ListTag javaPatterns = new ListTag("patterns"); - for (Tag pattern : patterns.getValue()) { - BannerPattern bannerPattern = BannerPattern.getByBedrockIdentifier((String) ((CompoundTag) pattern).get("Pattern").getValue()); - DyeColor dyeColor = DyeColor.getById((int) ((CompoundTag) pattern).get("Color").getValue()); - if (bannerPattern != null && dyeColor != null) { - javaPatterns.add(getJavaBannerPatternTag(bannerPattern, dyeColor)); - } - } - blockEntityTag.put(javaPatterns); - - tag.put(blockEntityTag); - tag.remove("Patterns"); // Remove the old Bedrock patterns list + // TODO more registry stuff + //components.put(DataComponentType.BANNER_PATTERNS); } + // Bedrock's creative inventory does not support other patterns as of 1.20.5 } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java b/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java index aa34f76ba..712e75a23 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/CompassItem.java @@ -28,11 +28,11 @@ package org.geysermc.geyser.item.type; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; +import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; -import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import org.geysermc.mcprotocollib.protocol.data.game.item.component.LodestoneTracker; @@ -78,7 +78,7 @@ public class CompassItem extends Item { } @Override - public @NonNull ItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { + public @NonNull GeyserItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { if (mapping.getBedrockIdentifier().equals("minecraft:lodestone_compass")) { // Revert the entry back to the compass mapping = mappings.getStoredItems().compass(); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java index 9a10c701c..7e1181c4e 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/CrossbowItem.java @@ -25,10 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.ByteTag; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; @@ -63,22 +59,4 @@ public class CrossbowItem extends Item { builder.putCompound("chargedItem", newProjectile.build()); } } - - @Override - public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { - super.translateNbtToJava(tag, mapping); - - if (tag.get("chargedItem") != null) { - CompoundTag chargedItem = tag.get("chargedItem"); - - CompoundTag newProjectile = new CompoundTag(""); - newProjectile.put(new ByteTag("Count", (byte) chargedItem.get("Count").getValue())); - newProjectile.put(new StringTag("id", (String) chargedItem.get("Name").getValue())); - - ListTag chargedProjectiles = new ListTag("ChargedProjectiles"); - chargedProjectiles.add(newProjectile); - - tag.put(chargedProjectiles); - } - } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java index e57470607..d4bf838bd 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java @@ -25,11 +25,9 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.item.ArmorMaterial; import org.geysermc.geyser.item.DyeableLeatherItem; -import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; @@ -45,11 +43,4 @@ public class DyeableArmorItem extends ArmorItem implements DyeableLeatherItem { DyeableLeatherItem.translateComponentsToBedrock(components, builder); } - - @Override - public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { - super.translateNbtToJava(tag, mapping); - - DyeableLeatherItem.translateNbtToJava(tag); - } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java index 881598648..b50a3b847 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java @@ -25,10 +25,8 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.item.DyeableLeatherItem; -import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; @@ -44,11 +42,4 @@ public class DyeableHorseArmorItem extends Item implements DyeableLeatherItem { DyeableLeatherItem.translateComponentsToBedrock(components, builder); } - - @Override - public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { - super.translateNbtToJava(tag, mapping); - - DyeableLeatherItem.translateNbtToJava(tag); - } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java index 952967475..98e98b4b8 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java @@ -25,9 +25,14 @@ package org.geysermc.geyser.item.type; +import it.unimi.dsi.fastutil.ints.Int2IntMap; +import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtType; +import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.inventory.item.Enchantment; +import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; @@ -62,4 +67,29 @@ public class EnchantedBookItem extends Item { builder.putList("ench", NbtType.COMPOUND, bedrockEnchants); } } + + @Override + public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) { + super.translateNbtToJava(bedrockTag, components, mapping); + + List enchantmentTag = bedrockTag.getList("ench", NbtType.COMPOUND); + if (enchantmentTag != null) { + Int2IntMap javaEnchantments = new Int2IntOpenHashMap(enchantmentTag.size()); + for (NbtMap bedrockEnchantment : enchantmentTag) { + short bedrockId = bedrockEnchantment.getShort("id"); + + Enchantment enchantment = Enchantment.getByBedrockId(bedrockId); + if (enchantment != null) { + int level = bedrockEnchantment.getShort("lvl", (short) 1); + // TODO + javaEnchantments.put(Enchantment.JavaEnchantment.valueOf(enchantment.name()).ordinal(), level); + } else { + GeyserImpl.getInstance().getLogger().debug("Unknown bedrock enchantment: " + bedrockId); + } + } + if (!javaEnchantments.isEmpty()) { + components.put(DataComponentType.STORED_ENCHANTMENTS, new ItemEnchantments(javaEnchantments, true)); + } + } + } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java index e5656b494..1265956da 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java @@ -25,9 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.ByteTag; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.IntArrayTag; +import it.unimi.dsi.fastutil.ints.IntArrays; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -36,7 +34,6 @@ import org.geysermc.geyser.level.FireworkColor; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; -import org.geysermc.geyser.util.MathUtils; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import org.geysermc.mcprotocollib.protocol.data.game.item.component.Fireworks; @@ -73,8 +70,23 @@ public class FireworkRocketItem extends Item { } @Override - public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { - super.translateNbtToJava(tag, mapping); + public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) { + super.translateNbtToJava(bedrockTag, components, mapping); + + NbtMap fireworksTag = bedrockTag.getCompound("Fireworks"); + if (!fireworksTag.isEmpty()) { + List explosions = fireworksTag.getList("Explosions", NbtType.COMPOUND); + if (!explosions.isEmpty()) { + List javaExplosions = new ArrayList<>(); + for (NbtMap explosion : explosions) { + Fireworks.FireworkExplosion javaExplosion = translateExplosionToJava(explosion); + if (javaExplosion != null) { + javaExplosions.add(javaExplosion); + } + } + components.put(DataComponentType.FIREWORKS, new Fireworks(1, javaExplosions)); + } + } } static NbtMap translateExplosionToBedrock(Fireworks.FireworkExplosion explosion) { @@ -111,45 +123,22 @@ public class FireworkRocketItem extends Item { return newExplosionData.build(); } - static CompoundTag translateExplosionToJava(CompoundTag explosion, String newName) { - CompoundTag newExplosionData = new CompoundTag(newName); - - if (explosion.get("FireworkType") != null) { - newExplosionData.put(new ByteTag("Type", MathUtils.getNbtByte(explosion.get("FireworkType").getValue()))); - } - - if (explosion.get("FireworkColor") != null) { - byte[] oldColors = (byte[]) explosion.get("FireworkColor").getValue(); - int[] colors = new int[oldColors.length]; + /** + * The only thing that the Bedrock creative inventory has - as of 1.20.80 - is color. + */ + static Fireworks.FireworkExplosion translateExplosionToJava(NbtMap explosion) { + byte[] javaColors = explosion.getByteArray("FireworkColor", null); + if (javaColors != null) { + int[] colors = new int[javaColors.length]; int i = 0; - for (byte color : oldColors) { + for (byte color : javaColors) { colors[i++] = FireworkColor.fromBedrockId(color); } - newExplosionData.put(new IntArrayTag("Colors", colors)); + return new Fireworks.FireworkExplosion(0, colors, IntArrays.EMPTY_ARRAY, false, false); + } else { + return null; } - - if (explosion.get("FireworkFade") != null) { - byte[] oldColors = (byte[]) explosion.get("FireworkFade").getValue(); - int[] colors = new int[oldColors.length]; - - int i = 0; - for (byte color : oldColors) { - colors[i++] = FireworkColor.fromBedrockId(color); - } - - newExplosionData.put(new IntArrayTag("FadeColors", colors)); - } - - if (explosion.get("FireworkTrail") != null) { - newExplosionData.put(new ByteTag("Trail", MathUtils.getNbtByte(explosion.get("FireworkTrail").getValue()))); - } - - if (explosion.get("FireworkFlicker") != null) { - newExplosionData.put(new ByteTag("Flicker", MathUtils.getNbtByte(explosion.get("FireworkFlicker").getValue()))); - } - - return newExplosionData; } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java index ab6b7f300..18234975d 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; import org.geysermc.geyser.registry.type.ItemMapping; @@ -80,15 +78,16 @@ public class FireworkStarItem extends Item { } @Override - public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { - super.translateNbtToJava(tag, mapping); + public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) { + super.translateNbtToJava(bedrockTag, components, mapping); - Tag explosion = tag.remove("FireworksItem"); - if (explosion instanceof CompoundTag) { - CompoundTag newExplosion = FireworkRocketItem.translateExplosionToJava((CompoundTag) explosion, "Explosion"); - tag.put(newExplosion); + NbtMap explosion = bedrockTag.getCompound("FireworksItem"); + if (!explosion.isEmpty()) { + Fireworks.FireworkExplosion newExplosion = FireworkRocketItem.translateExplosionToJava(explosion); + if (newExplosion == null) { + return; + } + components.put(DataComponentType.FIREWORK_EXPLOSION, newExplosion); } - // Remove custom color, if any, since this only exists on Bedrock - tag.remove("customColor"); } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java index 0ff78676c..c31e15578 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java @@ -25,14 +25,12 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; -import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.mcprotocollib.protocol.data.game.Holder; -import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import org.geysermc.mcprotocollib.protocol.data.game.item.component.Instrument; @@ -80,18 +78,11 @@ public class GoatHornItem extends Item { } @Override - public @NonNull ItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { - ItemStack itemStack = super.translateToJava(itemData, mapping, mappings); + public @NonNull GeyserItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { + GeyserItemStack itemStack = super.translateToJava(itemData, mapping, mappings); int damage = itemData.getDamage(); - if (damage < 0 || damage >= INSTRUMENTS.size()) { - GeyserImpl.getInstance().getLogger().debug("Unknown goat horn instrument for damage: " + damage); - damage = 0; - } - - String instrument = INSTRUMENTS.get(damage); - StringTag instrumentTag = new StringTag("instrument", "minecraft:" + instrument); - //itemStack.getNbt().put(instrumentTag); + itemStack.getOrCreateComponents().put(DataComponentType.INSTRUMENT, Holder.ofId(damage)); return itemStack; } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/Item.java b/core/src/main/java/org/geysermc/geyser/item/type/Item.java index 64e2dcbc6..8fcb19ad5 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/Item.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/Item.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.*; import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -33,6 +32,7 @@ import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.inventory.item.Enchantment; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.registry.type.ItemMapping; @@ -44,7 +44,6 @@ import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.mcprotocollib.protocol.data.game.Identifier; -import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments; @@ -108,11 +107,8 @@ public class Item { return builder; } - public @NonNull ItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { - if (itemData.getTag() == null) { - return new ItemStack(javaId, itemData.getCount(), null); - } - return new ItemStack(javaId, itemData.getCount(), null/*ItemTranslator.translateToJavaNBT("", itemData.getTag())*/); + public @NonNull GeyserItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { + return GeyserItemStack.of(javaId, itemData.getCount()); } public ItemMapping toBedrockDefinition(DataComponents components, ItemMappings mappings) { @@ -162,57 +158,60 @@ public class Item { * * Therefore, if translation cannot be achieved for a certain item, it is not necessarily bad. */ - public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { - CompoundTag displayTag = tag.get("display"); - if (displayTag != null) { - if (displayTag.contains("Name")) { - StringTag nameTag = displayTag.get("Name"); - displayTag.put(new StringTag("Name", MessageTranslator.convertToJavaMessage(nameTag.getValue()))); - } + public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) { + // TODO see if any items from the creative menu need this +// CompoundTag displayTag = tag.get("display"); +// if (displayTag != null) { +// if (displayTag.contains("Name")) { +// StringTag nameTag = displayTag.get("Name"); +// displayTag.put(new StringTag("Name", MessageTranslator.convertToJavaMessage(nameTag.getValue()))); +// } +// +// if (displayTag.contains("Lore")) { +// ListTag loreTag = displayTag.get("Lore"); +// List lore = new ArrayList<>(); +// for (Tag subTag : loreTag.getValue()) { +// if (!(subTag instanceof StringTag)) continue; +// lore.add(new StringTag("", MessageTranslator.convertToJavaMessage(((StringTag) subTag).getValue()))); +// } +// displayTag.put(new ListTag("Lore", lore)); +// } +// } - if (displayTag.contains("Lore")) { - ListTag loreTag = displayTag.get("Lore"); - List lore = new ArrayList<>(); - for (Tag subTag : loreTag.getValue()) { - if (!(subTag instanceof StringTag)) continue; - lore.add(new StringTag("", MessageTranslator.convertToJavaMessage(((StringTag) subTag).getValue()))); - } - displayTag.put(new ListTag("Lore", lore)); - } - } - - ListTag enchantmentTag = tag.remove("ench"); - if (enchantmentTag != null) { - List enchantments = new ArrayList<>(); - for (Tag value : enchantmentTag.getValue()) { - if (!(value instanceof CompoundTag tagValue)) - continue; - - ShortTag bedrockId = tagValue.get("id"); - if (bedrockId == null) continue; - - Enchantment enchantment = Enchantment.getByBedrockId(bedrockId.getValue()); - if (enchantment != null) { - CompoundTag javaTag = new CompoundTag(""); - Map javaValue = javaTag.getValue(); - javaValue.put("id", new StringTag("id", enchantment.getJavaIdentifier())); - ShortTag levelTag = tagValue.get("lvl"); - javaValue.put("lvl", new IntTag("lvl", levelTag != null ? levelTag.getValue() : 1)); - javaTag.setValue(javaValue); - - enchantments.add(javaTag); - } else { - GeyserImpl.getInstance().getLogger().debug("Unknown bedrock enchantment: " + bedrockId); - } - } - if (!enchantments.isEmpty()) { - if ((this instanceof EnchantedBookItem)) { - tag.put(new ListTag("StoredEnchantments", enchantments)); - } else { - tag.put(new ListTag("Enchantments", enchantments)); - } - } - } + // TODO no creative item should have enchantments *except* enchanted books +// List enchantmentTag = bedrockTag.getList("ench", NbtType.COMPOUND); +// if (enchantmentTag != null) { +// List enchantments = new ArrayList<>(); +// for (Tag value : enchantmentTag.getValue()) { +// if (!(value instanceof CompoundTag tagValue)) +// continue; +// +// ShortTag bedrockId = tagValue.get("id"); +// if (bedrockId == null) continue; +// +// Enchantment enchantment = Enchantment.getByBedrockId(bedrockId.getValue()); +// if (enchantment != null) { +// CompoundTag javaTag = new CompoundTag(""); +// Map javaValue = javaTag.getValue(); +// javaValue.put("id", new StringTag("id", enchantment.getJavaIdentifier())); +// ShortTag levelTag = tagValue.get("lvl"); +// javaValue.put("lvl", new IntTag("lvl", levelTag != null ? levelTag.getValue() : 1)); +// javaTag.setValue(javaValue); +// +// enchantments.add(javaTag); +// } else { +// GeyserImpl.getInstance().getLogger().debug("Unknown bedrock enchantment: " + bedrockId); +// } +// } +// if (!enchantments.isEmpty()) { +// if ((this instanceof EnchantedBookItem)) { +// bedrockTag.put(new ListTag("StoredEnchantments", enchantments)); +// components.put(DataComponentType.STORED_ENCHANTMENTS, enchantments); +// } else { +// components.put(DataComponentType.ENCHANTMENTS, enchantments); +// } +// } +// } } protected final @Nullable NbtMap remapEnchantment(GeyserSession session, int enchantId, int level, BedrockItemBuilder builder) { @@ -243,8 +242,8 @@ public class Item { /* Translation methods end */ - public ItemStack newItemStack(int count, DataComponents components) { - return new ItemStack(this.javaId, count, components); + public GeyserItemStack newItemStack(int count, DataComponents components) { + return GeyserItemStack.of(this.javaId, count, components); } public void setJavaId(int javaId) { // TODO like this? diff --git a/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java b/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java index f6492a169..5d8a1667d 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/MapItem.java @@ -25,10 +25,7 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.IntTag; import org.checkerframework.checker.nullness.qual.NonNull; -import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; @@ -52,15 +49,4 @@ public class MapItem extends Item { builder.putInt("map_name_index", mapValue); builder.putByte("map_display_players", (byte) 1); } - - @Override - public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { - super.translateNbtToJava(tag, mapping); - - IntTag mapNameIndex = tag.remove("map_name_index"); - if (mapNameIndex != null) { - tag.put(new IntTag("map", mapNameIndex.getValue())); - tag.remove("map_uuid"); - } - } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java index 13d7ccd5e..b69f7d35f 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java @@ -25,16 +25,15 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.inventory.item.Potion; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.translator.item.CustomItemTranslator; -import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import org.geysermc.mcprotocollib.protocol.data.game.item.component.PotionContents; @@ -69,12 +68,11 @@ public class PotionItem extends Item { } @Override - public @NonNull ItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { + public @NonNull GeyserItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { Potion potion = Potion.getByBedrockId(itemData.getDamage()); - ItemStack itemStack = super.translateToJava(itemData, mapping, mappings); + GeyserItemStack itemStack = super.translateToJava(itemData, mapping, mappings); if (potion != null) { - StringTag potionTag = new StringTag("Potion", potion.getJavaIdentifier()); - //itemStack.getNbt().put(potionTag); + itemStack.getOrCreateComponents().put(DataComponentType.POTION_CONTENTS, potion.toComponent()); } return itemStack; } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java index 2f2f45c5b..6b2d589d6 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -85,12 +84,4 @@ public class ShulkerBoxItem extends BlockItem { } builder.putList("Items", NbtType.COMPOUND, itemsList); } - - @Override - public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { - super.translateNbtToJava(tag, mapping); - - // Remove any extraneous Bedrock tag and don't touch the Java one - tag.remove("Items"); - } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java index 8c00cb049..7c5ad26f6 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/TropicalFishBucketItem.java @@ -25,13 +25,12 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.TextDecoration; import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.nbt.NbtMap; import org.geysermc.geyser.entity.type.living.animal.TropicalFishEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.MinecraftLocale; @@ -58,26 +57,22 @@ public class TropicalFishBucketItem extends Item { builder.putString("CustomName", MinecraftLocale.getLocaleString("entity.minecraft.tropical_fish", session.locale())); // Add Java's client side lore tag // Do you know how frequently Java NBT used to be before 1.20.5? It was a lot. And now it's just this lowly check. - CompoundTag entityTag = components.get(DataComponentType.BUCKET_ENTITY_DATA); + NbtMap entityTag = components.get(DataComponentType.BUCKET_ENTITY_DATA); if (entityTag != null && !entityTag.isEmpty()) { //TODO test - Tag bucketVariant = entityTag.get("BucketVariantTag"); - if (bucketVariant == null || !(bucketVariant.getValue() instanceof Number)) { - return; - } + int bucketVariant = entityTag.getInt("BucketVariantTag"); List lore = builder.getOrCreateLore(); - int varNumber = ((Number) bucketVariant.getValue()).intValue(); - int predefinedVariantId = TropicalFishEntity.getPredefinedId(varNumber); + int predefinedVariantId = TropicalFishEntity.getPredefinedId(bucketVariant); if (predefinedVariantId != -1) { Component tooltip = Component.translatable("entity.minecraft.tropical_fish.predefined." + predefinedVariantId, LORE_STYLE); lore.add(0, MessageTranslator.convertMessage(tooltip, session.locale())); } else { - Component typeTooltip = Component.translatable("entity.minecraft.tropical_fish.type." + TropicalFishEntity.getVariantName(varNumber), LORE_STYLE); + Component typeTooltip = Component.translatable("entity.minecraft.tropical_fish.type." + TropicalFishEntity.getVariantName(bucketVariant), LORE_STYLE); lore.add(0, MessageTranslator.convertMessage(typeTooltip, session.locale())); - byte baseColor = TropicalFishEntity.getBaseColor(varNumber); - byte patternColor = TropicalFishEntity.getPatternColor(varNumber); + byte baseColor = TropicalFishEntity.getBaseColor(bucketVariant); + byte patternColor = TropicalFishEntity.getPatternColor(bucketVariant); Component colorTooltip = Component.translatable("color.minecraft." + TropicalFishEntity.getColorName(baseColor), LORE_STYLE); if (baseColor != patternColor) { colorTooltip = colorTooltip.append(Component.text(", ", LORE_STYLE)) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java index 097a5e65b..55ad16b20 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WritableBookItem.java @@ -25,15 +25,10 @@ package org.geysermc.geyser.item.type; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; -import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.text.MessageTranslator; @@ -69,24 +64,4 @@ public class WritableBookItem extends Item { builder.putList("pages", NbtType.COMPOUND, bedrockPages); } - - @Override - public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { - super.translateNbtToJava(tag, mapping); - - if (!tag.contains("pages")) { - return; - } - List pages = new ArrayList<>(); - ListTag pagesTag = tag.get("pages"); - for (Tag subTag : pagesTag.getValue()) { - if (!(subTag instanceof CompoundTag pageTag)) - continue; - - StringTag textTag = pageTag.get("text"); - pages.add(new StringTag("", textTag.getValue())); - } - tag.remove("pages"); - tag.put(new ListTag("pages", pages)); - } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java index a11c4f583..dd41a5e89 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/WrittenBookItem.java @@ -62,7 +62,7 @@ public class WrittenBookItem extends Item { for (Filterable page : bookContent.getPages()) { NbtMapBuilder pageBuilder = NbtMap.builder(); pageBuilder.putString("photoname", ""); - pageBuilder.putString("text", MessageTranslator.convertMessage(page.getRaw())); + pageBuilder.putString("text", MessageTranslator.convertMessage(session, page.getRaw())); bedrockPages.add(pageBuilder.build()); } builder.putList("pages", NbtType.COMPOUND, bedrockPages); @@ -70,6 +70,5 @@ public class WrittenBookItem extends Item { builder.putString("title", bookContent.getTitle().getRaw()) .putString("author", bookContent.getAuthor()) .putInt("generation", bookContent.getGeneration()); - // TODO isResolved } } diff --git a/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java b/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java index 27b2430bd..6112dc6cf 100644 --- a/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java +++ b/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java @@ -25,13 +25,9 @@ package org.geysermc.geyser.level; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.IntTag; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import org.cloudburstmc.nbt.NbtMap; import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; -import java.util.List; - /** * Represents the information we store from the current Java dimension * @param piglinSafe Whether piglins and hoglins are safe from conversion in this dimension. @@ -39,33 +35,16 @@ import java.util.List; */ public record JavaDimension(int minY, int maxY, boolean piglinSafe, double worldCoordinateScale) { - public static void load(List entries, Int2ObjectMap map) { - for (int i = 0; i < entries.size(); i++) { - RegistryEntry entry = entries.get(i); - CompoundTag dimension = entry.getData(); - int minY = ((IntTag) dimension.get("min_y")).getValue(); - int maxY = ((IntTag) dimension.get("height")).getValue(); - // Logical height can be ignored probably - seems to be for artificial limits like the Nether. - - // Set if piglins/hoglins should shake - boolean piglinSafe = ((Number) dimension.get("piglin_safe").getValue()).byteValue() != (byte) 0; - // Load world coordinate scale for the world border - double coordinateScale = ((Number) dimension.get("coordinate_scale").getValue()).doubleValue(); - - map.put(i, new JavaDimension(minY, maxY, piglinSafe, coordinateScale)); - } - } - public static JavaDimension read(RegistryEntry entry) { - CompoundTag dimension = entry.getData(); - int minY = ((IntTag) dimension.get("min_y")).getValue(); - int maxY = ((IntTag) dimension.get("height")).getValue(); + NbtMap dimension = entry.getData(); + int minY = dimension.getInt("min_y"); + int maxY = dimension.getInt("height"); // Logical height can be ignored probably - seems to be for artificial limits like the Nether. // Set if piglins/hoglins should shake - boolean piglinSafe = ((Number) dimension.get("piglin_safe").getValue()).byteValue() != (byte) 0; + boolean piglinSafe = dimension.getBoolean("piglin_safe"); // Load world coordinate scale for the world border - double coordinateScale = ((Number) dimension.get("coordinate_scale").getValue()).doubleValue(); + double coordinateScale = dimension.getDouble("coordinate_scale"); return new JavaDimension(minY, maxY, piglinSafe, coordinateScale); } diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java index f9515dbb4..50cdf4b5b 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java @@ -25,15 +25,13 @@ package org.geysermc.geyser.session.cache; -import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.GlobalPos; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.LodestoneTracker; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.GeyserItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.GlobalPos; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.LodestoneTracker; import java.util.Map; import java.util.WeakHashMap; @@ -54,17 +52,7 @@ public final class LodestoneCache { */ private int id = 1; - public void cacheInventoryItem(GeyserItemStack itemStack) { - DataComponents components = itemStack.getComponents(); - if (components == null) { - // invalid - return; - } - LodestoneTracker tracker = components.get(DataComponentType.LODESTONE_TRACKER); - if (tracker == null) { - return; - } - + public void cacheInventoryItem(GeyserItemStack itemStack, LodestoneTracker tracker) { GlobalPos position = tracker.getPos(); if (position == null) { diff --git a/core/src/main/java/org/geysermc/geyser/skin/SkinManager.java b/core/src/main/java/org/geysermc/geyser/skin/SkinManager.java index 33a51fe8f..4f3a94688 100644 --- a/core/src/main/java/org/geysermc/geyser/skin/SkinManager.java +++ b/core/src/main/java/org/geysermc/geyser/skin/SkinManager.java @@ -26,10 +26,9 @@ package org.geysermc.geyser.skin; import com.fasterxml.jackson.databind.JsonNode; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.Nullable; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.data.skin.ImageData; import org.cloudburstmc.protocol.bedrock.data.skin.SerializedSkin; import org.cloudburstmc.protocol.bedrock.packet.PlayerListPacket; @@ -45,6 +44,7 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.Collections; +import java.util.List; import java.util.UUID; import java.util.function.Consumer; @@ -224,22 +224,22 @@ public class SkinManager { * @param tag tag to build the GameProfileData from * @return The built GameProfileData, or null if this wasn't a valid tag */ - public static @Nullable GameProfileData from(CompoundTag tag) { - if (!(tag.get("Properties") instanceof CompoundTag propertiesTag)) { + public static @Nullable GameProfileData from(NbtMap tag) { + NbtMap properties = tag.getCompound("Properties", null); + if (properties == null) { return null; } - if (!(propertiesTag.get("textures") instanceof ListTag texturesTag) || texturesTag.size() == 0) { + List textures = properties.getList("textures", NbtType.COMPOUND); + if (textures.isEmpty()) { return null; } - if (!(texturesTag.get(0) instanceof CompoundTag texturesData)) { - return null; - } - if (!(texturesData.get("Value") instanceof StringTag skinDataValue)) { + String skinDataValue = textures.get(0).getString("Value", null); + if (skinDataValue == null) { return null; } try { - return loadFromJson(skinDataValue.getValue()); + return loadFromJson(skinDataValue); } catch (IOException e) { GeyserImpl.getInstance().getLogger().debug("Something went wrong while processing skin for tag " + tag); if (GeyserImpl.getInstance().getConfig().isDebugMode()) { diff --git a/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java b/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java index a85153d13..b2222d3b9 100644 --- a/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java +++ b/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java @@ -25,15 +25,14 @@ package org.geysermc.geyser.text; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.Style; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtType; import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; import java.util.EnumSet; +import java.util.List; import java.util.Locale; import java.util.Set; @@ -42,28 +41,28 @@ public final class TextDecoration { private final Style style; private final Set parameters; - public TextDecoration(CompoundTag tag) { - translationKey = (String) tag.get("translation_key").getValue(); + public TextDecoration(NbtMap tag) { + translationKey = tag.getString("translation_key"); - CompoundTag styleTag = tag.get("style"); + NbtMap styleTag = tag.getCompound("style"); Style.Builder builder = Style.style(); - if (styleTag != null) { - StringTag color = styleTag.get("color"); + if (!styleTag.isEmpty()) { + String color = styleTag.getString("color", null); if (color != null) { - builder.color(NamedTextColor.NAMES.value(color.getValue())); + builder.color(NamedTextColor.NAMES.value(color)); } //TODO implement the rest - Tag italic = styleTag.get("italic"); - if (italic != null && ((Number) italic.getValue()).byteValue() == (byte) 1) { + boolean italic = styleTag.getBoolean("italic"); + if (italic) { builder.decorate(net.kyori.adventure.text.format.TextDecoration.ITALIC); } } style = builder.build(); this.parameters = EnumSet.noneOf(Parameter.class); - ListTag parameters = tag.get("parameters"); - for (Tag parameter : parameters) { - this.parameters.add(Parameter.valueOf(((String) parameter.getValue()).toUpperCase(Locale.ROOT))); + List parameters = tag.getList("parameters", NbtType.STRING); + for (String parameter : parameters) { + this.parameters.add(Parameter.valueOf(parameter.toUpperCase(Locale.ROOT))); } } @@ -90,8 +89,8 @@ public final class TextDecoration { public static TextDecoration readChatType(RegistryEntry entry) { // Note: The ID is NOT ALWAYS THE SAME! ViaVersion as of 1.19 adds two registry entries that do NOT match vanilla. - CompoundTag tag = entry.getData(); - CompoundTag chat = tag.get("chat"); + NbtMap tag = entry.getData(); + NbtMap chat = tag.getCompound("chat", null); TextDecoration textDecoration = null; if (chat != null) { textDecoration = new TextDecoration(chat); diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java index 0914aeba8..5e4ffcafd 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java @@ -224,7 +224,7 @@ public abstract class InventoryTranslator { //only set the head if the destination is the head slot GeyserItemStack javaItem = inventory.getItem(sourceSlot); if (javaItem.asItem() == Items.PLAYER_HEAD - && javaItem.getNbt() != null) { + && javaItem.getComponents() != null) { FakeHeadProvider.setHead(session, session.getPlayerEntity(), javaItem.getComponents()); } } else if (sourceSlot == 5) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java index 142651eb4..7459ccf30 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java @@ -94,7 +94,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator { contents[i - 5] = item.getItemData(session); if (i == 5 && item.asItem() == Items.PLAYER_HEAD && - item.getNbt() != null) { + item.getComponents() != null) { FakeHeadProvider.setHead(session, session.getPlayerEntity(), item.getComponents()); } } @@ -138,7 +138,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator { if (slot == 5) { // Check for custom skull if (javaItem.asItem() == Items.PLAYER_HEAD - && javaItem.getNbt() != null) { + && javaItem.getComponents() != null) { FakeHeadProvider.setHead(session, session.getPlayerEntity(), javaItem.getComponents()); } else { FakeHeadProvider.restoreOriginalSkin(session, session.getPlayerEntity()); diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java index 543f519c9..f9879499a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java @@ -58,7 +58,7 @@ public class ShulkerInventoryTranslator extends AbstractBlockInventoryTranslator .putInt("z", position.getZ()) .putString("CustomName", inventory.getTitle()); // Don't reset facing property - shulkerBoxTranslator.translateTag(tag, null, javaBlockState); + shulkerBoxTranslator.translateTag(session, tag, null, javaBlockState); BlockEntityDataPacket dataPacket = new BlockEntityDataPacket(); dataPacket.setData(tag.build()); diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index 24362f800..df54eff79 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -29,22 +29,11 @@ import com.github.steveice10.mc.auth.data.GameProfile; import com.github.steveice10.mc.auth.data.GameProfile.Texture; import com.github.steveice10.mc.auth.data.GameProfile.TextureType; import com.github.steveice10.mc.auth.exception.property.PropertyException; -import org.geysermc.mcprotocollib.protocol.data.game.Identifier; -import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.ModifierOperation; -import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.AdventureModePredicate; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemAttributeModifiers; -import com.github.steveice10.opennbt.tag.builtin.*; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; -import org.cloudburstmc.nbt.NbtList; import org.cloudburstmc.nbt.NbtMap; -import org.cloudburstmc.nbt.NbtMapBuilder; -import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; @@ -63,6 +52,13 @@ import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.util.InventoryUtils; +import org.geysermc.mcprotocollib.protocol.data.game.Identifier; +import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.ModifierOperation; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.AdventureModePredicate; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemAttributeModifiers; import java.text.DecimalFormat; import java.util.ArrayList; @@ -93,16 +89,17 @@ public final class ItemTranslator { ItemMapping bedrockItem = mappings.getMapping(data); Item javaItem = bedrockItem.getJavaItem(); - ItemStack itemStack = javaItem.translateToJava(data, bedrockItem, mappings); + GeyserItemStack itemStack = javaItem.translateToJava(data, bedrockItem, mappings); -// if (itemStack.getNbt() != null) { -// javaItem.translateNbtToJava(itemStack.getNbt(), bedrockItem); -// if (itemStack.getNbt().isEmpty()) { -// // Otherwise, seems to cause issues with villagers accepting books, and I don't see how this will break anything else. - Camotoy -// itemStack = new ItemStack(itemStack.getId(), itemStack.getAmount(), null); -// } -// } - return itemStack; + NbtMap nbt = data.getTag(); + if (nbt != null && !nbt.isEmpty()) { + DataComponents components = new DataComponents(new HashMap<>()); + javaItem.translateNbtToJava(nbt, components, bedrockItem); + if (!components.getDataComponents().isEmpty()) { + itemStack.setComponents(components); + } + } + return itemStack.getItemStack(); } public static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, int javaId, int count, DataComponents components) { @@ -375,125 +372,6 @@ public final class ItemTranslator { } } - public static NbtMap translateNbtToBedrock(CompoundTag tag) { - if (!tag.getValue().isEmpty()) { - NbtMapBuilder builder = NbtMap.builder(); - for (Tag javaTag : tag.values()) { - Object translatedTag = translateToBedrockNBT(javaTag); - if (translatedTag == null) - continue; - - builder.put(javaTag.getName(), translatedTag); - } - return builder.build(); - } - return NbtMap.EMPTY; - } - - private static @Nullable Object translateToBedrockNBT(Tag tag) { - if (tag instanceof CompoundTag compoundTag) { - return translateNbtToBedrock(compoundTag); - } - - if (tag instanceof ListTag listTag) { - List tagList = new ArrayList<>(); - for (Tag value : listTag) { - tagList.add(translateToBedrockNBT(value)); - } - NbtType type = NbtType.COMPOUND; - if (!tagList.isEmpty()) { - type = NbtType.byClass(tagList.get(0).getClass()); - } - //noinspection unchecked,rawtypes - return new NbtList(type, tagList); - } - - if (tag instanceof LongArrayTag) { - //Long array tag does not exist in BE - //LongArrayTag longArrayTag = (LongArrayTag) tag; - //return new org.cloudburstmc.nbt.tag.LongArrayTag(longArrayTag.getName(), longArrayTag.getValue()); - return null; - } - - return tag.getValue(); - } - - public static CompoundTag translateToJavaNBT(String name, NbtMap tag) { - CompoundTag javaTag = new CompoundTag(name); - Map javaValue = javaTag.getValue(); - if (tag != null && !tag.isEmpty()) { - for (Map.Entry entry : tag.entrySet()) { - Tag translatedTag = translateToJavaNBT(entry.getKey(), entry.getValue()); - if (translatedTag == null) - continue; - - javaValue.put(translatedTag.getName(), translatedTag); - } - } - - javaTag.setValue(javaValue); - return javaTag; - } - - private static @Nullable Tag translateToJavaNBT(String name, Object object) { - if (object instanceof int[]) { - return new IntArrayTag(name, (int[]) object); - } - - if (object instanceof byte[]) { - return new ByteArrayTag(name, (byte[]) object); - } - - if (object instanceof Byte) { - return new ByteTag(name, (byte) object); - } - - if (object instanceof Float) { - return new FloatTag(name, (float) object); - } - - if (object instanceof Double) { - return new DoubleTag(name, (double) object); - } - - if (object instanceof Integer) { - return new IntTag(name, (int) object); - } - - if (object instanceof long[]) { - return new LongArrayTag(name, (long[]) object); - } - - if (object instanceof Long) { - return new LongTag(name, (long) object); - } - - if (object instanceof Short) { - return new ShortTag(name, (short) object); - } - - if (object instanceof String) { - return new StringTag(name, (String) object); - } - - if (object instanceof List) { - List tags = new ArrayList<>(); - - for (Object value : (List) object) { - Tag javaTag = translateToJavaNBT("", value); - if (javaTag != null) - tags.add(javaTag); - } - return new ListTag(name, tags); - } - - if (object instanceof NbtMap map) { - return translateToJavaNBT(name, map); - } - - return null; - } - /** * Translates the display name of the item * @param session the Bedrock client's session diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java index bc08dd93b..c87d1a217 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java @@ -25,40 +25,43 @@ package org.geysermc.geyser.translator.level.block.entity; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.item.type.BannerItem; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; + +import java.util.List; @BlockEntity(type = BlockEntityType.BANNER) public class BannerBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { int bannerColor = BlockStateValues.getBannerColor(blockState); if (bannerColor != -1) { - builder.put("Base", 15 - bannerColor); + bedrockNbt.putInt("Base", 15 - bannerColor); } - if (tag == null) { + if (javaNbt == null) { return; } - if (tag.get("patterns") instanceof ListTag patterns) { + List patterns = javaNbt.getList("patterns", NbtType.COMPOUND); + if (!patterns.isEmpty()) { if (BannerItem.isOminous(patterns)) { // This is an ominous banner; don't try to translate the raw patterns (it doesn't translate correctly) // and tell the Bedrock client that this is an ominous banner - builder.putInt("Type", 1); + bedrockNbt.putInt("Type", 1); } else { - builder.put("Patterns", BannerItem.convertBannerPattern(patterns)); + bedrockNbt.putList("Patterns", NbtType.COMPOUND, BannerItem.convertBannerPattern(patterns)); } } - Tag customName = tag.get("CustomName"); + String customName = javaNbt.getString("CustomName", null); if (customName != null) { - builder.put("CustomName", customName.getValue()); + bedrockNbt.putString("CustomName", customName); } } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BeaconBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BeaconBlockEntityTranslator.java index 0db362949..f7dee2864 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BeaconBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BeaconBlockEntityTranslator.java @@ -25,18 +25,19 @@ package org.geysermc.geyser.translator.level.block.entity; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.BEACON) public class BeaconBlockEntityTranslator extends BlockEntityTranslator { @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { - int primary = getOrDefault(tag.get("Primary"), 0); + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + int primary = javaNbt.getInt("primary"); // The effects here generally map one-to-one Java <-> Bedrock. Only the newer ones get more complicated - builder.putInt("primary", primary == -1 ? 0 : primary); - int secondary = getOrDefault(tag.get("Secondary"), 0); - builder.putInt("secondary", secondary == -1 ? 0 : secondary); + bedrockNbt.putInt("primary", primary == -1 ? 0 : primary); + int secondary = javaNbt.getInt("secondary"); + bedrockNbt.putInt("secondary", secondary == -1 ? 0 : secondary); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedBlockEntityTranslator.java index 1c46edf0a..720ffea3c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedBlockEntityTranslator.java @@ -25,20 +25,21 @@ package org.geysermc.geyser.translator.level.block.entity; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.BED) public class BedBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { byte bedcolor = BlockStateValues.getBedColor(blockState); // Just in case... if (bedcolor == -1) { bedcolor = 0; } - builder.put("color", bedcolor); + bedrockNbt.putByte("color", bedcolor); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java index 5f6487a24..45981377c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java @@ -25,13 +25,11 @@ package org.geysermc.geyser.translator.level.block.entity; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.BlockEntityUtils; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; /** * The class that all block entities (on both Java and Bedrock) should translate with @@ -40,11 +38,11 @@ public abstract class BlockEntityTranslator { protected BlockEntityTranslator() { } - public abstract void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState); + public abstract void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState); - public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, CompoundTag tag, int blockState) { + public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, NbtMap javaNbt, int blockState) { NbtMapBuilder tagBuilder = getConstantBedrockTag(type, x, y, z); - translateTag(tagBuilder, tag, blockState); + translateTag(session, tagBuilder, javaNbt, blockState); return tagBuilder.build(); } @@ -59,9 +57,4 @@ public abstract class BlockEntityTranslator { .putInt("z", z) .putString("id", bedrockId); } - - @SuppressWarnings("unchecked") - protected T getOrDefault(Tag tag, T defaultValue) { - return (tag != null && tag.getValue() != null) ? (T) tag.getValue() : defaultValue; - } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java index d2777d372..4f9dfec46 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java @@ -25,49 +25,46 @@ package org.geysermc.geyser.translator.level.block.entity; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.level.block.BlockStateValues; -import org.geysermc.geyser.network.GameProtocol; -import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.ItemMapping; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.BRUSHABLE_BLOCK) public class BrushableBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { - if (!(tag.remove("item") instanceof CompoundTag itemTag)) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + NbtMap itemTag = javaNbt.getCompound("item"); + if (itemTag.isEmpty()) { return; } - Tag hitDirection = tag.get("hit_direction"); - if (hitDirection == null) { + byte hitDirection = javaNbt.getByte("hit_direction", (byte) -1); + if (hitDirection == -1) { // java server sends no direction when the item recedes back into the block (if player stops brushing) return; } - String id = ((StringTag) itemTag.get("id")).getValue(); + String id = itemTag.getString("id"); if (Items.AIR.javaIdentifier().equals(id)) { return; // server sends air when the block contains nothing } - ItemMapping mapping = Registries.ITEMS.forVersion(GameProtocol.DEFAULT_BEDROCK_CODEC.getProtocolVersion()).getMapping(id); + ItemMapping mapping = session.getItemMappings().getMapping(id); if (mapping == null) { return; } NbtMapBuilder itemBuilder = NbtMap.builder() .putString("Name", mapping.getBedrockIdentifier()) - .putByte("Count", (byte) itemTag.get("Count").getValue()); + .putByte("Count", (byte) itemTag.getByte("Count")); - builder.putCompound("item", itemBuilder.build()); + bedrockNbt.putCompound("item", itemBuilder.build()); // controls which side the item protrudes from - builder.putByte("brush_direction", ((Number) hitDirection.getValue()).byteValue()); + bedrockNbt.putByte("brush_direction", hitDirection); // controls how much the item protrudes - builder.putInt("brush_count", BlockStateValues.getBrushProgress(blockState)); + bedrockNbt.putInt("brush_count", BlockStateValues.getBrushProgress(blockState)); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CampfireBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CampfireBlockEntityTranslator.java index 390615b9e..699319bb6 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CampfireBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CampfireBlockEntityTranslator.java @@ -25,37 +25,37 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; -import org.geysermc.geyser.network.GameProtocol; -import org.geysermc.geyser.registry.Registries; +import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.registry.type.ItemMapping; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; +import java.util.List; + @BlockEntity(type = BlockEntityType.CAMPFIRE) public class CampfireBlockEntityTranslator extends BlockEntityTranslator { @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { - if (tag.get("Items") instanceof ListTag items) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + List items = javaNbt.getList("Items", NbtType.COMPOUND); + if (items != null) { int i = 1; - for (Tag itemTag : items.getValue()) { - builder.put("Item" + i, getItem((CompoundTag) itemTag)); + for (NbtMap itemTag : items) { + bedrockNbt.put("Item" + i, getItem(session, itemTag)); i++; } } } - protected NbtMap getItem(CompoundTag tag) { - // TODO: Version independent mappings - ItemMapping mapping = Registries.ITEMS.forVersion(GameProtocol.DEFAULT_BEDROCK_CODEC.getProtocolVersion()).getMapping((String) tag.get("id").getValue()); - NbtMapBuilder tagBuilder = NbtMap.builder() - .putString("Name", mapping.getBedrockIdentifier()) - .putByte("Count", (byte) tag.get("Count").getValue()) - .putShort("Damage", (short) mapping.getBedrockData()); - tagBuilder.put("tag", NbtMap.builder().build()); + protected NbtMap getItem(GeyserSession session, NbtMap tag) { + ItemMapping mapping = session.getItemMappings().getMapping(tag.getString("id")); + if (mapping == null) { + mapping = ItemMapping.AIR; + } + NbtMapBuilder tagBuilder = BedrockItemBuilder.createItemNbt(mapping, tag.getByte("Count"), mapping.getBedrockData()); + tagBuilder.put("tag", NbtMap.builder().build()); // I don't think this is necessary... - Camo, 1.20.5/1.20.80 return tagBuilder.build(); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CommandBlockBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CommandBlockBlockEntityTranslator.java index 31a7dbc69..0e00a19a8 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CommandBlockBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CommandBlockBlockEntityTranslator.java @@ -25,34 +25,31 @@ package org.geysermc.geyser.translator.level.block.entity; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; -import com.github.steveice10.opennbt.tag.builtin.*; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.text.MessageTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.COMMAND_BLOCK) public class CommandBlockBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { - if (tag == null || tag.size() < 5) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + if (javaNbt == null || javaNbt.size() < 5) { return; // These values aren't here } // Java infers from the block state, but Bedrock needs it in the tag - builder.put("conditionalMode", BlockStateValues.getCommandBlockValues().getOrDefault(blockState, (byte) 0)); + bedrockNbt.putByte("conditionalMode", BlockStateValues.getCommandBlockValues().getOrDefault(blockState, (byte) 0)); // Java and Bedrock values - builder.put("conditionMet", ((ByteTag) tag.get("conditionMet")).getValue()); - builder.put("auto", ((ByteTag) tag.get("auto")).getValue()); - builder.put("CustomName", MessageTranslator.convertJsonMessage(((StringTag) tag.get("CustomName")).getValue())); - builder.put("powered", ((ByteTag) tag.get("powered")).getValue()); - builder.put("Command", ((StringTag) tag.get("Command")).getValue()); - builder.put("SuccessCount", ((IntTag) tag.get("SuccessCount")).getValue()); - builder.put("TrackOutput", ((ByteTag) tag.get("TrackOutput")).getValue()); - builder.put("UpdateLastExecution", ((ByteTag) tag.get("UpdateLastExecution")).getValue()); - if (tag.get("LastExecution") != null) { - builder.put("LastExecution", ((LongTag) tag.get("LastExecution")).getValue()); - } else { - builder.put("LastExecution", (long) 0); - } + bedrockNbt.putByte("conditionMet", javaNbt.getByte("conditionMet")); + bedrockNbt.putByte("auto", javaNbt.getByte("auto")); + bedrockNbt.putString("CustomName", MessageTranslator.convertJsonMessage(javaNbt.getString("CustomName"), session.locale())); + bedrockNbt.putByte("powered", javaNbt.getByte("powered")); + bedrockNbt.putString("Command", javaNbt.getString("Command")); + bedrockNbt.putInt("SuccessCount", javaNbt.getInt("SuccessCount")); + bedrockNbt.putByte("TrackOutput", javaNbt.getByte("TrackOutput")); + bedrockNbt.putByte("UpdateLastExecution", javaNbt.getByte("UpdateLastExecution")); + bedrockNbt.putLong("LastExecution", javaNbt.getLong("LastExecution")); // Note: may not be present? Was a null check before 1.20.5 } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java index 3ab61c489..b24558b45 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java @@ -25,33 +25,22 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; +import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; -import java.util.ArrayList; -import java.util.List; - @BlockEntity(type = BlockEntityType.DECORATED_POT) public class DecoratedPotBlockEntityTranslator extends BlockEntityTranslator { @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { - if (tag == null) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + if (javaNbt == null) { return; } // exact same format - if (tag.get("sherds") instanceof ListTag sherds) { - List translated = new ArrayList<>(4); - for (Tag sherd : sherds) { - translated.add(((StringTag) sherd).getValue()); - } - builder.putList("sherds", NbtType.STRING, translated); - } + bedrockNbt.putList("sherds", NbtType.STRING, javaNbt.getList("sherds", NbtType.STRING)); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java index 141520ed9..dcb39d22c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.cloudburstmc.math.vector.Vector3i; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.DoubleChestValue; @@ -47,17 +47,17 @@ public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator impl @Override public void updateBlock(GeyserSession session, int blockState, Vector3i position) { NbtMapBuilder tagBuilder = getConstantBedrockTag(BlockEntityUtils.getBedrockBlockEntityId(BlockEntityType.CHEST), position.getX(), position.getY(), position.getZ()); - translateTag(tagBuilder, null, blockState); + translateTag(session, tagBuilder, null, blockState); BlockEntityUtils.updateBlockEntity(session, tagBuilder.build(), position); } @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { DoubleChestValue chestValues = BlockStateValues.getDoubleChestValues().get(blockState); if (chestValues != null) { - int x = (int) builder.get("x"); - int z = (int) builder.get("z"); - translateChestValue(builder, chestValues, x, z); + int x = (int) bedrockNbt.get("x"); + int z = (int) bedrockNbt.get("z"); + translateChestValue(bedrockNbt, chestValues, x, z); } } @@ -88,10 +88,10 @@ public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator impl x = x + (chestValues.isLeft() ? 1 : -1); } } - builder.put("pairx", x); - builder.put("pairz", z); + builder.putInt("pairx", x); + builder.putInt("pairz", z); if (!chestValues.isLeft()) { - builder.put("pairlead", (byte) 1); + builder.putInt("pairlead", (byte) 1); } } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EmptyBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EmptyBlockEntityTranslator.java index 1a7958c62..9ce0aff0a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EmptyBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EmptyBlockEntityTranslator.java @@ -25,11 +25,12 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; +import org.geysermc.geyser.session.GeyserSession; public class EmptyBlockEntityTranslator extends BlockEntityTranslator { @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EndGatewayBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EndGatewayBlockEntityTranslator.java index 633992431..97428eec1 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EndGatewayBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EndGatewayBlockEntityTranslator.java @@ -25,44 +25,28 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.IntTag; -import com.github.steveice10.opennbt.tag.builtin.LongTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; import org.cloudburstmc.nbt.NbtList; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; +import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; -import java.util.LinkedHashMap; - @BlockEntity(type = BlockEntityType.END_GATEWAY) public class EndGatewayBlockEntityTranslator extends BlockEntityTranslator { @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { - Tag ageTag = tag.get("Age"); - if (ageTag instanceof LongTag) { - builder.put("Age", (int) ((long) ageTag.getValue())); - } + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + bedrockNbt.putInt("Age", (int) javaNbt.getLong("Age")); // Java sometimes does not provide this tag, but Bedrock crashes if it doesn't exist // Linked coordinates IntList tagsList = new IntArrayList(); // Yes, the axis letters are capitalized - tagsList.add(getExitPortalCoordinate(tag, "X")); - tagsList.add(getExitPortalCoordinate(tag, "Y")); - tagsList.add(getExitPortalCoordinate(tag, "Z")); - builder.put("ExitPortal", new NbtList<>(NbtType.INT, tagsList)); - } - - private int getExitPortalCoordinate(CompoundTag tag, String axis) { - // Return 0 if it doesn't exist, otherwise give proper value - if (tag.get("ExitPortal") != null) { - LinkedHashMap compoundTag = (LinkedHashMap) tag.get("ExitPortal").getValue(); - IntTag intTag = (IntTag) compoundTag.get(axis); - return intTag.getValue(); - } - return 0; + NbtMap exitPortal = javaNbt.getCompound("ExitPortal"); + tagsList.add(exitPortal.getInt("X", 0)); + tagsList.add(exitPortal.getInt("Y", 0)); + tagsList.add(exitPortal.getInt( "Z", 0)); + bedrockNbt.put("ExitPortal", new NbtList<>(NbtType.INT, tagsList)); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java index 34c051a34..bd83e3d54 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java @@ -25,28 +25,27 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.JIGSAW) public class JigsawBlockBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { - Tag jointTag = tag.get("joint"); - if (jointTag instanceof StringTag) { - builder.put("joint", ((StringTag) jointTag).getValue()); + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + String joint = javaNbt.getString("joint", null); + if (joint != null) { + bedrockNbt.putString("joint", joint); } else { // Tag is not present in at least 1.14.4 Paper // Minecraft 1.18.1 deliberately has a fallback here, but not for any other value - builder.put("joint", BlockStateValues.getHorizontalFacingJigsaws().contains(blockState) ? "aligned" : "rollable"); + bedrockNbt.putString("joint", BlockStateValues.getHorizontalFacingJigsaws().contains(blockState) ? "aligned" : "rollable"); } - builder.put("name", getOrDefault(tag.get("name"), "")); - builder.put("target_pool", getOrDefault(tag.get("pool"), "")); - builder.put("final_state", ((StringTag) tag.get("final_state")).getValue()); - builder.put("target", getOrDefault(tag.get("target"), "")); + bedrockNbt.putString("name", javaNbt.getString("name")); + bedrockNbt.putString("target_pool", javaNbt.getString("target_pool")); + bedrockNbt.putString("final_state", javaNbt.getString("final_state")); + bedrockNbt.putString("target", javaNbt.getString("target")); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/ShulkerBoxBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/ShulkerBoxBlockEntityTranslator.java index 529ed731e..ba2ddd815 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/ShulkerBoxBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/ShulkerBoxBlockEntityTranslator.java @@ -25,10 +25,11 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.checkerframework.checker.nullness.qual.Nullable; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.inventory.ShulkerInventoryTranslator; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @@ -39,12 +40,12 @@ public class ShulkerBoxBlockEntityTranslator extends BlockEntityTranslator imple * where {@code tag} is passed as null. */ @Override - public void translateTag(NbtMapBuilder builder, @Nullable CompoundTag tag, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, @Nullable NbtMap javaNbt, int blockState) { byte direction = BlockStateValues.getShulkerBoxDirection(blockState); // Just in case... if (direction == -1) { direction = 1; } - builder.put("facing", direction); + bedrockNbt.putByte("facing", direction); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SignBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SignBlockEntityTranslator.java index 38a4f59c5..bbf0dbcb3 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SignBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SignBlockEntityTranslator.java @@ -25,15 +25,16 @@ package org.geysermc.geyser.translator.level.block.entity; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.nbt.NbtType; +import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.util.SignUtils; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; + +import java.util.List; @BlockEntity(type = BlockEntityType.SIGN) public class SignBlockEntityTranslator extends BlockEntityTranslator { @@ -72,25 +73,21 @@ public class SignBlockEntityTranslator extends BlockEntityTranslator { } @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { - builder.putCompound("FrontText", translateSide(tag.get("front_text"))); - builder.putCompound("BackText", translateSide(tag.get("back_text"))); - var waxed = tag.get("is_waxed"); - builder.putBoolean("IsWaxed", waxed != null && waxed.getValue() instanceof Number number && number.byteValue() != 0); + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + bedrockNbt.putCompound("FrontText", translateSide(javaNbt.getCompound("front_text"))); + bedrockNbt.putCompound("BackText", translateSide(javaNbt.getCompound("back_text"))); + bedrockNbt.putBoolean("IsWaxed", javaNbt.getBoolean("is_waxed")); } - private NbtMap translateSide(Tag tag) { - if (!(tag instanceof CompoundTag signData)) { - return NbtMap.EMPTY; - } + private NbtMap translateSide(NbtMap javaNbt) { NbtMapBuilder builder = NbtMap.builder(); StringBuilder signText = new StringBuilder(); - Tag messages = signData.get("messages"); - if (messages instanceof ListTag listTag) { - var it = listTag.iterator(); + List messages = javaNbt.getList("messages", NbtType.STRING); + if (!messages.isEmpty()) { + var it = messages.iterator(); while (it.hasNext()) { - String signLine = (String) it.next().getValue(); + String signLine = it.next(); signLine = MessageTranslator.convertMessageLenient(signLine); // Check the character width on the sign to ensure there is no overflow that is usually hidden @@ -133,13 +130,13 @@ public class SignBlockEntityTranslator extends BlockEntityTranslator { builder.putString("Text", signText.toString()); // Java Edition 1.14 added the ability to change the text color of the whole sign using dye - Tag color = signData.get("color"); + String color = javaNbt.getString("color", null); if (color != null) { - builder.putInt("SignTextColor", getBedrockSignColor(color.getValue().toString())); + builder.putInt("SignTextColor", getBedrockSignColor(color)); } // Glowing text - boolean isGlowing = getOrDefault(signData.get("has_glowing_text"), (byte) 0) != (byte) 0; + boolean isGlowing = javaNbt.getBoolean("has_glowing_text"); builder.putBoolean("IgnoreLighting", isGlowing); return builder.build(); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java index 38a056bd0..b1ab017e8 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java @@ -25,24 +25,22 @@ package org.geysermc.geyser.translator.level.block.entity; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.IntArrayTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; import org.checkerframework.checker.nullness.qual.Nullable; +import org.cloudburstmc.math.vector.Vector3i; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; import org.geysermc.geyser.GeyserImpl; -import org.cloudburstmc.math.vector.Vector3i; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.SkullCache; import org.geysermc.geyser.skin.SkinProvider; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import java.nio.charset.StandardCharsets; -import java.util.LinkedHashMap; +import java.util.List; import java.util.Locale; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -52,56 +50,60 @@ import java.util.concurrent.ExecutionException; public class SkullBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { byte skullVariant = BlockStateValues.getSkullVariant(blockState); float rotation = BlockStateValues.getSkullRotation(blockState) * 22.5f; // Just in case... if (skullVariant == -1) { skullVariant = 0; } - builder.put("Rotation", rotation); - builder.put("SkullType", skullVariant); + bedrockNbt.putFloat("Rotation", rotation); + bedrockNbt.putByte("SkullType", skullVariant); if (BlockStateValues.isSkullPowered(blockState)) { - builder.putBoolean("MouthMoving", true); + bedrockNbt.putBoolean("MouthMoving", true); } } - private static UUID getUUID(CompoundTag profile) { - if (profile.get("id") instanceof IntArrayTag uuidTag && uuidTag.length() == 4) { - int[] uuidAsArray = uuidTag.getValue(); + private static UUID getUUID(NbtMap profile) { + int[] uuidAsArray = profile.getIntArray("id"); + if (uuidAsArray.length == 4) { // thank u viaversion return new UUID((long) uuidAsArray[0] << 32 | ((long) uuidAsArray[1] & 0xFFFFFFFFL), (long) uuidAsArray[2] << 32 | ((long) uuidAsArray[3] & 0xFFFFFFFFL)); } // Convert username to an offline UUID String username = null; - if (profile.get("name") instanceof StringTag nameTag) { - username = nameTag.getValue().toLowerCase(Locale.ROOT); + String nameTag = profile.getString("name", null); + if (nameTag != null) { + username = nameTag.toLowerCase(Locale.ROOT); } return UUID.nameUUIDFromBytes(("OfflinePlayer:" + username).getBytes(StandardCharsets.UTF_8)); } - private static CompletableFuture getTextures(CompoundTag profile, UUID uuid) { - ListTag properties = profile.get("properties"); - if (properties == null) { + private static CompletableFuture<@Nullable String> getTextures(NbtMap profile, UUID uuid) { + List properties = profile.getList("properties", NbtType.COMPOUND); + if (properties.isEmpty()) { if (uuid != null && uuid.version() == 4) { String uuidString = uuid.toString().replace("-", ""); return SkinProvider.requestTexturesFromUUID(uuidString); - } else if (profile.get("name") instanceof StringTag nameTag) { - // Fall back to username if UUID was missing or was an offline mode UUID - return SkinProvider.requestTexturesFromUsername(nameTag.getValue()); + } else { + String nameTag = profile.getString("name", null); + if (nameTag != null) { + // Fall back to username if UUID was missing or was an offline mode UUID + return SkinProvider.requestTexturesFromUsername(nameTag); + } } return CompletableFuture.completedFuture(null); } - LinkedHashMap tag1 = (LinkedHashMap) properties.get(0).getValue(); - StringTag texture = (StringTag) tag1.get("value"); - return CompletableFuture.completedFuture(texture.getValue()); + NbtMap tag1 = properties.get(0); + String texture = tag1.getString("value", null); + return CompletableFuture.completedFuture(texture); } - public static @Nullable BlockDefinition translateSkull(GeyserSession session, CompoundTag tag, Vector3i blockPosition, int blockState) { - CompoundTag profile = tag.get("profile"); - if (profile == null) { + public static @Nullable BlockDefinition translateSkull(GeyserSession session, NbtMap javaNbt, Vector3i blockPosition, int blockState) { + NbtMap profile = javaNbt.getCompound("profile"); + if (profile.isEmpty()) { session.getSkullCache().removeSkull(blockPosition); return null; } @@ -112,13 +114,13 @@ public class SkullBlockEntityTranslator extends BlockEntityTranslator implements try { String texture = texturesFuture.get(); if (texture == null) { - session.getGeyser().getLogger().debug("Custom skull with invalid profile tag: " + blockPosition + " " + tag); + session.getGeyser().getLogger().debug("Custom skull with invalid profile tag: " + blockPosition + " " + javaNbt); return null; } SkullCache.Skull skull = session.getSkullCache().putSkull(blockPosition, uuid, texture, blockState); return skull.getBlockDefinition(); } catch (InterruptedException | ExecutionException e) { - session.getGeyser().getLogger().debug("Failed to acquire textures for custom skull: " + blockPosition + " " + tag); + session.getGeyser().getLogger().debug("Failed to acquire textures for custom skull: " + blockPosition + " " + javaNbt); if (GeyserImpl.getInstance().getConfig().isDebugMode()) { e.printStackTrace(); } @@ -129,7 +131,7 @@ public class SkullBlockEntityTranslator extends BlockEntityTranslator implements // profile contained a username, so we have to wait for it to be retrieved texturesFuture.whenComplete((texturesProperty, throwable) -> { if (texturesProperty == null) { - session.getGeyser().getLogger().debug("Custom skull with invalid profile tag: " + blockPosition + " " + tag); + session.getGeyser().getLogger().debug("Custom skull with invalid profile tag: " + blockPosition + " " + javaNbt); return; } if (session.getEventLoop().inEventLoop()) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java index 5611bf90c..05b763e6b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java @@ -25,10 +25,6 @@ package org.geysermc.geyser.translator.level.block.entity; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3i; @@ -38,17 +34,18 @@ import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.MOB_SPAWNER) public class SpawnerBlockEntityTranslator extends BlockEntityTranslator { @Override - public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, CompoundTag tag, int blockState) { + public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, NbtMap javaNbt, int blockState) { // Sending an empty EntityIdentifier to empty the spawner is ignored by the client, so we send a whole new spawner! // Fixes https://github.com/GeyserMC/Geyser/issues/4214 - CompoundTag spawnData = tag.get("SpawnData"); + NbtMap spawnData = javaNbt.getCompound("SpawnData"); if (spawnData != null) { - CompoundTag entityTag = spawnData.get("entity"); + NbtMap entityTag = spawnData.getCompound("entity"); if (entityTag.isEmpty()) { Vector3i position = Vector3i.from(x, y, z); // Set to air and back to reset the spawner - "just" updating the spawner doesn't work @@ -66,62 +63,63 @@ public class SpawnerBlockEntityTranslator extends BlockEntityTranslator { } } - return super.getBlockEntityTag(session, type, x, y, z, tag, blockState); + return super.getBlockEntityTag(session, type, x, y, z, javaNbt, blockState); } @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { - Tag current; + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + Object current; - if ((current = tag.get("MaxNearbyEntities")) != null) { - builder.put("MaxNearbyEntities", current.getValue()); + // TODO use primitive get and put methods + if ((current = javaNbt.get("MaxNearbyEntities")) != null) { + bedrockNbt.put("MaxNearbyEntities", current); } - if ((current = tag.get("RequiredPlayerRange")) != null) { - builder.put("RequiredPlayerRange", current.getValue()); + if ((current = javaNbt.get("RequiredPlayerRange")) != null) { + bedrockNbt.put("RequiredPlayerRange", current); } - if ((current = tag.get("SpawnCount")) != null) { - builder.put("SpawnCount", current.getValue()); + if ((current = javaNbt.get("SpawnCount")) != null) { + bedrockNbt.put("SpawnCount", current); } - if ((current = tag.get("MaxSpawnDelay")) != null) { - builder.put("MaxSpawnDelay", current.getValue()); + if ((current = javaNbt.get("MaxSpawnDelay")) != null) { + bedrockNbt.put("MaxSpawnDelay", current); } - if ((current = tag.get("Delay")) != null) { - builder.put("Delay", current.getValue()); + if ((current = javaNbt.get("Delay")) != null) { + bedrockNbt.put("Delay", current); } - if ((current = tag.get("SpawnRange")) != null) { - builder.put("SpawnRange", current.getValue()); + if ((current = javaNbt.get("SpawnRange")) != null) { + bedrockNbt.put("SpawnRange", current); } - if ((current = tag.get("MinSpawnDelay")) != null) { - builder.put("MinSpawnDelay", current.getValue()); + if ((current = javaNbt.get("MinSpawnDelay")) != null) { + bedrockNbt.put("MinSpawnDelay", current); } - translateSpawnData(builder, tag.get("SpawnData")); + translateSpawnData(bedrockNbt, javaNbt.getCompound("SpawnData", null)); - builder.put("isMovable", (byte) 1); + bedrockNbt.put("isMovable", (byte) 1); } - static void translateSpawnData(@NonNull NbtMapBuilder builder, @Nullable CompoundTag spawnData) { + static void translateSpawnData(@NonNull NbtMapBuilder builder, @Nullable NbtMap spawnData) { if (spawnData == null) { return; } - CompoundTag entityTag = spawnData.get("entity"); - if (entityTag.get("id") instanceof StringTag idTag) { + NbtMap entityTag = spawnData.getCompound("entity"); + String entityId = entityTag.getString("id"); + if (entityId != null) { // As of 1.19.3, spawners can be empty - String entityId = idTag.getValue(); builder.put("EntityIdentifier", entityId); EntityDefinition definition = Registries.JAVA_ENTITY_IDENTIFIERS.get(entityId); if (definition != null) { - builder.put("DisplayEntityWidth", definition.width()); - builder.put("DisplayEntityHeight", definition.height()); - builder.put("DisplayEntityScale", 1.0f); + builder.putFloat("DisplayEntityWidth", definition.width()); + builder.putFloat("DisplayEntityHeight", definition.height()); + builder.putFloat("DisplayEntityScale", 1.0f); } } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java index 40b10de40..aefd97dd5 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.translator.level.block.entity; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -35,22 +33,23 @@ import org.cloudburstmc.protocol.bedrock.data.structure.StructureRotation; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.StructureBlockUtils; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.STRUCTURE_BLOCK) public class StructureBlockBlockEntityTranslator extends BlockEntityTranslator { @Override - public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, CompoundTag tag, int blockState) { + public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, NbtMap javaNbt, int blockState) { // Sending a structure with size 0 doesn't clear the outline. Hence, we have to force it by replacing the block :/ - int xStructureSize = getOrDefault(tag.get("sizeX"), 0); - int yStructureSize = getOrDefault(tag.get("sizeY"), 0); - int zStructureSize = getOrDefault(tag.get("sizeZ"), 0); + int xStructureSize = javaNbt.getInt("sizeX"); + int yStructureSize = javaNbt.getInt("sizeY"); + int zStructureSize = javaNbt.getInt("sizeZ"); Vector3i size = Vector3i.from(xStructureSize, yStructureSize, zStructureSize); if (size.equals(Vector3i.ZERO)) { Vector3i position = Vector3i.from(x, y, z); - String mode = getOrDefault(tag.get("mode"), ""); + String mode = javaNbt.getString("mode"); // Set to air and back to reset the structure block UpdateBlockPacket emptyBlockPacket = new UpdateBlockPacket(); @@ -66,18 +65,18 @@ public class StructureBlockBlockEntityTranslator extends BlockEntityTranslator { session.sendUpstreamPacket(spawnerBlockPacket); } - return super.getBlockEntityTag(session, type, x, y, z, tag, blockState); + return super.getBlockEntityTag(session, type, x, y, z, javaNbt, blockState); } @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { - if (tag.size() < 5) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + if (javaNbt.size() < 5) { return; // These values aren't here } - builder.putString("structureName", getOrDefault(tag.get("name"), "")); + bedrockNbt.putString("structureName", javaNbt.getString("name")); - String mode = getOrDefault(tag.get("mode"), ""); + String mode = javaNbt.getString("mode"); int bedrockData = switch (mode) { case "LOAD" -> 2; case "CORNER" -> 3; @@ -85,53 +84,53 @@ public class StructureBlockBlockEntityTranslator extends BlockEntityTranslator { default -> 1; // SAVE }; - builder.putInt("data", bedrockData); - builder.putString("dataField", ""); // ??? possibly related to Java's "metadata" + bedrockNbt.putInt("data", bedrockData); + bedrockNbt.putString("dataField", ""); // ??? possibly related to Java's "metadata" // Mirror behaves different in Java and Bedrock - it requires modifying the position in space as well - String mirror = getOrDefault(tag.get("mirror"), ""); + String mirror = javaNbt.getString("mirror"); StructureMirror bedrockMirror = switch (mirror) { case "FRONT_BACK" -> StructureMirror.X; case "LEFT_RIGHT" -> StructureMirror.Z; default -> StructureMirror.NONE; }; - builder.putByte("mirror", (byte) bedrockMirror.ordinal()); + bedrockNbt.putByte("mirror", (byte) bedrockMirror.ordinal()); - builder.putByte("ignoreEntities", getOrDefault(tag.get("ignoreEntities"), (byte) 0)); - builder.putByte("isPowered", getOrDefault(tag.get("powered"), (byte) 0)); - builder.putLong("seed", getOrDefault(tag.get("seed"), 0L)); - builder.putByte("showBoundingBox", getOrDefault(tag.get("showboundingbox"), (byte) 0)); + bedrockNbt.putByte("ignoreEntities", javaNbt.getByte("ignoreEntities")); + bedrockNbt.putByte("isPowered", javaNbt.getByte("powered")); + bedrockNbt.putLong("seed", javaNbt.getLong("seed")); + bedrockNbt.putByte("showBoundingBox", javaNbt.getByte("showboundingbox")); - String rotation = getOrDefault(tag.get("rotation"), ""); + String rotation = javaNbt.getString("rotation"); StructureRotation bedrockRotation = switch (rotation) { case "CLOCKWISE_90" -> StructureRotation.ROTATE_90; case "CLOCKWISE_180" -> StructureRotation.ROTATE_180; case "COUNTERCLOCKWISE_90" -> StructureRotation.ROTATE_270; default -> StructureRotation.NONE; }; - builder.putByte("rotation", (byte) bedrockRotation.ordinal()); + bedrockNbt.putByte("rotation", (byte) bedrockRotation.ordinal()); - int xStructureSize = getOrDefault(tag.get("sizeX"), 0); - int yStructureSize = getOrDefault(tag.get("sizeY"), 0); - int zStructureSize = getOrDefault(tag.get("sizeZ"), 0); + int xStructureSize = javaNbt.getInt("sizeX"); + int yStructureSize = javaNbt.getInt("sizeY"); + int zStructureSize = javaNbt.getInt("sizeZ"); // The "positions" are also offsets on Java - int posX = getOrDefault(tag.get("posX"), 0); - int posY = getOrDefault(tag.get("posY"), 0); - int posZ = getOrDefault(tag.get("posZ"), 0); + int posX = javaNbt.getInt("posX"); + int posY = javaNbt.getInt("posY"); + int posZ = javaNbt.getInt("posZ"); Vector3i offset = StructureBlockUtils.calculateOffset(bedrockRotation, bedrockMirror, xStructureSize, zStructureSize); - builder.putInt("xStructureOffset", posX + offset.getX()); - builder.putInt("yStructureOffset", posY); - builder.putInt("zStructureOffset", posZ + offset.getZ()); + bedrockNbt.putInt("xStructureOffset", posX + offset.getX()); + bedrockNbt.putInt("yStructureOffset", posY); + bedrockNbt.putInt("zStructureOffset", posZ + offset.getZ()); - builder.putInt("xStructureSize", xStructureSize); - builder.putInt("yStructureSize", yStructureSize); - builder.putInt("zStructureSize", zStructureSize); + bedrockNbt.putInt("xStructureSize", xStructureSize); + bedrockNbt.putInt("yStructureSize", yStructureSize); + bedrockNbt.putInt("zStructureSize", zStructureSize); - builder.putFloat("integrity", getOrDefault(tag.get("integrity"), 0f)); // Is 1.0f by default on Java but 100.0f on Bedrock + bedrockNbt.putFloat("integrity", javaNbt.getFloat("integrity")); // Is 1.0f by default on Java but 100.0f on Bedrock // Java's "showair" is unrepresented } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/TrialSpawnerBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/TrialSpawnerBlockEntityTranslator.java index da013cf3c..ff3f89f3f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/TrialSpawnerBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/TrialSpawnerBlockEntityTranslator.java @@ -25,23 +25,24 @@ package org.geysermc.geyser.translator.level.block.entity; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; +import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.TRIAL_SPAWNER) public class TrialSpawnerBlockEntityTranslator extends BlockEntityTranslator { @Override - public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { - if (tag == null) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + if (javaNbt == null) { return; } // trial spawners have "spawn_data" instead of "SpawnData" - SpawnerBlockEntityTranslator.translateSpawnData(builder, tag.get("spawn_data")); + SpawnerBlockEntityTranslator.translateSpawnData(bedrockNbt, javaNbt.getCompound("spawn_data", null)); // Because trial spawners don't exist on bedrock yet - builder.put("id", "MobSpawner"); + bedrockNbt.put("id", "MobSpawner"); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java index 82b51dfdd..b13344fd3 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java @@ -25,9 +25,8 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.math.vector.Vector3i; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; import org.cloudburstmc.protocol.bedrock.data.structure.StructureMirror; @@ -71,7 +70,7 @@ public class JavaBlockEntityDataTranslator extends PacketTranslator 5 ) { - CompoundTag map = packet.getNbt(); + NbtMap map = packet.getNbt(); - String mode = getOrDefault(map.get("mode"), ""); + String mode = map.getString("mode"); if (!mode.equalsIgnoreCase("LOAD")) { return; } - String mirror = getOrDefault(map.get("mirror"), ""); + String mirror = map.getString("mirror"); StructureMirror bedrockMirror = switch (mirror) { case "FRONT_BACK" -> StructureMirror.X; case "LEFT_RIGHT" -> StructureMirror.Z; default -> StructureMirror.NONE; }; - String rotation = getOrDefault(map.get("rotation"), ""); + String rotation = map.getString("rotation"); StructureRotation bedrockRotation = switch (rotation) { case "CLOCKWISE_90" -> StructureRotation.ROTATE_90; case "CLOCKWISE_180" -> StructureRotation.ROTATE_180; @@ -129,10 +128,10 @@ public class JavaBlockEntityDataTranslator extends PacketTranslator StructureRotation.NONE; }; - String name = getOrDefault(map.get("name"), ""); - int sizeX = getOrDefault(map.get("sizeX"), 0); - int sizeY = getOrDefault(map.get("sizeY"), 0); - int sizeZ = getOrDefault(map.get("sizeZ"), 0); + String name = map.getString("name"); + int sizeX = map.getInt("sizeX"); + int sizeY = map.getInt("sizeY"); + int sizeZ = map.getInt("sizeZ"); session.getStructureBlockCache().setCurrentStructureBlock(null); @@ -149,10 +148,4 @@ public class JavaBlockEntityDataTranslator extends PacketTranslator T getOrDefault(Tag tag, T defaultValue) { - //noinspection unchecked - return (tag != null && tag.getValue() != null) ? (T) tag.getValue() : defaultValue; - } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java index 609574cdd..c3a399863 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.translator.protocol.java.level; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufOutputStream; @@ -385,7 +384,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator> 4) - (bedrockDimension.minY() >> 4); diff --git a/core/src/main/java/org/geysermc/geyser/translator/sound/BlockSoundInteractionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/sound/BlockSoundInteractionTranslator.java index ead619b68..02e5044bb 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/sound/BlockSoundInteractionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/sound/BlockSoundInteractionTranslator.java @@ -25,16 +25,12 @@ package org.geysermc.geyser.translator.sound; -import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.util.BlockUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import java.util.Map; @@ -104,25 +100,14 @@ public interface BlockSoundInteractionTranslator extends SoundInteractionTransla return true; } - CompoundTag tag = itemInHand.getNbt(); - if (tag == null) { - // No CanPlaceOn tag can exist - return false; - } - ListTag canPlaceOn = tag.get("CanPlaceOn"); - if (canPlaceOn == null || canPlaceOn.size() == 0) { - return false; + var canPlaceOn = itemInHand.getComponent(DataComponentType.CAN_PLACE_ON); + if (canPlaceOn == null || canPlaceOn.getPredicates().isEmpty()) { + // Component doesn't exist - no restrictions apply. + return true; } - String cleanIdentifier = BlockUtils.getCleanIdentifier(blockIdentifier); - - for (Tag t : canPlaceOn) { - if (t instanceof StringTag stringTag) { - if (cleanIdentifier.equals(stringTag.getValue())) { - // This operation would/could be a success! - return true; - } - } + for (var blockPredicate : canPlaceOn.getPredicates()) { + // I don't want to deal with this right now. TODO } // The block in world is not present in the CanPlaceOn tag on the item diff --git a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java index 612b9c38b..3f1c902c7 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java @@ -187,14 +187,28 @@ public class MessageTranslator { } } + /** + * Convenience method for locale getting. + */ + public static String convertJsonMessage(GeyserSession session, String message) { + return convertJsonMessage(message, session.locale()); + } + public static String convertJsonMessage(String message, String locale) { return convertMessage(GSON_SERIALIZER.deserialize(message), locale); } - public static String convertJsonMessage(String message) { - return convertJsonMessage(message, GeyserLocale.getDefaultLocale()); + /** + * Convenience method for locale getting. + */ + public static String convertMessage(GeyserSession session, Component message) { + return convertMessage(message, session.locale()); } + /** + * DO NOT USE THIS METHOD unless where you're calling from does not have a (reliable) way of getting the + * context's locale. + */ public static String convertMessage(Component message) { return convertMessage(message, GeyserLocale.getDefaultLocale()); } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3cb136683..f8f979539 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "1ca8808" # Revert from jitpack after release +mcprotocollib = "98410a1" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From f47754be03819954a9d9499831b5e59595a0930a Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 27 Apr 2024 15:49:19 -0400 Subject: [PATCH 114/272] Goat horns --- .../geyser/item/type/GoatHornItem.java | 28 ++----------------- .../translator/item/ItemTranslator.java | 5 ++-- 2 files changed, 5 insertions(+), 28 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java index c31e15578..cd21c0b6e 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java @@ -35,20 +35,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponen import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import org.geysermc.mcprotocollib.protocol.data.game.item.component.Instrument; -import java.util.List; - public class GoatHornItem extends Item { - private static final List INSTRUMENTS = List.of( - "ponder_goat_horn", - "sing_goat_horn", - "seek_goat_horn", - "feel_goat_horn", - "admire_goat_horn", - "call_goat_horn", - "yearn_goat_horn", - "dream_goat_horn" // Called "Resist" on Bedrock 1.19.0 due to https://bugs.mojang.com/browse/MCPE-155059 - ); - public GoatHornItem(String javaIdentifier, Builder builder) { super(javaIdentifier, builder); } @@ -60,19 +47,8 @@ public class GoatHornItem extends Item { return builder; } Holder instrument = components.get(DataComponentType.INSTRUMENT); - // TODO registry - if (instrument != null) { - // Drop the Minecraft namespace if applicable -// if (instrument.startsWith("minecraft:")) { -// instrument = instrument.substring("minecraft:".length()); -// } -// -// int damage = INSTRUMENTS.indexOf(instrument); -// if (damage == -1) { -// damage = 0; -// GeyserImpl.getInstance().getLogger().debug("Unknown goat horn instrument: " + instrumentTag.getValue()); -// } -// builder.damage(damage); + if (instrument != null && instrument.isId()) { + builder.damage(instrument.id()); } return builder; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index 2535a5652..629192e01 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -93,7 +93,8 @@ public final class ItemTranslator { NbtMap nbt = data.getTag(); if (nbt != null && !nbt.isEmpty()) { - DataComponents components = new DataComponents(new HashMap<>()); + // translateToJava may have added components + DataComponents components = itemStack.getComponents() == null ? new DataComponents(new HashMap<>()) : itemStack.getComponents(); javaItem.translateNbtToJava(nbt, components, bedrockItem); if (!components.getDataComponents().isEmpty()) { itemStack.setComponents(components); @@ -394,7 +395,7 @@ public final class ItemTranslator { customName = components.get(DataComponentType.ITEM_NAME); } if (customName != null) { - // Get the translated name and prefix it with a reset char TODO test + // Get the translated name and prefix it with a reset char return MessageTranslator.convertMessage(customName, session.locale()); } } From 6d5ac233d6112dd65f162064c55963b20373285d Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 27 Apr 2024 21:00:10 -0400 Subject: [PATCH 115/272] Dyeable items work. --- .../geyser/entity/EntityDefinitions.java | 6 +-- ...ippedArrowEntity.java => ArrowEntity.java} | 7 +-- .../geyser/inventory/item/Potion.java | 9 ---- .../inventory/item/TippedArrowPotion.java | 9 ---- .../geyser/item/DyeableLeatherItem.java | 42 ----------------- .../java/org/geysermc/geyser/item/Items.java | 46 +++++++++---------- .../geysermc/geyser/item/type/ChestItem.java | 44 ------------------ .../geyser/item/type/DyeableArmorItem.java | 12 +++-- .../item/type/DyeableHorseArmorItem.java | 45 ------------------ .../geysermc/geyser/item/type/FlowerItem.java | 33 ------------- .../translator/item/ItemTranslator.java | 16 +++---- 11 files changed, 45 insertions(+), 224 deletions(-) rename core/src/main/java/org/geysermc/geyser/entity/type/{TippedArrowEntity.java => ArrowEntity.java} (86%) delete mode 100644 core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java delete mode 100644 core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java delete mode 100644 core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java delete mode 100644 core/src/main/java/org/geysermc/geyser/item/type/FlowerItem.java diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index 317892676..4063a675c 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -56,7 +56,7 @@ public final class EntityDefinitions { public static final EntityDefinition AREA_EFFECT_CLOUD; public static final EntityDefinition ARMADILLO; public static final EntityDefinition ARMOR_STAND; - public static final EntityDefinition ARROW; + public static final EntityDefinition ARROW; public static final EntityDefinition AXOLOTL; public static final EntityDefinition BAT; public static final EntityDefinition BEE; @@ -378,10 +378,10 @@ public final class EntityDefinitions { .addTranslator(MetadataType.BYTE, AbstractArrowEntity::setArrowFlags) .addTranslator(null) // "Piercing level" .build(); - ARROW = EntityDefinition.inherited(TippedArrowEntity::new, abstractArrowBase) + ARROW = EntityDefinition.inherited(ArrowEntity::new, abstractArrowBase) .type(EntityType.ARROW) .heightAndWidth(0.25f) - .addTranslator(MetadataType.INT, TippedArrowEntity::setPotionEffectColor) + .addTranslator(MetadataType.INT, ArrowEntity::setPotionEffectColor) .build(); SPECTRAL_ARROW = EntityDefinition.inherited(abstractArrowBase.factory(), abstractArrowBase) .type(EntityType.SPECTRAL_ARROW) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/TippedArrowEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ArrowEntity.java similarity index 86% rename from core/src/main/java/org/geysermc/geyser/entity/type/TippedArrowEntity.java rename to core/src/main/java/org/geysermc/geyser/entity/type/ArrowEntity.java index be4133028..1ee706811 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/TippedArrowEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ArrowEntity.java @@ -34,12 +34,9 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEnt import java.util.UUID; -/** - * Internally this is known as TippedArrowEntity but is used with tipped arrows and normal arrows - */ -public class TippedArrowEntity extends AbstractArrowEntity { +public class ArrowEntity extends AbstractArrowEntity { - public TippedArrowEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { + public ArrowEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java b/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java index 79b9565fb..00a9b091e 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java @@ -91,15 +91,6 @@ public enum Potion { return new PotionContents(this.ordinal(), -1, Int2ObjectMaps.emptyMap()); } - public static @Nullable Potion getByJavaIdentifier(String javaIdentifier) { - for (Potion potion : VALUES) { - if (potion.javaIdentifier.equals(javaIdentifier)) { - return potion; - } - } - return null; - } - public static @Nullable Potion getByBedrockId(int bedrockId) { for (Potion potion : VALUES) { if (potion.bedrockId == bedrockId) { diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java b/core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java index 5c33fec67..ec6b10ec8 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java @@ -99,15 +99,6 @@ public enum TippedArrowPotion { return VALUES[id]; } - public static @Nullable TippedArrowPotion getByJavaIdentifier(String javaIdentifier) { - for (TippedArrowPotion potion : VALUES) { - if (potion.javaIdentifier.equals(javaIdentifier)) { - return potion; - } - } - return null; - } - public static @Nullable TippedArrowPotion getByBedrockId(int bedrockId) { for (TippedArrowPotion potion : VALUES) { if (potion.bedrockId == bedrockId) { diff --git a/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java b/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java deleted file mode 100644 index eabdbee87..000000000 --- a/core/src/main/java/org/geysermc/geyser/item/DyeableLeatherItem.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.geyser.item; - -import org.geysermc.geyser.translator.item.BedrockItemBuilder; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.DyedItemColor; - -public interface DyeableLeatherItem { - - static void translateComponentsToBedrock(DataComponents components, BedrockItemBuilder builder) { - DyedItemColor dyedItemColor = components.get(DataComponentType.DYED_COLOR); - if (dyedItemColor == null) { - return; - } - builder.putInt("customColor", dyedItemColor.getRgb()); - } -} diff --git a/core/src/main/java/org/geysermc/geyser/item/Items.java b/core/src/main/java/org/geysermc/geyser/item/Items.java index 42a087acf..f13330700 100644 --- a/core/src/main/java/org/geysermc/geyser/item/Items.java +++ b/core/src/main/java/org/geysermc/geyser/item/Items.java @@ -256,20 +256,20 @@ public final class Items { public static final Item GREEN_WOOL = register(new BlockItem("green_wool", builder())); public static final Item RED_WOOL = register(new BlockItem("red_wool", builder())); public static final Item BLACK_WOOL = register(new BlockItem("black_wool", builder())); - public static final Item DANDELION = register(new FlowerItem("dandelion", builder())); - public static final Item POPPY = register(new FlowerItem("poppy", builder())); - public static final Item BLUE_ORCHID = register(new FlowerItem("blue_orchid", builder())); - public static final Item ALLIUM = register(new FlowerItem("allium", builder())); - public static final Item AZURE_BLUET = register(new FlowerItem("azure_bluet", builder())); - public static final Item RED_TULIP = register(new FlowerItem("red_tulip", builder())); - public static final Item ORANGE_TULIP = register(new FlowerItem("orange_tulip", builder())); - public static final Item WHITE_TULIP = register(new FlowerItem("white_tulip", builder())); - public static final Item PINK_TULIP = register(new FlowerItem("pink_tulip", builder())); - public static final Item OXEYE_DAISY = register(new FlowerItem("oxeye_daisy", builder())); - public static final Item CORNFLOWER = register(new FlowerItem("cornflower", builder())); - public static final Item LILY_OF_THE_VALLEY = register(new FlowerItem("lily_of_the_valley", builder())); - public static final Item WITHER_ROSE = register(new FlowerItem("wither_rose", builder())); - public static final Item TORCHFLOWER = register(new FlowerItem("torchflower", builder())); + public static final Item DANDELION = register(new BlockItem("dandelion", builder())); + public static final Item POPPY = register(new BlockItem("poppy", builder())); + public static final Item BLUE_ORCHID = register(new BlockItem("blue_orchid", builder())); + public static final Item ALLIUM = register(new BlockItem("allium", builder())); + public static final Item AZURE_BLUET = register(new BlockItem("azure_bluet", builder())); + public static final Item RED_TULIP = register(new BlockItem("red_tulip", builder())); + public static final Item ORANGE_TULIP = register(new BlockItem("orange_tulip", builder())); + public static final Item WHITE_TULIP = register(new BlockItem("white_tulip", builder())); + public static final Item PINK_TULIP = register(new BlockItem("pink_tulip", builder())); + public static final Item OXEYE_DAISY = register(new BlockItem("oxeye_daisy", builder())); + public static final Item CORNFLOWER = register(new BlockItem("cornflower", builder())); + public static final Item LILY_OF_THE_VALLEY = register(new BlockItem("lily_of_the_valley", builder())); + public static final Item WITHER_ROSE = register(new BlockItem("wither_rose", builder())); + public static final Item TORCHFLOWER = register(new BlockItem("torchflower", builder())); public static final Item PITCHER_PLANT = register(new BlockItem("pitcher_plant", builder())); public static final Item SPORE_BLOSSOM = register(new BlockItem("spore_blossom", builder())); public static final Item BROWN_MUSHROOM = register(new BlockItem("brown_mushroom", builder())); @@ -337,7 +337,7 @@ public final class Items { public static final Item PURPUR_PILLAR = register(new BlockItem("purpur_pillar", builder())); public static final Item PURPUR_STAIRS = register(new BlockItem("purpur_stairs", builder())); public static final Item SPAWNER = register(new BlockItem("spawner", builder())); - public static final Item CHEST = register(new ChestItem("chest", builder())); + public static final Item CHEST = register(new BlockItem("chest", builder())); public static final Item CRAFTING_TABLE = register(new BlockItem("crafting_table", builder())); public static final Item FARMLAND = register(new BlockItem("farmland", builder())); public static final Item FURNACE = register(new BlockItem("furnace", builder())); @@ -419,7 +419,7 @@ public final class Items { public static final Item END_STONE_BRICKS = register(new BlockItem("end_stone_bricks", builder())); public static final Item DRAGON_EGG = register(new BlockItem("dragon_egg", builder())); public static final Item SANDSTONE_STAIRS = register(new BlockItem("sandstone_stairs", builder())); - public static final Item ENDER_CHEST = register(new ChestItem("ender_chest", builder())); + public static final Item ENDER_CHEST = register(new BlockItem("ender_chest", builder())); public static final Item EMERALD_BLOCK = register(new BlockItem("emerald_block", builder())); public static final Item OAK_STAIRS = register(new BlockItem("oak_stairs", builder())); public static final Item SPRUCE_STAIRS = register(new BlockItem("spruce_stairs", builder())); @@ -716,7 +716,7 @@ public final class Items { public static final Item SCULK_SENSOR = register(new BlockItem("sculk_sensor", builder())); public static final Item CALIBRATED_SCULK_SENSOR = register(new BlockItem("calibrated_sculk_sensor", builder())); public static final Item TRIPWIRE_HOOK = register(new BlockItem("tripwire_hook", builder())); - public static final Item TRAPPED_CHEST = register(new ChestItem("trapped_chest", builder())); + public static final Item TRAPPED_CHEST = register(new BlockItem("trapped_chest", builder())); public static final Item TNT = register(new BlockItem("tnt", builder())); public static final Item REDSTONE_LAMP = register(new BlockItem("redstone_lamp", builder())); public static final Item NOTE_BLOCK = register(new BlockItem("note_block", builder())); @@ -894,10 +894,10 @@ public final class Items { public static final Item WHEAT_SEEDS = register(new BlockItem("wheat_seeds", builder())); public static final Item WHEAT = register(new Item("wheat", builder())); public static final Item BREAD = register(new Item("bread", builder())); - public static final Item LEATHER_HELMET = register(new ArmorItem("leather_helmet", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(55))); - public static final Item LEATHER_CHESTPLATE = register(new ArmorItem("leather_chestplate", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(80))); - public static final Item LEATHER_LEGGINGS = register(new ArmorItem("leather_leggings", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(75))); - public static final Item LEATHER_BOOTS = register(new ArmorItem("leather_boots", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(65))); + public static final Item LEATHER_HELMET = register(new DyeableArmorItem("leather_helmet", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(55))); + public static final Item LEATHER_CHESTPLATE = register(new DyeableArmorItem("leather_chestplate", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(80))); + public static final Item LEATHER_LEGGINGS = register(new DyeableArmorItem("leather_leggings", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(75))); + public static final Item LEATHER_BOOTS = register(new DyeableArmorItem("leather_boots", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(65))); public static final Item CHAINMAIL_HELMET = register(new ArmorItem("chainmail_helmet", ArmorMaterial.CHAINMAIL, builder().stackSize(1).maxDamage(165))); public static final Item CHAINMAIL_CHESTPLATE = register(new ArmorItem("chainmail_chestplate", ArmorMaterial.CHAINMAIL, builder().stackSize(1).maxDamage(240))); public static final Item CHAINMAIL_LEGGINGS = register(new ArmorItem("chainmail_leggings", ArmorMaterial.CHAINMAIL, builder().stackSize(1).maxDamage(225))); @@ -1165,7 +1165,7 @@ public final class Items { public static final Item IRON_HORSE_ARMOR = register(new ArmorItem("iron_horse_armor", ArmorMaterial.IRON, builder().stackSize(1))); public static final Item GOLDEN_HORSE_ARMOR = register(new ArmorItem("golden_horse_armor", ArmorMaterial.GOLD, builder().stackSize(1))); public static final Item DIAMOND_HORSE_ARMOR = register(new ArmorItem("diamond_horse_armor", ArmorMaterial.DIAMOND, builder().stackSize(1))); - public static final Item LEATHER_HORSE_ARMOR = register(new ArmorItem("leather_horse_armor", ArmorMaterial.LEATHER, builder().stackSize(1))); + public static final Item LEATHER_HORSE_ARMOR = register(new DyeableArmorItem("leather_horse_armor", ArmorMaterial.LEATHER, builder().stackSize(1))); public static final Item LEAD = register(new Item("lead", builder())); public static final Item NAME_TAG = register(new Item("name_tag", builder())); public static final Item COMMAND_BLOCK_MINECART = register(new Item("command_block_minecart", builder().stackSize(1))); @@ -1240,7 +1240,7 @@ public final class Items { public static final Item GUSTER_BANNER_PATTERN = register(new Item("guster_banner_pattern", builder().stackSize(1))); public static final Item GOAT_HORN = register(new GoatHornItem("goat_horn", builder().stackSize(1))); public static final Item COMPOSTER = register(new BlockItem("composter", builder())); - public static final Item BARREL = register(new ChestItem("barrel", builder())); + public static final Item BARREL = register(new BlockItem("barrel", builder())); public static final Item SMOKER = register(new BlockItem("smoker", builder())); public static final Item BLAST_FURNACE = register(new BlockItem("blast_furnace", builder())); public static final Item CARTOGRAPHY_TABLE = register(new BlockItem("cartography_table", builder())); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java deleted file mode 100644 index 09718ba66..000000000 --- a/core/src/main/java/org/geysermc/geyser/item/type/ChestItem.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.geyser.item.type; - -import org.checkerframework.checker.nullness.qual.NonNull; -import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.translator.item.BedrockItemBuilder; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; - -@Deprecated -public class ChestItem extends BlockItem { - - public ChestItem(String javaIdentifier, Builder builder) { - super(javaIdentifier, builder); - } - - @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { - super.translateComponentsToBedrock(session, components, builder); - } -} diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java index d4bf838bd..b2dbb95e5 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java @@ -27,12 +27,13 @@ package org.geysermc.geyser.item.type; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.item.ArmorMaterial; -import org.geysermc.geyser.item.DyeableLeatherItem; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DyedItemColor; -public class DyeableArmorItem extends ArmorItem implements DyeableLeatherItem { +public class DyeableArmorItem extends ArmorItem { public DyeableArmorItem(String javaIdentifier, ArmorMaterial material, Builder builder) { super(javaIdentifier, material, builder); } @@ -41,6 +42,11 @@ public class DyeableArmorItem extends ArmorItem implements DyeableLeatherItem { public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - DyeableLeatherItem.translateComponentsToBedrock(components, builder); + // Note that this is handled as of 1.20.5 in the ItemColors class. + // But horse leather armor and body leather armor are now both armor items. So it works! + DyedItemColor dyedItemColor = components.get(DataComponentType.DYED_COLOR); + if (dyedItemColor != null) { + builder.putInt("customColor", dyedItemColor.getRgb()); + } } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java deleted file mode 100644 index b50a3b847..000000000 --- a/core/src/main/java/org/geysermc/geyser/item/type/DyeableHorseArmorItem.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.geyser.item.type; - -import org.checkerframework.checker.nullness.qual.NonNull; -import org.geysermc.geyser.item.DyeableLeatherItem; -import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.translator.item.BedrockItemBuilder; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; - -public class DyeableHorseArmorItem extends Item implements DyeableLeatherItem { - public DyeableHorseArmorItem(String javaIdentifier, Builder builder) { - super(javaIdentifier, builder); - } - - @Override - public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { - super.translateComponentsToBedrock(session, components, builder); - - DyeableLeatherItem.translateComponentsToBedrock(components, builder); - } -} diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FlowerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FlowerItem.java deleted file mode 100644 index c65eec1d2..000000000 --- a/core/src/main/java/org/geysermc/geyser/item/type/FlowerItem.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.geyser.item.type; - -// If blocks are implemented, then this class is not needed. -public class FlowerItem extends BlockItem { - public FlowerItem(String javaIdentifier, Builder builder) { - super(javaIdentifier, builder); - } -} diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index 629192e01..11e092b57 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -71,7 +71,7 @@ public final class ItemTranslator { /** * The order of these slots is their display order on Java Edition clients */ - private static final String[] ALL_SLOTS = new String[]{"mainhand", "offhand", "feet", "legs", "chest", "head"}; + private static final ItemAttributeModifiers.EquipmentSlotGroup[] ALL_SLOTS = ItemAttributeModifiers.EquipmentSlotGroup.values(); private static final DecimalFormat ATTRIBUTE_FORMAT = new DecimalFormat("0.#####"); private ItemTranslator() { @@ -128,7 +128,7 @@ public final class ItemTranslator { .build(); } - private static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, Item javaItem, ItemMapping bedrockItem, int count, DataComponents components) { + private static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, Item javaItem, ItemMapping bedrockItem, int count, @Nullable DataComponents components) { BedrockItemBuilder nbtBuilder = new BedrockItemBuilder(); if (components != null) { @@ -208,8 +208,8 @@ public final class ItemTranslator { ItemAttributeModifiers.EquipmentSlotGroup slotGroup = entry.getSlot(); if (slotGroup == ItemAttributeModifiers.EquipmentSlotGroup.ANY) { // modifier applies to all slots implicitly - for (String slot : ALL_SLOTS) { // TODO SOMEONE LOOK HERE PLZ - //slotsToModifiers.computeIfAbsent(slot, s -> new ArrayList<>()).add(loreEntry); + for (var slot : ALL_SLOTS) { + slotsToModifiers.computeIfAbsent(slot, s -> new ArrayList<>()).add(loreEntry); } } else { // modifier applies to only the specified slot @@ -218,7 +218,7 @@ public final class ItemTranslator { } // iterate through the small array, not the map, so that ordering matches Java Edition - for (String slot : ALL_SLOTS) { + for (var slot : ALL_SLOTS) { List modifierStrings = slotsToModifiers.get(slot); if (modifierStrings == null || modifierStrings.isEmpty()) { continue; @@ -275,10 +275,10 @@ public final class ItemTranslator { return MessageTranslator.convertMessage(attributeComponent, language); } - private static void addAdvancedTooltips(DataComponents components, BedrockItemBuilder builder, Item item, String language) { + private static void addAdvancedTooltips(@Nullable DataComponents components, BedrockItemBuilder builder, Item item, String language) { int maxDurability = item.maxDamage(); - if (maxDurability != 0) { + if (maxDurability != 0 && components != null) { Integer durabilityComponent = components.get(DataComponentType.DAMAGE); if (durabilityComponent != null) { int durability = maxDurability - durabilityComponent; @@ -300,7 +300,7 @@ public final class ItemTranslator { Component component = Component.text() .resetStyle() .color(NamedTextColor.DARK_GRAY) - .append(Component.translatable("item.nbt_tags", // TODO + .append(Component.translatable("item.components", Component.text(components.getDataComponents().size()))) .build(); builder.getOrCreateLore().add(MessageTranslator.convertMessage(component, language)); From e97bbcc483f0e2ad6787e89ff03366eef2dff2ab Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Sun, 28 Apr 2024 02:10:20 -0400 Subject: [PATCH 116/272] Potion effect colors --- .../geyser/entity/EntityDefinitions.java | 3 +- .../geyser/entity/type/LivingEntity.java | 35 +++++++++++++++++++ gradle/libs.versions.toml | 2 +- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index 4063a675c..fd0673062 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -454,8 +454,7 @@ public final class EntityDefinitions { EntityDefinition livingEntityBase = EntityDefinition.inherited(LivingEntity::new, entityBase) .addTranslator(MetadataType.BYTE, LivingEntity::setLivingEntityFlags) .addTranslator(MetadataType.FLOAT, LivingEntity::setHealth) - .addTranslator(MetadataType.INT, - (livingEntity, entityMetadata) -> livingEntity.getDirtyMetadata().put(EntityDataTypes.EFFECT_COLOR, entityMetadata.getValue())) + .addTranslator(MetadataType.PARTICLES, LivingEntity::setParticles) .addTranslator(MetadataType.BOOLEAN, (livingEntity, entityMetadata) -> livingEntity.getDirtyMetadata().put(EntityDataTypes.EFFECT_AMBIENCE, (byte) (((BooleanEntityMetadata) entityMetadata).getPrimitiveValue() ? 1 : 0))) .addTranslator(null) // Arrow count diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java index 401135bbf..58a3bf8e7 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java @@ -55,9 +55,13 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.EntityEffectParticleData; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.Particle; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ParticleType; import java.util.*; @@ -152,6 +156,37 @@ public class LivingEntity extends Entity { session.sendUpstreamPacket(attributesPacket); } + // TODO: support all particle types + public void setParticles(ObjectEntityMetadata> entityMetadata) { + List particles = entityMetadata.getValue(); + float r = 0f; + float g = 0f; + float b = 0f; + + int count = 0; + for (Particle particle : particles) { + if (particle.getType() != ParticleType.ENTITY_EFFECT) { + continue; + } + + int color = ((EntityEffectParticleData) particle.getData()).getColor(); + r += ((color >> 16) & 0xFF) / 255f; + g += ((color >> 8) & 0xFF) / 255f; + b += ((color) & 0xFF) / 255f; + count++; + } + + int result = 0; + if (count > 0) { + r = r / count * 255f; + g = g / count * 255f; + b = b / count * 255f; + result = (int) r << 16 | (int) g << 8 | (int) b; + } + + dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, result); + } + public @Nullable Vector3i setBedPosition(EntityMetadata, ?> entityMetadata) { Optional optionalPos = entityMetadata.getValue(); if (optionalPos.isPresent()) { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f8f979539..7c16b883b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "98410a1" # Revert from jitpack after release +mcprotocollib = "400f1b4" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From 9cb9a1450e6740df5abef30ff4261a0f75b8c32d Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Sun, 28 Apr 2024 07:43:33 -0700 Subject: [PATCH 117/272] Don't use tee to write metadata.json to downloads API (#4612) --- .github/workflows/build.yml | 7 ++++--- .github/workflows/preview.yml | 6 ++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 284fa265a..7ec013dc2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -136,14 +136,15 @@ jobs: run: | cat metadata.json echo + mv metadata.json metadata.json.tmp version=$(cat gradle.properties | grep -o "version=[0-9\\.]*" | cut -d"=" -f2) - cat metadata.json | jq --arg project "${PROJECT}" --arg version "${version}" ' + jq --arg project "${PROJECT}" --arg version "${version}" ' . | .changes |= map({"commit", "summary", "message"}) | .downloads |= map_values({"name", "sha256"}) | {$project, "repo", $version, "number": .build, "changes", "downloads"} - ' | tee metadata.json - echo + ' metadata.json.tmp > metadata.json + cat metadata.json - name: Publish to Downloads API if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} shell: bash diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 13712d5ef..1268f0674 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -69,11 +69,13 @@ jobs: run: | cat metadata.json echo - cat metadata.json | jq --arg project "${PROJECT}" --arg version "${VERSION}" --arg number "${BUILD}" ' + mv metadata.json metadata.json.tmp + jq --arg project "${PROJECT}" --arg version "${VERSION}" --arg number "${BUILD}" ' . | .downloads |= map_values({"name", "sha256"}) | {$project, "repo", $version, "number": $number | tonumber, "changes": [], "downloads"} - ' | tee metadata.json + ' metadata.json.tmp > metadata.json + cat metadata.json - name: Publish to Downloads API if: success() shell: bash From 420f67752cae958be277bd0d9374b6c019d97ae2 Mon Sep 17 00:00:00 2001 From: basaigh <53559772+basaigh@users.noreply.github.com> Date: Sun, 28 Apr 2024 18:54:34 +0100 Subject: [PATCH 118/272] Fix suspicious stew NPEs --- .../java/org/geysermc/geyser/registry/type/ItemMappings.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java b/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java index f3cfa3f0f..94c863660 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java +++ b/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java @@ -148,9 +148,10 @@ public class ItemMappings implements DefinitionRegistry { } } else { if (!(mapping.getBedrockData() == data.getDamage() || - // Make exceptions for potions, tipped arrows, firework stars, and goat horns, whose damage values can vary + // Make exceptions for potions, tipped arrows, firework stars, goat horns, and suspicious stews, whose damage values can vary (mapping.getJavaItem() instanceof PotionItem || mapping.getJavaItem() == Items.ARROW - || mapping.getJavaItem() == Items.FIREWORK_STAR || mapping.getJavaItem() == Items.GOAT_HORN))) { + || mapping.getJavaItem() == Items.FIREWORK_STAR || mapping.getJavaItem() == Items.GOAT_HORN + || mapping.getJavaItem() == Items.SUSPICIOUS_STEW))) { continue; } } From 9b1e45007aeca1c64000d26da8dbf316d2e887ab Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Sun, 28 Apr 2024 23:41:13 +0200 Subject: [PATCH 119/272] Fix injectors, should work with Spigot/Paper 1.20.5 now --- .../org/geysermc/geyser/platform/mod/GeyserModInjector.java | 5 ++++- .../geyser/platform/spigot/GeyserSpigotInjector.java | 5 ++++- .../java/entity/player/JavaCookieRequestTranslator.java | 1 + .../java/entity/player/JavaStoreCookieTranslator.java | 1 + .../java/entity/player/JavaTransferPacketTranslator.java | 1 + 5 files changed, 11 insertions(+), 2 deletions(-) diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModInjector.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModInjector.java index 06496293f..624eccb3f 100644 --- a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModInjector.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModInjector.java @@ -93,8 +93,11 @@ public class GeyserModInjector extends GeyserInjector { protected void initChannel(@NonNull Channel ch) throws Exception { initChannel.invoke(childHandler, ch); + int index = ch.pipeline().names().indexOf("encoder"); + String baseName = index != -1 ? "encoder" : "outbound_config"; + if (bootstrap.getGeyserConfig().isDisableCompression()) { - ch.pipeline().addAfter("encoder", "geyser-compression-disabler", new GeyserModCompressionDisabler()); + ch.pipeline().addAfter(baseName, "geyser-compression-disabler", new GeyserModCompressionDisabler()); } } }) diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java index 6aa5d563f..6d22a77ae 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java @@ -119,8 +119,11 @@ public class GeyserSpigotInjector extends GeyserInjector { protected void initChannel(@NonNull Channel ch) throws Exception { initChannel.invoke(childHandler, ch); + int index = ch.pipeline().names().indexOf("encoder"); + String baseName = index != -1 ? "encoder" : "outbound_config"; + if (bootstrap.getGeyserConfig().isDisableCompression() && GeyserSpigotCompressionDisabler.ENABLED) { - ch.pipeline().addAfter("encoder", "geyser-compression-disabler", new GeyserSpigotCompressionDisabler()); + ch.pipeline().addAfter(baseName, "geyser-compression-disabler", new GeyserSpigotCompressionDisabler()); } } }) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java index 5266ebabd..33bfa7be8 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaCookieRequestTranslator.java @@ -33,6 +33,7 @@ import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.Serverbound @Translator(packet = ClientboundCookieRequestPacket.class) public class JavaCookieRequestTranslator extends PacketTranslator { + @Override public void translate(GeyserSession session, ClientboundCookieRequestPacket packet) { ServerboundCookieResponsePacket responsePacket = new ServerboundCookieResponsePacket( diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java index 19237b646..342618ff8 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java @@ -32,6 +32,7 @@ import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.Clientbound @Translator(packet = ClientboundStoreCookiePacket.class) public class JavaStoreCookieTranslator extends PacketTranslator { + @Override public void translate(GeyserSession session, ClientboundStoreCookiePacket packet) { session.getCookies().put(packet.getKey(), packet.getPayload()); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java index 86fd70677..ad793f934 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaTransferPacketTranslator.java @@ -35,6 +35,7 @@ import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.Clientbound @Translator(packet = ClientboundTransferPacket.class) public class JavaTransferPacketTranslator extends PacketTranslator { + @Override public void translate(GeyserSession session, ClientboundTransferPacket packet) { ServerTransferEvent event = new ServerTransferEvent( From 82123aecf121b4fe688d6b166500821ecd036876 Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Sun, 28 Apr 2024 23:52:23 +0200 Subject: [PATCH 120/272] Fix: Modded platform injector not being used --- .../geysermc/geyser/platform/mod/GeyserModBootstrap.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java index db966ec1a..9622736de 100644 --- a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java @@ -58,6 +58,7 @@ import org.geysermc.geyser.util.FileUtils; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.net.SocketAddress; import java.nio.file.Path; import java.util.Map; import java.util.UUID; @@ -240,6 +241,11 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap { return ip != null ? ip : ""; // See issue #3812 } + @Override + public SocketAddress getSocketAddress() { + return this.geyserInjector.getServerSocketAddress(); + } + @Override public int getServerPort() { return ((GeyserServerPortGetter) server).geyser$getServerPort(); From e8c1c2218f99c6abbaa981d71fd360cba7b9f2c7 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 29 Apr 2024 00:35:44 -0400 Subject: [PATCH 121/272] Fix banners on shields --- .../geysermc/geyser/item/type/BannerItem.java | 45 +++++++++++-------- .../geysermc/geyser/item/type/ShieldItem.java | 29 ++++++------ 2 files changed, 39 insertions(+), 35 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index 232f340ea..9f5138323 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -113,6 +113,31 @@ public class BannerItem extends BlockItem { return new NbtList<>(NbtType.COMPOUND, tagsList); } + /** + * Converts a Java item component for banners into Bedrock item NBT. + */ + static void convertBannerPattern(GeyserSession session, List patterns, BedrockItemBuilder builder) { + if (isOminous(session, patterns)) { + // Remove the current patterns and set the ominous banner type + builder.putInt("Type", 1); + } else { + List patternList = new ArrayList<>(patterns.size()); + for (BannerPatternLayer patternLayer : patterns) { + patternLayer.getPattern().ifId(holder -> { + BannerPattern bannerPattern = session.getRegistryCache().bannerPatterns().get(holder.id()); + if (bannerPattern != null) { + NbtMap tag = NbtMap.builder() + .putString("Pattern", bannerPattern.getBedrockIdentifier()) + .putInt("Color", 15 - patternLayer.getColorId()) + .build(); + patternList.add(tag); + } + }); + } + builder.putList("Patterns", NbtType.COMPOUND, patternList); + } + } + /** * Convert the Java edition banner pattern nbt to Bedrock edition, null if the pattern doesn't exist * @@ -166,25 +191,7 @@ public class BannerItem extends BlockItem { List patterns = components.get(DataComponentType.BANNER_PATTERNS); if (patterns != null) { - if (isOminous(session, patterns)) { - // Remove the current patterns and set the ominous banner type - builder.putInt("Type", 1); - } else { - List patternList = new ArrayList<>(patterns.size()); - for (BannerPatternLayer patternLayer : patterns) { - patternLayer.getPattern().ifId(holder -> { - BannerPattern bannerPattern = session.getRegistryCache().bannerPatterns().get(holder.id()); - if (bannerPattern != null) { - NbtMap tag = NbtMap.builder() - .putString("Pattern", bannerPattern.getBedrockIdentifier()) - .putInt("Color", 15 - patternLayer.getColorId()) - .build(); - patternList.add(tag); - } - }); - } - builder.putList("Patterns", NbtType.COMPOUND, patternList); - } + convertBannerPattern(session, patterns, builder); } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java index 001fa74b6..14d41a073 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java @@ -29,8 +29,12 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.item.components.ToolTier; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import java.util.List; + public class ShieldItem extends Item { public ShieldItem(String javaIdentifier, Builder builder) { super(javaIdentifier, builder); @@ -40,22 +44,15 @@ public class ShieldItem extends Item { public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { super.translateComponentsToBedrock(session, components, builder); - // TODO figure out patterns first. -// if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) { -// if (blockEntityTag.get("Patterns") instanceof ListTag patterns) { -// for (Tag pattern : patterns) { -// if (((CompoundTag) pattern).get("Color") instanceof IntTag color) { -// color.setValue(15 - color.getValue()); -// } -// } -// // Bedrock looks for patterns at the root -// tag.put(patterns); -// } -// if (blockEntityTag.get("Base") instanceof IntTag base) { -// base.setValue(15 - base.getValue()); -// tag.put(base); -// } -// } + List patterns = components.get(DataComponentType.BANNER_PATTERNS); + if (patterns != null) { + BannerItem.convertBannerPattern(session, patterns, builder); + } + // Shield pattern backing color + Integer baseColor = components.get(DataComponentType.BASE_COLOR); + if (baseColor != null) { + builder.putInt("Base", 15 - baseColor); + } } @Override From 88ae447fc6ee9667494bfefb5cd258c00d4535fc Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 29 Apr 2024 00:47:52 -0400 Subject: [PATCH 122/272] Fix banner block entity base colors with no patterns --- .../level/block/entity/BlockEntityTranslator.java | 9 +++++++-- .../block/entity/SpawnerBlockEntityTranslator.java | 5 ++++- .../entity/StructureBlockBlockEntityTranslator.java | 6 +++++- .../java/level/JavaLevelChunkWithLightTranslator.java | 11 ++++------- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java index 45981377c..6df7781be 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; @@ -40,9 +41,13 @@ public abstract class BlockEntityTranslator { public abstract void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState); - public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, NbtMap javaNbt, int blockState) { + public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, @Nullable NbtMap javaNbt, int blockState) { NbtMapBuilder tagBuilder = getConstantBedrockTag(type, x, y, z); - translateTag(session, tagBuilder, javaNbt, blockState); + if (javaNbt != null || this instanceof RequiresBlockState) { + // Always process tags if the block state is part of the tag. + // See: banner base colors. + translateTag(session, tagBuilder, javaNbt, blockState); + } return tagBuilder.build(); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java index 05b763e6b..edf71d384 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java @@ -40,7 +40,10 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType public class SpawnerBlockEntityTranslator extends BlockEntityTranslator { @Override - public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, NbtMap javaNbt, int blockState) { + public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, @Nullable NbtMap javaNbt, int blockState) { + if (javaNbt == null) { + return super.getBlockEntityTag(session, type, x, y, z, javaNbt, blockState); + } // Sending an empty EntityIdentifier to empty the spawner is ignored by the client, so we send a whole new spawner! // Fixes https://github.com/GeyserMC/Geyser/issues/4214 NbtMap spawnData = javaNbt.getCompound("SpawnData"); diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java index aefd97dd5..4bb9c5676 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -39,7 +40,10 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType public class StructureBlockBlockEntityTranslator extends BlockEntityTranslator { @Override - public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, NbtMap javaNbt, int blockState) { + public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, @Nullable NbtMap javaNbt, int blockState) { + if (javaNbt == null) { + return super.getBlockEntityTag(session, type, x, y, z, javaNbt, blockState); + } // Sending a structure with size 0 doesn't clear the outline. Hence, we have to force it by replacing the block :/ int xStructureSize = javaNbt.getInt("sizeX"); int yStructureSize = javaNbt.getInt("sizeY"); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java index c3a399863..29db95e3f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java @@ -412,13 +412,10 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator Date: Mon, 29 Apr 2024 01:03:18 -0400 Subject: [PATCH 123/272] Firework shapes --- .../org/geysermc/geyser/item/type/FireworkRocketItem.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java index 1265956da..bba13e753 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java @@ -92,10 +92,7 @@ public class FireworkRocketItem extends Item { static NbtMap translateExplosionToBedrock(Fireworks.FireworkExplosion explosion) { NbtMapBuilder newExplosionData = NbtMap.builder(); -// if (explosion.get("Type") != null) { -// newExplosionData.put(new ByteTag("FireworkType", MathUtils.getNbtByte(explosion.get("Type").getValue()))); -// } - //newExplosionData.putByte("FireworkType", explosion.get) //TODO??? + newExplosionData.putByte("FireworkType", (byte) explosion.getShapeId()); int[] oldColors = explosion.getColors(); byte[] colors = new byte[oldColors.length]; From 4ff746e48ab4562978fab9981df2ea1f7cc8a039 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Mon, 29 Apr 2024 04:20:24 -0400 Subject: [PATCH 124/272] Fix translateTag NPE --- .../level/block/entity/BannerBlockEntityTranslator.java | 3 ++- .../level/block/entity/BrushableBlockEntityTranslator.java | 7 ++++++- .../block/entity/JigsawBlockBlockEntityTranslator.java | 7 ++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java index c87d1a217..81f58214c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; @@ -38,7 +39,7 @@ import java.util.List; @BlockEntity(type = BlockEntityType.BANNER) public class BannerBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override - public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, @Nullable NbtMap javaNbt, int blockState) { int bannerColor = BlockStateValues.getBannerColor(blockState); if (bannerColor != -1) { bedrockNbt.putInt("Base", 15 - bannerColor); diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java index 4f9dfec46..b4012236b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.item.Items; @@ -37,7 +38,11 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType public class BrushableBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override - public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, @Nullable NbtMap javaNbt, int blockState) { + if (javaNbt == null) { + return; + } + NbtMap itemTag = javaNbt.getCompound("item"); if (itemTag.isEmpty()) { return; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java index bd83e3d54..53f32682c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.block.BlockStateValues; @@ -34,7 +35,11 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType @BlockEntity(type = BlockEntityType.JIGSAW) public class JigsawBlockBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override - public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, @Nullable NbtMap javaNbt, int blockState) { + if (javaNbt == null) { + return; + } + String joint = javaNbt.getString("joint", null); if (joint != null) { bedrockNbt.putString("joint", joint); From 8b7b8cdffdb7aba97ef817037859d1151f4b2665 Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Mon, 29 Apr 2024 16:08:14 +0200 Subject: [PATCH 125/272] Properly shutdown LocalSession's, ensure transferring works properly regardless if we're injected or not --- bootstrap/mod/fabric/build.gradle.kts | 2 -- .../platform/spigot/GeyserSpigotInjector.java | 2 +- .../geysermc/geyser/network/netty/LocalSession.java | 13 +++++++------ .../org/geysermc/geyser/session/GeyserSession.java | 4 ++-- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/bootstrap/mod/fabric/build.gradle.kts b/bootstrap/mod/fabric/build.gradle.kts index 53e4dfe53..cd513c1e4 100644 --- a/bootstrap/mod/fabric/build.gradle.kts +++ b/bootstrap/mod/fabric/build.gradle.kts @@ -49,9 +49,7 @@ application { relocate("org.cloudburstmc.netty") relocate("org.cloudburstmc.protocol") -relocate("com.github.steveice10.mc.protocol") relocate("com.github.steveice10.mc.auth") -relocate("com.github.steveice10.packetlib") tasks { remapJar { diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java index 6d22a77ae..5dcfbd0f8 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java @@ -178,7 +178,7 @@ public class GeyserSpigotInjector extends GeyserInjector { MinecraftProtocol protocol = new MinecraftProtocol(); LocalSession session = new LocalSession(bootstrap.getGeyserConfig().getRemote().address(), bootstrap.getGeyserConfig().getRemote().port(), this.serverSocketAddress, - InetAddress.getLoopbackAddress().getHostAddress(), protocol, protocol.createHelper(), false); + InetAddress.getLoopbackAddress().getHostAddress(), protocol, protocol.createHelper()); session.connect(); session.disconnect(""); } diff --git a/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java b/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java index b5598d063..958e88288 100644 --- a/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java +++ b/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java @@ -30,6 +30,7 @@ import io.netty.buffer.ByteBufAllocator; import io.netty.channel.*; import io.netty.channel.unix.PreferredDirectByteBufAllocator; import io.netty.handler.codec.haproxy.*; +import io.netty.util.concurrent.DefaultThreadFactory; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.mcprotocollib.network.BuiltinFlags; import org.geysermc.mcprotocollib.network.codec.PacketCodecHelper; @@ -42,6 +43,7 @@ import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodecHelper; import java.net.Inet4Address; import java.net.InetSocketAddress; import java.net.SocketAddress; +import java.util.concurrent.TimeUnit; /** * Manages a Minecraft Java session over our LocalChannel implementations. @@ -54,24 +56,23 @@ public final class LocalSession extends TcpSession { private final String clientIp; private final PacketCodecHelper codecHelper; - private final boolean transferring; - - public LocalSession(String host, int port, SocketAddress targetAddress, String clientIp, PacketProtocol protocol, MinecraftCodecHelper codecHelper, boolean transferring) { + public LocalSession(String host, int port, SocketAddress targetAddress, String clientIp, PacketProtocol protocol, MinecraftCodecHelper codecHelper) { super(host, port, protocol); this.targetAddress = targetAddress; this.clientIp = clientIp; this.codecHelper = codecHelper; - this.transferring = transferring; } @Override - public void connect(boolean wait) { + public void connect(boolean wait, boolean transferring) { if (this.disconnected) { throw new IllegalStateException("Connection has already been disconnected."); } if (DEFAULT_EVENT_LOOP_GROUP == null) { - DEFAULT_EVENT_LOOP_GROUP = new DefaultEventLoopGroup(); + DEFAULT_EVENT_LOOP_GROUP = new DefaultEventLoopGroup(new DefaultThreadFactory(this.getClass(), true)); + Runtime.getRuntime().addShutdownHook(new Thread( + () -> DEFAULT_EVENT_LOOP_GROUP.shutdownGracefully(100, 500, TimeUnit.MILLISECONDS))); } try { diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 869999357..d10a20b3d 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -880,7 +880,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { // We're going to connect through the JVM and not through TCP downstream = new LocalSession(this.remoteServer.address(), this.remoteServer.port(), geyser.getBootstrap().getSocketAddress(), upstream.getAddress().getAddress().getHostAddress(), - this.protocol, this.protocol.createHelper(), loginEvent.transferring()); + this.protocol, this.protocol.createHelper()); this.downstream = new DownstreamSession(downstream); } else { downstream = new TcpClientSession(this.remoteServer.address(), this.remoteServer.port(), this.protocol); @@ -1070,7 +1070,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { setDaylightCycle(true); } - downstream.connect(false); + downstream.connect(false, loginEvent.transferring()); } public void disconnect(String reason) { From 5d3630cf236aa47eb4e494272764ea58a02857d6 Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Mon, 29 Apr 2024 23:19:18 +0200 Subject: [PATCH 126/272] ominous banners - this really isn't ideal --- .../platform/spigot/GeyserSpigotPlugin.java | 4 +-- .../geyser/inventory/item/BannerPattern.java | 16 +++++----- .../geysermc/geyser/item/type/BannerItem.java | 32 ++++++++++++++----- .../geyser/session/GeyserSession.java | 1 + .../geyser/session/cache/RegistryCache.java | 19 +++++++++-- 5 files changed, 52 insertions(+), 20 deletions(-) diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java index 1f14a2f65..1170ce678 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java @@ -244,8 +244,8 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { if (Boolean.parseBoolean(System.getProperty("Geyser.UseDirectAdapters", "true"))) { try { - String name = Bukkit.getServer().getClass().getPackage().getName(); - String nmsVersion = name.substring(name.lastIndexOf('.') + 1); + String version = Bukkit.getBukkitVersion().split("-")[0]; + String nmsVersion = "v" + version.replace(".", "_"); SpigotAdapters.registerWorldAdapter(nmsVersion); if (isViaVersion && isViaVersionNeeded()) { this.geyserWorldManager = new GeyserSpigotLegacyNativeWorldManager(this); diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java b/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java index 442690d7d..ae225073a 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java @@ -45,7 +45,7 @@ public enum BannerPattern { STRIPE_MIDDLE("ms"), STRIPE_DOWNRIGHT("drs"), STRIPE_DOWNLEFT("dls"), - SMALL_STRIPES("ss"), + STRIPE_SMALL("ss"), CROSS("cr"), STRAIGHT_CROSS("sc"), TRIANGLE_BOTTOM("bt"), @@ -53,15 +53,15 @@ public enum BannerPattern { TRIANGLES_BOTTOM("bts"), TRIANGLES_TOP("tts"), DIAGONAL_LEFT("ld"), - DIAGONAL_UP_RIGHT("rd"), - DIAGONAL_UP_LEFT("lud"), - DIAGONAL_RIGHT("rud"), - CIRCLE("mc"), - RHOMBUS("mr"), + DIAGONAL_RIGHT("rd"), + DIAGONAL_LEFT_MIRROR("lud"), + DIAGONAL_RIGHT_MIRROR("rud"), + CIRCLE_MIDDLE("mc"), + RHOMBUS_MIDDLE("mr"), HALF_VERTICAL("vh"), HALF_HORIZONTAL("hh"), - HALF_VERTICAL_RIGHT("vhr"), - HALF_HORIZONTAL_BOTTOM("hhb"), + HALF_VERTICAL_MIRROR("vhr"), + HALF_HORIZONTAL_MIRROR("hhb"), BORDER("bo"), CURLY_BORDER("cbo"), GRADIENT("gra"), diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index 9f5138323..255e320a6 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -26,18 +26,26 @@ package org.geysermc.geyser.item.type; import it.unimi.dsi.fastutil.Pair; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.text.format.TextColor; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtList; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtType; +import org.cloudburstmc.protocol.common.util.Int2ObjectBiMap; import org.geysermc.geyser.inventory.item.BannerPattern; import org.geysermc.geyser.inventory.item.DyeColor; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.text.GeyserLocale; +import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.Holder; import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.Unit; import java.util.ArrayList; import java.util.List; @@ -56,13 +64,13 @@ public class BannerItem extends BlockItem { static { // Construct what an ominous banner is supposed to look like OMINOUS_BANNER_PATTERN = List.of( - Pair.of(BannerPattern.RHOMBUS, DyeColor.CYAN), + Pair.of(BannerPattern.RHOMBUS_MIDDLE, DyeColor.CYAN), Pair.of(BannerPattern.STRIPE_BOTTOM, DyeColor.LIGHT_GRAY), Pair.of(BannerPattern.STRIPE_CENTER, DyeColor.GRAY), Pair.of(BannerPattern.BORDER, DyeColor.LIGHT_GRAY), Pair.of(BannerPattern.STRIPE_MIDDLE, DyeColor.BLACK), Pair.of(BannerPattern.HALF_HORIZONTAL, DyeColor.LIGHT_GRAY), - Pair.of(BannerPattern.CIRCLE, DyeColor.LIGHT_GRAY), + Pair.of(BannerPattern.CIRCLE_MIDDLE, DyeColor.LIGHT_GRAY), Pair.of(BannerPattern.BORDER, DyeColor.BLACK) ); @@ -171,14 +179,13 @@ public class BannerItem extends BlockItem { * @return The Java edition format pattern layer */ public static BannerPatternLayer getJavaBannerPattern(GeyserSession session, NbtMap pattern) { - return null; // TODO - /*Int2ObjectBiMap registry = session.getRegistryCache().bannerPatterns(); + Int2ObjectBiMap registry = session.getRegistryCache().bannerPatterns(); BannerPattern bannerPattern = BannerPattern.getByBedrockIdentifier(pattern.getString("Pattern")); DyeColor dyeColor = DyeColor.getById(15 - pattern.getInt("Color")); if (bannerPattern != null && dyeColor != null && registry.containsValue(bannerPattern)) { return new BannerPatternLayer(Holder.ofId(registry.get(bannerPattern)), dyeColor.ordinal()); } - return null;*/ + return null; } public BannerItem(String javaIdentifier, Builder builder) { @@ -196,13 +203,22 @@ public class BannerItem extends BlockItem { } @Override - public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) { // TODO + public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) { super.translateNbtToJava(bedrockTag, components, mapping); if (bedrockTag.getInt("Type") == 1) { // Ominous banner pattern - // TODO more registry stuff - //components.put(DataComponentType.BANNER_PATTERNS); + List patternLayers = new ArrayList<>(); + for (Pair pair : OMINOUS_BANNER_PATTERN) { + patternLayers.add(new BannerPatternLayer(Holder.ofId(pair.left().ordinal()), pair.right().ordinal())); + } + + components.put(DataComponentType.BANNER_PATTERNS, patternLayers); + components.put(DataComponentType.HIDE_ADDITIONAL_TOOLTIP, Unit.INSTANCE); + components.put(DataComponentType.ITEM_NAME, Component.text( + MinecraftLocale.getLocaleString("block.minecraft.ominous_banner", GeyserLocale.getDefaultLocale()) + ).style(Style.style(TextColor.color(16755200))) + ); } // Bedrock's creative inventory does not support other patterns as of 1.20.5 } diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index d10a20b3d..869917b4c 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -579,6 +579,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { private final GeyserEntityData entityData; + @Getter private MinecraftProtocol protocol; public GeyserSession(GeyserImpl geyser, BedrockServerSession bedrockServerSession, EventLoop eventLoop) { diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java index 7ad2afec7..22fc72cf4 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java @@ -34,6 +34,7 @@ import lombok.Getter; import lombok.experimental.Accessors; import org.cloudburstmc.protocol.bedrock.data.TrimMaterial; import org.cloudburstmc.protocol.bedrock.data.TrimPattern; +import org.cloudburstmc.protocol.common.util.Int2ObjectBiMap; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.entity.type.living.animal.tameable.WolfEntity; import org.geysermc.geyser.inventory.item.BannerPattern; @@ -70,7 +71,7 @@ public final class RegistryCache { register("trim_material", cache -> cache.trimMaterials, TrimRecipe::readTrimMaterial); register("trim_pattern", cache -> cache.trimPatterns, TrimRecipe::readTrimPattern); register("worldgen/biome", (cache, array) -> cache.biomeTranslations = array, BiomeTranslator::loadServerBiome); - register("banner_pattern", cache -> cache.bannerPatterns, ($, entry) -> BannerPattern.getByJavaIdentifier(entry.getId())); + registerBannerRegistry(($, entry) -> BannerPattern.getByJavaIdentifier(entry.getId())); register("wolf_variant", cache -> cache.wolfVariants, ($, entry) -> WolfEntity.WolfVariant.getByJavaIdentifier(entry.getId())); } @@ -89,7 +90,7 @@ public final class RegistryCache { private final Int2ObjectMap trimMaterials = new Int2ObjectOpenHashMap<>(); private final Int2ObjectMap trimPatterns = new Int2ObjectOpenHashMap<>(); - private final Int2ObjectMap bannerPatterns = new Int2ObjectOpenHashMap<>(); + private Int2ObjectBiMap bannerPatterns = new Int2ObjectBiMap<>(); private final Int2ObjectMap wolfVariants = new Int2ObjectOpenHashMap<>(); public RegistryCache(GeyserSession session) { @@ -108,6 +109,20 @@ public final class RegistryCache { } } + private static void registerBannerRegistry(BiFunction reader) { + REGISTRIES.put("minecraft:banner_pattern", ((registryCache, entries) -> { + // Clear each local cache every time a new registry entry is given to us + // (e.g. proxy server switches) + registryCache.bannerPatterns = new Int2ObjectBiMap<>(); + for (int i = 0; i < entries.size(); i++) { + RegistryEntry entry = entries.get(i); + // This is what Geyser wants to keep as a value for this registry. + T cacheEntry = reader.apply(registryCache.session, entry); + registryCache.bannerPatterns.put(i, (BannerPattern) cacheEntry); + } + })); + } + /** * @param registry the Java registry resource location, without the "minecraft:" prefix. * @param localCacheFunction which local field in RegistryCache are we caching entries for this registry? From 28d5db622bbe60f583d7727de147949173b3d093 Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Mon, 29 Apr 2024 23:41:14 +0200 Subject: [PATCH 127/272] revert bad change --- .../geyser/inventory/item/BannerPattern.java | 16 ++++++++-------- .../geysermc/geyser/item/type/BannerItem.java | 5 +++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java b/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java index ae225073a..442690d7d 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java @@ -45,7 +45,7 @@ public enum BannerPattern { STRIPE_MIDDLE("ms"), STRIPE_DOWNRIGHT("drs"), STRIPE_DOWNLEFT("dls"), - STRIPE_SMALL("ss"), + SMALL_STRIPES("ss"), CROSS("cr"), STRAIGHT_CROSS("sc"), TRIANGLE_BOTTOM("bt"), @@ -53,15 +53,15 @@ public enum BannerPattern { TRIANGLES_BOTTOM("bts"), TRIANGLES_TOP("tts"), DIAGONAL_LEFT("ld"), - DIAGONAL_RIGHT("rd"), - DIAGONAL_LEFT_MIRROR("lud"), - DIAGONAL_RIGHT_MIRROR("rud"), - CIRCLE_MIDDLE("mc"), - RHOMBUS_MIDDLE("mr"), + DIAGONAL_UP_RIGHT("rd"), + DIAGONAL_UP_LEFT("lud"), + DIAGONAL_RIGHT("rud"), + CIRCLE("mc"), + RHOMBUS("mr"), HALF_VERTICAL("vh"), HALF_HORIZONTAL("hh"), - HALF_VERTICAL_MIRROR("vhr"), - HALF_HORIZONTAL_MIRROR("hhb"), + HALF_VERTICAL_RIGHT("vhr"), + HALF_HORIZONTAL_BOTTOM("hhb"), BORDER("bo"), CURLY_BORDER("cbo"), GRADIENT("gra"), diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index 255e320a6..2f2d09669 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -64,13 +64,13 @@ public class BannerItem extends BlockItem { static { // Construct what an ominous banner is supposed to look like OMINOUS_BANNER_PATTERN = List.of( - Pair.of(BannerPattern.RHOMBUS_MIDDLE, DyeColor.CYAN), + Pair.of(BannerPattern.RHOMBUS, DyeColor.CYAN), Pair.of(BannerPattern.STRIPE_BOTTOM, DyeColor.LIGHT_GRAY), Pair.of(BannerPattern.STRIPE_CENTER, DyeColor.GRAY), Pair.of(BannerPattern.BORDER, DyeColor.LIGHT_GRAY), Pair.of(BannerPattern.STRIPE_MIDDLE, DyeColor.BLACK), Pair.of(BannerPattern.HALF_HORIZONTAL, DyeColor.LIGHT_GRAY), - Pair.of(BannerPattern.CIRCLE_MIDDLE, DyeColor.LIGHT_GRAY), + Pair.of(BannerPattern.CIRCLE, DyeColor.LIGHT_GRAY), Pair.of(BannerPattern.BORDER, DyeColor.BLACK) ); @@ -211,6 +211,7 @@ public class BannerItem extends BlockItem { List patternLayers = new ArrayList<>(); for (Pair pair : OMINOUS_BANNER_PATTERN) { patternLayers.add(new BannerPatternLayer(Holder.ofId(pair.left().ordinal()), pair.right().ordinal())); + System.out.println("adding: " + pair.left().getJavaIdentifier() + " " + pair.right().name()); } components.put(DataComponentType.BANNER_PATTERNS, patternLayers); From c963503fef83d17fe0286e665142b474120e8ded Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 30 Apr 2024 00:33:49 -0400 Subject: [PATCH 128/272] Entity scale attribute is now applied --- .../geyser/entity/EntityDefinitions.java | 2 +- .../entity/attribute/GeyserAttributeType.java | 1 + .../geyser/entity/type/LivingEntity.java | 36 +++++++++++++++++++ .../entity/type/living/AgeableEntity.java | 5 ++- .../entity/type/living/ArmorStandEntity.java | 10 +++--- .../entity/type/living/SlimeEntity.java | 5 ++- .../type/living/monster/GiantEntity.java | 7 ++-- .../type/living/monster/PhantomEntity.java | 3 +- .../type/living/monster/PiglinEntity.java | 3 +- .../type/living/monster/ZoglinEntity.java | 3 +- .../type/living/monster/ZombieEntity.java | 3 +- .../org/geysermc/geyser/util/MathUtils.java | 11 ------ 12 files changed, 56 insertions(+), 33 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index fd0673062..ed2cda9b9 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -673,7 +673,7 @@ public final class EntityDefinitions { SLIME = EntityDefinition.inherited(SlimeEntity::new, mobEntityBase) .type(EntityType.SLIME) .heightAndWidth(0.51f) - .addTranslator(MetadataType.INT, SlimeEntity::setScale) + .addTranslator(MetadataType.INT, SlimeEntity::setSlimeScale) .build(); MAGMA_CUBE = EntityDefinition.inherited(MagmaCubeEntity::new, SLIME) .type(EntityType.MAGMA_CUBE) diff --git a/core/src/main/java/org/geysermc/geyser/entity/attribute/GeyserAttributeType.java b/core/src/main/java/org/geysermc/geyser/entity/attribute/GeyserAttributeType.java index 88d493275..f19912a8c 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/attribute/GeyserAttributeType.java +++ b/core/src/main/java/org/geysermc/geyser/entity/attribute/GeyserAttributeType.java @@ -49,6 +49,7 @@ public enum GeyserAttributeType { ATTACK_KNOCKBACK("minecraft:generic.attack_knockback", null, 1.5f, Float.MAX_VALUE, 0f), ATTACK_SPEED("minecraft:generic.attack_speed", null, 0f, 1024f, 4f), MAX_HEALTH("minecraft:generic.max_health", null, 0f, 1024f, 20f), + SCALE("minecraft:generic.scale", null, 0.0625f, 16f, 1f), // Unused. Do we need this? // Bedrock Attributes ABSORPTION(null, "minecraft:absorption", 0f, 1024f, 0f), diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java index 58a3bf8e7..d27fa3cad 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java @@ -86,6 +86,19 @@ public class LivingEntity extends Entity { */ private boolean isMaxFrozenState = false; + /** + * The base scale entity data, without attributes applied. Used for such cases as baby variants. + */ + @Getter(AccessLevel.NONE) + @Setter(AccessLevel.NONE) + private float scale; + /** + * The scale sent through the Java attributes packet + */ + @Getter(AccessLevel.NONE) + @Setter(AccessLevel.NONE) + private float attributeScale; + public LivingEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); } @@ -122,6 +135,9 @@ public class LivingEntity extends Entity { @Override protected void initializeMetadata() { + // Initialize here so overriding classes don't have 0 values + this.scale = 1f; + this.attributeScale = 1f; super.initializeMetadata(); // Matches Bedrock behavior; is always set to this dirtyMetadata.put(EntityDataTypes.STRUCTURAL_INTEGRITY, 1); @@ -230,6 +246,21 @@ public class LivingEntity extends Entity { return freezingPercentage; } + protected void setScale(float scale) { + this.scale = scale; + applyScale(); + } + + private void setAttributeScale(float scale) { + this.attributeScale = scale; + applyScale(); + } + + private void applyScale() { + // Take any adjustments Bedrock requires, and compute it alongside the attribute's additional changes + this.dirtyMetadata.put(EntityDataTypes.SCALE, scale * attributeScale); + } + /** * @return a Bedrock health attribute constructed from the data sent from the server */ @@ -366,6 +397,11 @@ public class LivingEntity extends Entity { case GENERIC_FOLLOW_RANGE -> newAttributes.add(calculateAttribute(javaAttribute, GeyserAttributeType.FOLLOW_RANGE)); case GENERIC_KNOCKBACK_RESISTANCE -> newAttributes.add(calculateAttribute(javaAttribute, GeyserAttributeType.KNOCKBACK_RESISTANCE)); case GENERIC_JUMP_STRENGTH -> newAttributes.add(calculateAttribute(javaAttribute, GeyserAttributeType.HORSE_JUMP_STRENGTH)); + case GENERIC_SCALE -> { + // Attribute on Java, entity data on Bedrock + setAttributeScale((float) AttributeUtils.calculateValue(javaAttribute)); + updateBedrockMetadata(); + } } } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/AgeableEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/AgeableEntity.java index 5b1d682ce..8f84e051b 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/AgeableEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/AgeableEntity.java @@ -26,7 +26,6 @@ package org.geysermc.geyser.entity.type.living; import org.cloudburstmc.math.vector.Vector3f; -import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; @@ -44,12 +43,12 @@ public class AgeableEntity extends CreatureEntity { protected void initializeMetadata() { super.initializeMetadata(); // Required as of 1.19.3 Java - dirtyMetadata.put(EntityDataTypes.SCALE, getAdultSize()); + setScale(getAdultSize()); } public void setBaby(BooleanEntityMetadata entityMetadata) { boolean isBaby = entityMetadata.getPrimitiveValue(); - dirtyMetadata.put(EntityDataTypes.SCALE, isBaby ? getBabySize() : getAdultSize()); + setScale(isBaby ? getBabySize() : getAdultSize()); setFlag(EntityFlag.BABY, isBaby); setBoundingBoxHeight(definition.height() * (isBaby ? getBabySize() : getAdultSize())); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java index fce51e741..d057f09c7 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java @@ -311,7 +311,7 @@ public class ArmorStandEntity extends LivingEntity { if (!isInvisible) { // The armor stand isn't invisible. We good. setFlag(EntityFlag.INVISIBLE, false); - dirtyMetadata.put(EntityDataTypes.SCALE, getScale()); + setScale(getScale()); updateOffsetRequirement(false); if (secondEntity != null) { @@ -327,7 +327,7 @@ public class ArmorStandEntity extends LivingEntity { if (!isNametagEmpty && (!helmet.equals(ItemData.AIR) || !chestplate.equals(ItemData.AIR) || !leggings.equals(ItemData.AIR) || !boots.equals(ItemData.AIR) || !hand.equals(ItemData.AIR) || !offhand.equals(ItemData.AIR))) { // Reset scale of the proper armor stand - this.dirtyMetadata.put(EntityDataTypes.SCALE, getScale()); + setScale(getScale()); // Set the proper armor stand to invisible to show armor setFlag(EntityFlag.INVISIBLE, true); // Update the position of the armor stand @@ -350,7 +350,7 @@ public class ArmorStandEntity extends LivingEntity { // Guarantee this copy is NOT invisible secondEntity.setFlag(EntityFlag.INVISIBLE, false); // Scale to 0 to show nametag - secondEntity.getDirtyMetadata().put(EntityDataTypes.SCALE, 0.0f); + secondEntity.setScale(0f); // No bounding box as we don't want to interact with this entity secondEntity.getDirtyMetadata().put(EntityDataTypes.WIDTH, 0.0f); secondEntity.getDirtyMetadata().put(EntityDataTypes.HEIGHT, 0.0f); @@ -360,7 +360,7 @@ public class ArmorStandEntity extends LivingEntity { } else if (isNametagEmpty) { // We can just make an invisible entity // Reset scale of the proper armor stand - dirtyMetadata.put(EntityDataTypes.SCALE, getScale()); + setScale(getScale()); // Set the proper armor stand to invisible to show armor setFlag(EntityFlag.INVISIBLE, true); // Update offset @@ -374,7 +374,7 @@ public class ArmorStandEntity extends LivingEntity { // Nametag is not empty and there is no armor // We don't need to make a new entity setFlag(EntityFlag.INVISIBLE, false); - dirtyMetadata.put(EntityDataTypes.SCALE, 0.0f); + setScale(0f); // As the above is applied, we need an offset updateOffsetRequirement(!isMarker); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/SlimeEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/SlimeEntity.java index 50095fe3f..3be2db1db 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/SlimeEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/SlimeEntity.java @@ -26,7 +26,6 @@ package org.geysermc.geyser.entity.type.living; import org.cloudburstmc.math.vector.Vector3f; -import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; @@ -39,8 +38,8 @@ public class SlimeEntity extends MobEntity { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); } - public void setScale(IntEntityMetadata entityMetadata) { - dirtyMetadata.put(EntityDataTypes.SCALE, 0.10f + entityMetadata.getPrimitiveValue()); + public void setSlimeScale(IntEntityMetadata entityMetadata) { + setScale(0.10f + entityMetadata.getPrimitiveValue()); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/GiantEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/GiantEntity.java index e98c8f120..6bef3ae3e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/GiantEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/GiantEntity.java @@ -26,7 +26,6 @@ package org.geysermc.geyser.entity.type.living.monster; import org.cloudburstmc.math.vector.Vector3f; -import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; @@ -36,7 +35,11 @@ public class GiantEntity extends MonsterEntity { public GiantEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); + } - dirtyMetadata.put(EntityDataTypes.SCALE, 6f); + @Override + protected void initializeMetadata() { + super.initializeMetadata(); + setScale(6f); } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PhantomEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PhantomEntity.java index cb4b7a8cf..18b7f6ae1 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PhantomEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PhantomEntity.java @@ -26,7 +26,6 @@ package org.geysermc.geyser.entity.type.living.monster; import org.cloudburstmc.math.vector.Vector3f; -import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.living.FlyingEntity; import org.geysermc.geyser.session.GeyserSession; @@ -46,7 +45,7 @@ public class PhantomEntity extends FlyingEntity { setBoundingBoxWidth(boundsScale * definition.width()); setBoundingBoxHeight(boundsScale * definition.height()); - dirtyMetadata.put(EntityDataTypes.SCALE, modelScale); + setScale(modelScale); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java index 9c43ab23a..f0f01272f 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java @@ -27,7 +27,6 @@ package org.geysermc.geyser.entity.type.living.monster; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; -import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; @@ -49,7 +48,7 @@ public class PiglinEntity extends BasePiglinEntity { public void setBaby(BooleanEntityMetadata entityMetadata) { boolean isBaby = entityMetadata.getPrimitiveValue(); - dirtyMetadata.put(EntityDataTypes.SCALE, isBaby? .55f : 1f); + setScale(isBaby? .55f : 1f); setFlag(EntityFlag.BABY, isBaby); updateMountOffset(); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java index efbb7753c..7eb950e21 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java @@ -26,7 +26,6 @@ package org.geysermc.geyser.entity.type.living.monster; import org.cloudburstmc.math.vector.Vector3f; -import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; @@ -43,7 +42,7 @@ public class ZoglinEntity extends MonsterEntity { public void setBaby(BooleanEntityMetadata entityMetadata) { boolean isBaby = entityMetadata.getPrimitiveValue(); if (isBaby != getFlag(EntityFlag.BABY)) { - dirtyMetadata.put(EntityDataTypes.SCALE, isBaby ? .55f : 1f); + setScale(isBaby ? .55f : 1f); setFlag(EntityFlag.BABY, isBaby); updatePassengerOffsets(); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieEntity.java index 11354fbf8..b8351089d 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieEntity.java @@ -26,7 +26,6 @@ package org.geysermc.geyser.entity.type.living.monster; import org.cloudburstmc.math.vector.Vector3f; -import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; @@ -43,7 +42,7 @@ public class ZombieEntity extends MonsterEntity { public void setZombieBaby(BooleanEntityMetadata entityMetadata) { boolean isBaby = entityMetadata.getPrimitiveValue(); - dirtyMetadata.put(EntityDataTypes.SCALE, isBaby ? .55f : 1.0f); + setScale(isBaby ? .55f : 1.0f); setFlag(EntityFlag.BABY, isBaby); updateMountOffset(); diff --git a/core/src/main/java/org/geysermc/geyser/util/MathUtils.java b/core/src/main/java/org/geysermc/geyser/util/MathUtils.java index 32f8b7ef5..08bed56f4 100644 --- a/core/src/main/java/org/geysermc/geyser/util/MathUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/MathUtils.java @@ -168,17 +168,6 @@ public class MathUtils { return value; } - /** - * Ensures the resulting object is a byte. Java Edition does not care whether a byte is encoded as an integer or not; - * it converts it into a byte anyway. - * - * @param value The value to convert - * @return The converted byte - */ - public static byte getNbtByte(Object value) { - return ((Number) value).byteValue(); - } - /** * Packs a chunk's X and Z coordinates into a single {@code long}. * From dacacc6df8ce009f74bca901196bc69c0cf7c5ca Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Tue, 30 Apr 2024 04:45:07 -0400 Subject: [PATCH 129/272] Anvil renaming --- .../org/geysermc/geyser/inventory/AnvilContainer.java | 8 ++++---- .../inventory/updater/AnvilInventoryUpdater.java | 3 +-- .../geyser/translator/text/MessageTranslator.java | 10 +++++++--- gradle/libs.versions.toml | 2 +- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java index e6332bc41..88838d068 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.inventory; +import net.kyori.adventure.text.Component; import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket; import lombok.Getter; @@ -72,10 +73,9 @@ public class AnvilContainer extends Container { String correctRename; newName = rename; - // TODO 1.20.5 fix properly - this name is apparently nullable?? - String originalName = MessageTranslator.convertMessage(ItemUtils.getCustomName(getInput().getComponents())); + Component originalName = ItemUtils.getCustomName(getInput().getComponents()); - String plainOriginalName = MessageTranslator.convertToPlainTextLenient(originalName, session.locale()); + String plainOriginalName = MessageTranslator.convertToPlainText(originalName, session.locale()); String plainNewName = MessageTranslator.convertToPlainText(rename); if (!plainOriginalName.equals(plainNewName)) { // Strip out formatting since Java Edition does not allow it @@ -85,7 +85,7 @@ public class AnvilContainer extends Container { session.sendDownstreamGamePacket(renameItemPacket); } else { // Restore formatting for item since we're not renaming - correctRename = MessageTranslator.convertMessageLenient(originalName); + correctRename = MessageTranslator.convertMessage(originalName, session.locale()); // Java Edition sends the original custom name when not renaming, // if there isn't a custom name an empty string is sent ServerboundRenameItemPacket renameItemPacket = new ServerboundRenameItemPacket(plainOriginalName); diff --git a/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java b/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java index 1021a5fb9..42924435e 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java @@ -118,8 +118,7 @@ public class AnvilInventoryUpdater extends InventoryUpdater { // Changing the item in the input slot resets the name field on Bedrock, but // does not result in a FilterTextPacket - // TODO test - String originalName = MessageTranslator.convertToPlainText(ItemUtils.getCustomName(input.getComponents())); + String originalName = MessageTranslator.convertToPlainText(ItemUtils.getCustomName(input.getComponents()), session.locale()); ServerboundRenameItemPacket renameItemPacket = new ServerboundRenameItemPacket(originalName); session.sendDownstreamGamePacket(renameItemPacket); diff --git a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java index 3f1c902c7..884f05256 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java @@ -260,13 +260,17 @@ public class MessageTranslator { } /** - * Convert legacy format message to plain text + * Convert a Java message to plain text * * @param message Message to convert + * @param locale Locale to use for translation strings * @return The plain text of the message */ - public static String convertToPlainText(Component message) { - return PlainTextComponentSerializer.plainText().serialize(message); + public static String convertToPlainText(Component message, String locale) { + if (message == null) { + return ""; + } + return PlainTextComponentSerializer.plainText().serialize(RENDERER.render(message, locale)); } /** diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7c16b883b..ab607495a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "400f1b4" # Revert from jitpack after release +mcprotocollib = "bc8526b" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From 74d6a37261c4516eab154f5622204b619156f609 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Tue, 30 Apr 2024 05:13:00 -0400 Subject: [PATCH 130/272] Fix bug when adding enchantments in anvil --- .../geyser/inventory/updater/AnvilInventoryUpdater.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java b/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java index 42924435e..d6a0d922b 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java @@ -387,7 +387,7 @@ public class AnvilInventoryUpdater extends InventoryUpdater { } return enchantments; } - return Object2IntMaps.emptyMap(); + return new Object2IntOpenHashMap<>(); } private boolean isEnchantedBook(GeyserItemStack itemStack) { From ff9965f5590c9c93bb1d01377de139f8ac1c490f Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Tue, 30 Apr 2024 05:49:22 -0400 Subject: [PATCH 131/272] Translate item repair cost component --- core/src/main/java/org/geysermc/geyser/item/type/Item.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/Item.java b/core/src/main/java/org/geysermc/geyser/item/type/Item.java index 8fcb19ad5..cc49f3785 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/Item.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/Item.java @@ -146,6 +146,11 @@ public class Item { if (!enchantNbtList.isEmpty()) { builder.putList("ench", NbtType.COMPOUND, enchantNbtList); } + + Integer repairCost = components.get(DataComponentType.REPAIR_COST); + if (repairCost != null) { + builder.putInt("RepairCost", repairCost); + } } /** From dd745b901f7826a3ef85ab7a2f0ea4f6e575e9b2 Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Tue, 30 Apr 2024 20:48:10 +0200 Subject: [PATCH 132/272] move to paper-adapters --- bootstrap/spigot/build.gradle.kts | 9 +++++++ .../platform/spigot/GeyserSpigotPlugin.java | 24 ++++++++++++++----- .../GeyserSpigotLegacyNativeWorldManager.java | 4 ++-- .../GeyserSpigotNativeWorldManager.java | 14 +++++++---- gradle/libs.versions.toml | 3 ++- 5 files changed, 41 insertions(+), 13 deletions(-) diff --git a/bootstrap/spigot/build.gradle.kts b/bootstrap/spigot/build.gradle.kts index 1d135c33d..8143d96a1 100644 --- a/bootstrap/spigot/build.gradle.kts +++ b/bootstrap/spigot/build.gradle.kts @@ -7,6 +7,9 @@ dependencies { implementation(variantOf(libs.adapters.spigot) { classifier("all") // otherwise the unshaded jar is used without the shaded NMS implementations }) + implementation(variantOf(libs.adapters.paper) { + classifier("all") // otherwise the unshaded jar is used without the shaded NMS implementations + }) implementation(libs.commodore) @@ -34,6 +37,12 @@ application { } tasks.withType { + + // Prevents Paper 1.20.5+ from remapping Geyser + manifest { + attributes["paperweight-mappings-namespace"] = "mojang" + } + archiveBaseName.set("Geyser-Spigot") dependencies { diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java index 1170ce678..e33de5f9b 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java @@ -46,6 +46,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.Constants; import org.geysermc.geyser.GeyserBootstrap; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.adapters.paper.PaperAdapters; import org.geysermc.geyser.adapters.spigot.SpigotAdapters; import org.geysermc.geyser.api.command.Command; import org.geysermc.geyser.api.extension.Extension; @@ -244,16 +245,27 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { if (Boolean.parseBoolean(System.getProperty("Geyser.UseDirectAdapters", "true"))) { try { - String version = Bukkit.getBukkitVersion().split("-")[0]; - String nmsVersion = "v" + version.replace(".", "_"); - SpigotAdapters.registerWorldAdapter(nmsVersion); + boolean isPaper = false; + try { + String name = Bukkit.getServer().getClass().getPackage().getName(); + String nmsVersion = name.substring(name.lastIndexOf('.') + 1); + SpigotAdapters.registerWorldAdapter(nmsVersion); + geyserLogger.debug("Using spigot NMS adapter for nms version: " + nmsVersion); + } catch (Exception e) { // Likely running on Paper 1.20.5+ + //noinspection deprecation + int protocolVersion = Bukkit.getUnsafe().getProtocolVersion(); + PaperAdapters.registerClosestWorldAdapter(protocolVersion); + isPaper = true; + geyserLogger.debug("Using paper world adapter for protocol version: " + protocolVersion); + } + if (isViaVersion && isViaVersionNeeded()) { - this.geyserWorldManager = new GeyserSpigotLegacyNativeWorldManager(this); + this.geyserWorldManager = new GeyserSpigotLegacyNativeWorldManager(this, isPaper); } else { // No ViaVersion - this.geyserWorldManager = new GeyserSpigotNativeWorldManager(this); + this.geyserWorldManager = new GeyserSpigotNativeWorldManager(this, isPaper); } - geyserLogger.debug("Using NMS adapter: " + this.geyserWorldManager.getClass() + ", " + nmsVersion); + geyserLogger.debug("Using world manager of type: " + this.geyserWorldManager.getClass().getSimpleName()); } catch (Exception e) { if (geyserConfig.isDebugMode()) { geyserLogger.debug("Error while attempting to find NMS adapter. Most likely, this can be safely ignored. :)"); diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotLegacyNativeWorldManager.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotLegacyNativeWorldManager.java index 021db5ec1..5d226e19e 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotLegacyNativeWorldManager.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotLegacyNativeWorldManager.java @@ -46,8 +46,8 @@ public class GeyserSpigotLegacyNativeWorldManager extends GeyserSpigotNativeWorl private final Int2IntMap oldToNewBlockId; - public GeyserSpigotLegacyNativeWorldManager(GeyserSpigotPlugin plugin) { - super(plugin); + public GeyserSpigotLegacyNativeWorldManager(GeyserSpigotPlugin plugin, boolean isPaper) { + super(plugin, isPaper); IntList allBlockStates = adapter.getAllBlockStates(); oldToNewBlockId = new Int2IntOpenHashMap(allBlockStates.size()); ProtocolVersion serverVersion = plugin.getServerProtocolVersion(); diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotNativeWorldManager.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotNativeWorldManager.java index 00212663c..45e84d254 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotNativeWorldManager.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotNativeWorldManager.java @@ -26,20 +26,26 @@ package org.geysermc.geyser.platform.spigot.world.manager; import org.bukkit.Bukkit; +import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; import org.checkerframework.checker.nullness.qual.Nullable; +import org.geysermc.geyser.adapters.WorldAdapter; +import org.geysermc.geyser.adapters.paper.PaperAdapters; import org.geysermc.geyser.adapters.spigot.SpigotAdapters; -import org.geysermc.geyser.adapters.spigot.SpigotWorldAdapter; import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.session.GeyserSession; public class GeyserSpigotNativeWorldManager extends GeyserSpigotWorldManager { - protected final SpigotWorldAdapter adapter; + protected final WorldAdapter adapter; - public GeyserSpigotNativeWorldManager(Plugin plugin) { + public GeyserSpigotNativeWorldManager(Plugin plugin, boolean isPaper) { super(plugin); - adapter = SpigotAdapters.getWorldAdapter(); + if (isPaper) { + adapter = PaperAdapters.getWorldAdapter(); + } else { + adapter = SpigotAdapters.getWorldAdapter(); + } } @Override diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7c16b883b..6a88f0b0f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -25,7 +25,7 @@ jline = "3.21.0" terminalconsoleappender = "1.2.0" folia = "1.19.4-R0.1-SNAPSHOT" viaversion = "4.9.2" -adapters = "1.11-SNAPSHOT" +adapters = "1.12-SNAPSHOT" commodore = "2.2" bungeecord = "a7c6ede" velocity = "3.1.1" @@ -100,6 +100,7 @@ fabric-permissions = { group = "me.lucko", name = "fabric-permissions-api", vers neoforge-minecraft = { group = "net.neoforged", name = "neoforge", version.ref = "neoforge-minecraft" } adapters-spigot = { group = "org.geysermc.geyser.adapters", name = "spigot-all", version.ref = "adapters" } +adapters-paper = { group = "org.geysermc.geyser.adapters", name = "paper-all", version.ref = "adapters" } bungeecord-proxy = { group = "com.github.SpigotMC.BungeeCord", name = "bungeecord-proxy", version.ref = "bungeecord" } checker-qual = { group = "org.checkerframework", name = "checker-qual", version.ref = "checkerframework" } commodore = { group = "me.lucko", name = "commodore", version.ref = "commodore" } From d99f49890100c5aa891d694a3c7619dc92520401 Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Tue, 30 Apr 2024 21:35:21 +0200 Subject: [PATCH 133/272] translate ominous banners --- .../geysermc/geyser/item/type/BannerItem.java | 16 ++++++++-------- .../geyser/session/cache/RegistryCache.java | 9 +++++++-- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index 2f2d09669..2f5d96b5a 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -38,8 +38,6 @@ import org.geysermc.geyser.inventory.item.BannerPattern; import org.geysermc.geyser.inventory.item.DyeColor; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.text.GeyserLocale; -import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.mcprotocollib.protocol.data.game.Holder; import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer; @@ -61,6 +59,9 @@ public class BannerItem extends BlockItem { private static final List> OMINOUS_BANNER_PATTERN; private static final List OMINOUS_BANNER_PATTERN_BLOCK; + // TODO fix - we somehow need to be able to get the sessions banner pattern registry, which we don't have where we need this :/ + private static final int[] ominousBannerPattern = new int[] { 21, 29, 30, 1, 34, 15, 3, 1 }; + static { // Construct what an ominous banner is supposed to look like OMINOUS_BANNER_PATTERN = List.of( @@ -209,16 +210,15 @@ public class BannerItem extends BlockItem { if (bedrockTag.getInt("Type") == 1) { // Ominous banner pattern List patternLayers = new ArrayList<>(); - for (Pair pair : OMINOUS_BANNER_PATTERN) { - patternLayers.add(new BannerPatternLayer(Holder.ofId(pair.left().ordinal()), pair.right().ordinal())); - System.out.println("adding: " + pair.left().getJavaIdentifier() + " " + pair.right().name()); + for (int i = 0; i < ominousBannerPattern.length; i++) { + patternLayers.add(new BannerPatternLayer(Holder.ofId(ominousBannerPattern[i]), OMINOUS_BANNER_PATTERN.get(i).right().ordinal())); } components.put(DataComponentType.BANNER_PATTERNS, patternLayers); components.put(DataComponentType.HIDE_ADDITIONAL_TOOLTIP, Unit.INSTANCE); - components.put(DataComponentType.ITEM_NAME, Component.text( - MinecraftLocale.getLocaleString("block.minecraft.ominous_banner", GeyserLocale.getDefaultLocale()) - ).style(Style.style(TextColor.color(16755200))) + components.put(DataComponentType.ITEM_NAME, Component + .translatable("block.minecraft.ominous_banner") // thank god this works + .style(Style.style(TextColor.color(16755200))) ); } // Bedrock's creative inventory does not support other patterns as of 1.20.5 diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java index 22fc72cf4..4dfc603ee 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java @@ -113,12 +113,17 @@ public final class RegistryCache { REGISTRIES.put("minecraft:banner_pattern", ((registryCache, entries) -> { // Clear each local cache every time a new registry entry is given to us // (e.g. proxy server switches) - registryCache.bannerPatterns = new Int2ObjectBiMap<>(); + registryCache.bannerPatterns = new Int2ObjectBiMap<>(); // Cannot clear it, must re-create :( for (int i = 0; i < entries.size(); i++) { RegistryEntry entry = entries.get(i); // This is what Geyser wants to keep as a value for this registry. T cacheEntry = reader.apply(registryCache.session, entry); - registryCache.bannerPatterns.put(i, (BannerPattern) cacheEntry); + if (cacheEntry != null) { + registryCache.bannerPatterns.put(i, (BannerPattern) cacheEntry); + } else { + // TODO - seems to be possible with viaversion :/ + GeyserImpl.getInstance().getLogger().warning("Was not able to translate entry: "); + } } })); } From 4a0a694eb9c6789c19ee724d55a132c8668993d7 Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Tue, 30 Apr 2024 21:38:25 +0200 Subject: [PATCH 134/272] revert bad diff --- .../src/main/java/org/geysermc/geyser/session/GeyserSession.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 869917b4c..d10a20b3d 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -579,7 +579,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { private final GeyserEntityData entityData; - @Getter private MinecraftProtocol protocol; public GeyserSession(GeyserImpl geyser, BedrockServerSession bedrockServerSession, EventLoop eventLoop) { From 255835438d7392f466b84841d7aedb6cfc3146be Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Tue, 30 Apr 2024 21:59:38 +0200 Subject: [PATCH 135/272] viaversion 4.10.0 compat, indicate 1.20.6 support on modrinth --- .../world/manager/GeyserSpigotLegacyNativeWorldManager.java | 2 +- .../src/main/kotlin/geyser.modded-conventions.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotLegacyNativeWorldManager.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotLegacyNativeWorldManager.java index 5d226e19e..fe2dda053 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotLegacyNativeWorldManager.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotLegacyNativeWorldManager.java @@ -58,7 +58,7 @@ public class GeyserSpigotLegacyNativeWorldManager extends GeyserSpigotNativeWorl int newBlockId = oldBlockId; // protocolList should *not* be null; we checked for that before initializing this class for (int i = protocolList.size() - 1; i >= 0; i--) { - MappingData mappingData = protocolList.get(i).getProtocol().getMappingData(); + MappingData mappingData = protocolList.get(i).protocol().getMappingData(); if (mappingData != null) { newBlockId = mappingData.getNewBlockStateId(newBlockId); } diff --git a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts index afea247a7..b75e9c5be 100644 --- a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts @@ -134,6 +134,6 @@ modrinth { syncBodyFrom.set(rootProject.file("README.md").readText()) uploadFile.set(tasks.getByPath("remapModrinthJar")) - gameVersions.addAll("1.20.5") + gameVersions.addAll("1.20.5", "1.20.6") failSilently.set(true) } \ No newline at end of file From aff7d2cf35d5e8799b59fca67d781b31e8e19a96 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Tue, 30 Apr 2024 18:05:46 -0400 Subject: [PATCH 136/272] Fix potential NPE --- .../main/java/org/geysermc/geyser/inventory/AnvilContainer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java index 88838d068..45a062468 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/AnvilContainer.java @@ -85,7 +85,7 @@ public class AnvilContainer extends Container { session.sendDownstreamGamePacket(renameItemPacket); } else { // Restore formatting for item since we're not renaming - correctRename = MessageTranslator.convertMessage(originalName, session.locale()); + correctRename = originalName != null ? MessageTranslator.convertMessage(originalName, session.locale()) : ""; // Java Edition sends the original custom name when not renaming, // if there isn't a custom name an empty string is sent ServerboundRenameItemPacket renameItemPacket = new ServerboundRenameItemPacket(plainOriginalName); From 59a2c0dc02abacd00fe3a72788cc9317c891557e Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 30 Apr 2024 18:35:52 -0400 Subject: [PATCH 137/272] Use item tags for all animal loved food --- .../geyser/entity/EntityDefinitions.java | 2 +- .../entity/type/living/TadpoleEntity.java | 4 +-- .../type/living/animal/AnimalEntity.java | 21 ++++++++-------- .../type/living/animal/ArmadilloEntity.java | 8 ++++++ .../type/living/animal/AxolotlEntity.java | 7 +++--- .../entity/type/living/animal/BeeEntity.java | 7 +++--- .../type/living/animal/ChickenEntity.java | 11 ++++---- .../entity/type/living/animal/CowEntity.java | 8 ++++++ .../entity/type/living/animal/FoxEntity.java | 7 +++--- .../entity/type/living/animal/FrogEntity.java | 9 ++++--- .../entity/type/living/animal/GoatEntity.java | 8 ++++++ .../type/living/animal/HoglinEntity.java | 9 ++++--- .../type/living/animal/MooshroomEntity.java | 2 +- .../type/living/animal/OcelotEntity.java | 9 ++++--- .../type/living/animal/PandaEntity.java | 8 +++--- .../entity/type/living/animal/PigEntity.java | 9 ++++--- .../type/living/animal/PolarBearEntity.java | 8 +++--- .../type/living/animal/RabbitEntity.java | 9 ++++--- .../type/living/animal/SheepEntity.java | 8 ++++++ .../type/living/animal/SnifferEntity.java | 7 +++--- .../type/living/animal/StriderEntity.java | 9 ++++--- .../type/living/animal/TurtleEntity.java | 9 ++++--- .../animal/horse/AbstractHorseEntity.java | 15 ++++------- .../type/living/animal/horse/CamelEntity.java | 8 +++--- .../type/living/animal/horse/LlamaEntity.java | 8 +++--- .../living/animal/tameable/CatEntity.java | 8 +++--- .../living/animal/tameable/ParrotEntity.java | 11 +++++--- .../animal/tameable/TameableEntity.java | 2 +- .../living/animal/tameable/WolfEntity.java | 7 +++--- .../geyser/item/type/FireworkRocketItem.java | 2 +- .../geyser/session/cache/tags/ItemTag.java | 25 +++++++++++++++++-- .../translator/item/ItemTranslator.java | 20 +++++++-------- 32 files changed, 174 insertions(+), 111 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index ed2cda9b9..6cd5f3fc2 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -964,7 +964,7 @@ public final class EntityDefinitions { .build(); } - EntityDefinition tameableEntityBase = EntityDefinition.inherited(TameableEntity::new, ageableEntityBase) + EntityDefinition tameableEntityBase = EntityDefinition.inherited(null, ageableEntityBase) // No factory, is abstract .addTranslator(MetadataType.BYTE, TameableEntity::setTameableFlags) .addTranslator(MetadataType.OPTIONAL_UUID, TameableEntity::setOwner) .build(); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/TadpoleEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/TadpoleEntity.java index 4fdaa1059..68cf763c3 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/TadpoleEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/TadpoleEntity.java @@ -29,8 +29,8 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; -import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; @@ -62,6 +62,6 @@ public class TadpoleEntity extends AbstractFishEntity { } private boolean isFood(GeyserItemStack itemStack) { - return itemStack.asItem() == Items.SLIME_BALL; + return session.getTagCache().is(ItemTag.FROG_FOOD, itemStack); } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AnimalEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AnimalEntity.java index bf23a5418..2e627b461 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AnimalEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AnimalEntity.java @@ -26,38 +26,39 @@ package org.geysermc.geyser.entity.type.living.animal; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.living.AgeableEntity; import org.geysermc.geyser.inventory.GeyserItemStack; -import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; -public class AnimalEntity extends AgeableEntity { +public abstract class AnimalEntity extends AgeableEntity { public AnimalEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); } - public final boolean canEat(GeyserItemStack itemStack) { - return canEat(itemStack.asItem()); + protected final boolean canEat(GeyserItemStack itemStack) { + ItemTag tag = getFoodTag(); + if (tag == null) { + return false; + } + return session.getTagCache().is(tag, itemStack); } /** - * @return true if this is a valid item to breed with for this animal. + * @return the tag associated with this animal for eating food. Null for nothing or different behavior. */ - public boolean canEat(Item item) { - // This is what it defaults to. OK. - return item == Items.WHEAT; - } + protected abstract @Nullable ItemTag getFoodTag(); @NonNull @Override diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java index 51fe09383..968520bb6 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ArmadilloEntity.java @@ -25,9 +25,11 @@ package org.geysermc.geyser.entity.type.living.animal; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.ArmadilloState; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; @@ -70,4 +72,10 @@ public class ArmadilloEntity extends AnimalEntity { }, 250, TimeUnit.MILLISECONDS); } } + + @Override + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.ARMADILLO_FOOD; + } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java index 37cd5f1e6..a87b1dd5e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java @@ -26,12 +26,12 @@ package org.geysermc.geyser.entity.type.living.animal; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.EntityUtils; @@ -61,8 +61,9 @@ public class AxolotlEntity extends AnimalEntity { } @Override - public boolean canEat(Item item) { - return session.getTagCache().is(ItemTag.AXOLOTL_FOOD, item); + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.AXOLOTL_FOOD; } @Override diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java index 28ebad473..4fcf0e178 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/BeeEntity.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.entity.type.living.animal; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; @@ -68,7 +68,8 @@ public class BeeEntity extends AnimalEntity { } @Override - public boolean canEat(Item item) { - return session.getTagCache().is(ItemTag.FLOWERS, item); + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.BEE_FOOD; } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ChickenEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ChickenEntity.java index 164fb1b6c..075a49923 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ChickenEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/ChickenEntity.java @@ -25,24 +25,23 @@ package org.geysermc.geyser.entity.type.living.animal; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; -import java.util.Set; import java.util.UUID; public class ChickenEntity extends AnimalEntity { - private static final Set VALID_FOOD = Set.of(Items.WHEAT_SEEDS, Items.MELON_SEEDS, Items.PUMPKIN_SEEDS, Items.BEETROOT_SEEDS); public ChickenEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); } @Override - public boolean canEat(Item item) { - return VALID_FOOD.contains(item); + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.CHICKEN_FOOD; } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/CowEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/CowEntity.java index d542cb46f..64e7de193 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/CowEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/CowEntity.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.entity.type.living.animal; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -33,6 +34,7 @@ import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; @@ -64,4 +66,10 @@ public class CowEntity extends AnimalEntity { session.playSoundEvent(SoundEvent.MILK, position); return InteractionResult.SUCCESS; } + + @Override + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.COW_FOOD; + } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FoxEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FoxEntity.java index 18e346b98..e20031baa 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FoxEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FoxEntity.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.entity.type.living.animal; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; @@ -56,7 +56,8 @@ public class FoxEntity extends AnimalEntity { } @Override - public boolean canEat(Item item) { - return session.getTagCache().is(ItemTag.FOX_FOOD, item); + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.FOX_FOOD; } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FrogEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FrogEntity.java index ed21a9609..120bfcdd4 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FrogEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/FrogEntity.java @@ -25,14 +25,14 @@ package org.geysermc.geyser.entity.type.living.animal; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.Entity; -import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; @@ -76,7 +76,8 @@ public class FrogEntity extends AnimalEntity { } @Override - public boolean canEat(Item item) { - return item == Items.SLIME_BALL; + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.FROG_FOOD; } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/GoatEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/GoatEntity.java index 7cbbd4433..4e919b81c 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/GoatEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/GoatEntity.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.entity.type.living.animal; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; @@ -34,6 +35,7 @@ import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; @@ -94,4 +96,10 @@ public class GoatEntity extends AnimalEntity { private void setHornCount() { dirtyMetadata.put(EntityDataTypes.GOAT_HORN_COUNT, (hasLeftHorn ? 1 : 0) + (hasRightHorn ? 1 : 0)); } + + @Override + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.GOAT_FOOD; + } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java index 29d1839c7..46cafad02 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.entity.type.living.animal; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import java.util.UUID; @@ -54,8 +54,9 @@ public class HoglinEntity extends AnimalEntity { } @Override - public boolean canEat(Item item) { - return item == Items.CRIMSON_FUNGUS; + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.HOGLIN_FOOD; } @Override diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/MooshroomEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/MooshroomEntity.java index 55c3c406f..2c9040b53 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/MooshroomEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/MooshroomEntity.java @@ -40,7 +40,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; -public class MooshroomEntity extends AnimalEntity { +public class MooshroomEntity extends CowEntity { private boolean isBrown = false; public MooshroomEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/OcelotEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/OcelotEntity.java index 8a3dd6c72..9d6d33227 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/OcelotEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/OcelotEntity.java @@ -26,13 +26,13 @@ package org.geysermc.geyser.entity.type.living.animal; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; -import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; @@ -46,8 +46,9 @@ public class OcelotEntity extends AnimalEntity { } @Override - public boolean canEat(Item item) { - return item == Items.COD || item == Items.SALMON; + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.OCELOT_FOOD; } @NonNull diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java index df72fdc63..595e79e32 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java @@ -34,9 +34,8 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; -import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; @@ -89,8 +88,9 @@ public class PandaEntity extends AnimalEntity { } @Override - public boolean canEat(Item item) { - return item == Items.BAMBOO; + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.PANDA_FOOD; } @NonNull diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PigEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PigEntity.java index 4dbf3064a..446e3e109 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PigEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PigEntity.java @@ -26,13 +26,13 @@ package org.geysermc.geyser.entity.type.living.animal; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; -import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.EntityUtils; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; @@ -47,8 +47,9 @@ public class PigEntity extends AnimalEntity { } @Override - public boolean canEat(Item item) { - return item == Items.CARROT || item == Items.POTATO || item == Items.BEETROOT; + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.PIG_FOOD; } @NonNull diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PolarBearEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PolarBearEntity.java index 1d7777cdb..0e83615f7 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PolarBearEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PolarBearEntity.java @@ -25,10 +25,11 @@ package org.geysermc.geyser.entity.type.living.animal; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import java.util.UUID; @@ -39,7 +40,8 @@ public class PolarBearEntity extends AnimalEntity { } @Override - public boolean canEat(Item item) { - return false; + @Nullable + protected ItemTag getFoodTag() { + return null; } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/RabbitEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/RabbitEntity.java index 09db7257b..0a108be73 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/RabbitEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/RabbitEntity.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.entity.type.living.animal; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import java.util.UUID; @@ -67,7 +67,8 @@ public class RabbitEntity extends AnimalEntity { } @Override - public boolean canEat(Item item) { - return item == Items.DANDELION || item == Items.CARROT || item == Items.GOLDEN_CARROT; + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.RABBIT_FOOD; } } \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SheepEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SheepEntity.java index e87186bf6..155ddf00c 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SheepEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SheepEntity.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.entity.type.living.animal; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; @@ -34,6 +35,7 @@ import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.DyeItem; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; @@ -55,6 +57,12 @@ public class SheepEntity extends AnimalEntity { dirtyMetadata.put(EntityDataTypes.COLOR, (byte) color); } + @Override + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.SHEEP_FOOD; + } + @NonNull @Override protected InteractiveTag testMobInteraction(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) { diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SnifferEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SnifferEntity.java index 35b2b4183..11fee5bbf 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SnifferEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/SnifferEntity.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.entity.type.living.animal; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; @@ -34,7 +35,6 @@ import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.type.Tickable; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; @@ -72,8 +72,9 @@ public class SnifferEntity extends AnimalEntity implements Tickable { } @Override - public boolean canEat(Item item) { - return session.getTagCache().is(ItemTag.SNIFFER_FOOD, item); + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.SNIFFER_FOOD; } public void setSnifferState(ObjectEntityMetadata entityMetadata) { diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/StriderEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/StriderEntity.java index dcdd40199..0291f75d9 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/StriderEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/StriderEntity.java @@ -26,14 +26,14 @@ package org.geysermc.geyser.entity.type.living.animal; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.inventory.GeyserItemStack; -import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.EntityUtils; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; @@ -94,8 +94,9 @@ public class StriderEntity extends AnimalEntity { } @Override - public boolean canEat(Item item) { - return item == Items.WARPED_FUNGUS; + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.STRIDER_FOOD; } @NonNull diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TurtleEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TurtleEntity.java index 1d0aec75f..b3c1128e3 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TurtleEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TurtleEntity.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.entity.type.living.animal; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import java.util.UUID; @@ -50,8 +50,9 @@ public class TurtleEntity extends AnimalEntity { } @Override - public boolean canEat(Item item) { - return item == Items.SEAGRASS; + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.TURTLE_FOOD; } @Override diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/AbstractHorseEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/AbstractHorseEntity.java index 76416c146..ddc212053 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/AbstractHorseEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/AbstractHorseEntity.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.entity.type.living.animal.horse; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; @@ -38,23 +39,16 @@ import org.geysermc.geyser.entity.attribute.GeyserAttributeType; import org.geysermc.geyser.entity.type.living.animal.AnimalEntity; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; -import java.util.Set; import java.util.UUID; public class AbstractHorseEntity extends AnimalEntity { - /** - * A list of all foods a horse/donkey can eat on Java Edition. - * Used to display interactive tag if needed. - */ - private static final Set DONKEY_AND_HORSE_FOODS = Set.of(Items.GOLDEN_APPLE, Items.ENCHANTED_GOLDEN_APPLE, - Items.GOLDEN_CARROT, Items.SUGAR, Items.APPLE, Items.WHEAT, Items.HAY_BLOCK); public AbstractHorseEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); @@ -124,8 +118,9 @@ public class AbstractHorseEntity extends AnimalEntity { } @Override - public boolean canEat(Item item) { - return DONKEY_AND_HORSE_FOODS.contains(item); + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.HORSE_FOOD; } @NonNull diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/CamelEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/CamelEntity.java index 00144617a..ee3b2be70 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/CamelEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/CamelEntity.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.entity.type.living.animal.horse; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; @@ -32,9 +33,8 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; @@ -90,8 +90,8 @@ public class CamelEntity extends AbstractHorseEntity { } @Override - public boolean canEat(Item item) { - return item == Items.CACTUS; + protected @Nullable ItemTag getFoodTag() { + return ItemTag.CAMEL_FOOD; } @Override diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java index 346b6da9b..76939ceb9 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/LlamaEntity.java @@ -26,12 +26,12 @@ package org.geysermc.geyser.entity.type.living.animal.horse; import lombok.Getter; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.MathUtils; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; @@ -56,7 +56,7 @@ public class LlamaEntity extends ChestedHorseEntity { } @Override - public boolean canEat(Item item) { - return item == Items.WHEAT || item == Items.HAY_BLOCK; + protected @Nullable ItemTag getFoodTag() { + return ItemTag.LLAMA_FOOD; } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/CatEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/CatEntity.java index fc5978c2b..bf1555e9d 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/CatEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/CatEntity.java @@ -26,14 +26,14 @@ package org.geysermc.geyser.entity.type.living.animal.tameable; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; -import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; @@ -109,8 +109,8 @@ public class CatEntity extends TameableEntity { } @Override - public boolean canEat(Item item) { - return item == Items.COD || item == Items.SALMON; + protected @Nullable ItemTag getFoodTag() { + return ItemTag.CAT_FOOD; } @NonNull diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/ParrotEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/ParrotEntity.java index 18feec979..8baba6f00 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/ParrotEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/ParrotEntity.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.entity.type.living.animal.tameable; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; @@ -33,6 +34,7 @@ import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; @@ -49,16 +51,17 @@ public class ParrotEntity extends TameableEntity { } @Override - public boolean canEat(Item item) { - return false; + @Nullable + protected ItemTag getFoodTag() { + return null; } private boolean isTameFood(Item item) { - return TAMING_FOOD.contains(item); + return session.getTagCache().is(ItemTag.PARROT_FOOD, item); } private boolean isPoisonousFood(Item item) { - return item == Items.COOKIE; + return session.getTagCache().is(ItemTag.PARROT_POISONOUS_FOOD, item); } @NonNull diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/TameableEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/TameableEntity.java index 4a1cd70e9..e16823d37 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/TameableEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/TameableEntity.java @@ -39,7 +39,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEn import java.util.Optional; import java.util.UUID; -public class TameableEntity extends AnimalEntity { +public abstract class TameableEntity extends AnimalEntity { /** * Used in the interactive tag manager to track if the session player owns this entity */ diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java index 833d0e175..ceb29695a 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java @@ -38,6 +38,7 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.DyeItem; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; import org.geysermc.geyser.util.ItemUtils; @@ -120,9 +121,9 @@ public class WolfEntity extends TameableEntity { } @Override - public boolean canEat(Item item) { - // Cannot be a baby to eat these foods - return WOLF_FOODS.contains(item) && !isBaby(); + @Nullable + protected ItemTag getFoodTag() { + return ItemTag.WOLF_FOOD; } @Override diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java index bba13e753..c70467b4c 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java @@ -115,7 +115,7 @@ public class FireworkRocketItem extends Item { newExplosionData.putByteArray("FireworkFade", colors); newExplosionData.putBoolean("FireworkTrail", explosion.isHasTrail()); - newExplosionData.putBoolean("FireworkFlicker", explosion.isHasTwinkle()); // TODO verify + newExplosionData.putBoolean("FireworkFlicker", explosion.isHasTwinkle()); return newExplosionData.build(); } diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/tags/ItemTag.java b/core/src/main/java/org/geysermc/geyser/session/cache/tags/ItemTag.java index df9a423ed..f064d0763 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/tags/ItemTag.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/tags/ItemTag.java @@ -31,11 +31,32 @@ public enum ItemTag { AXOLOTL_FOOD("axolotl_food"), CREEPER_IGNITERS("creeper_igniters"), FISHES("fishes"), - FLOWERS("flowers"), FOX_FOOD("fox_food"), PIGLIN_LOVED("piglin_loved"), SMALL_FLOWERS("small_flowers"), - SNIFFER_FOOD("sniffer_food"); + SNIFFER_FOOD("sniffer_food"), + PIGLIN_FOOD("piglin_food"), + COW_FOOD("cow_food"), + GOAT_FOOD("goat_food"), + SHEEP_FOOD("sheep_food"), + WOLF_FOOD("wolf_food"), + CAT_FOOD("cat_food"), + HORSE_FOOD("horse_food"), + CAMEL_FOOD("camel_food"), + ARMADILLO_FOOD("armadillo_food"), + BEE_FOOD("bee_food"), + CHICKEN_FOOD("chicken_food"), + FROG_FOOD("frog_food"), + HOGLIN_FOOD("hoglin_food"), + LLAMA_FOOD("llama_food"), + OCELOT_FOOD("ocelot_food"), + PANDA_FOOD("panda_food"), + PIG_FOOD("pig_food"), + RABBIT_FOOD("rabbit_food"), + STRIDER_FOOD("strider_food"), + TURTLE_FOOD("turtle_food"), + PARROT_FOOD("parrot_food"), + PARROT_POISONOUS_FOOD("parrot_poisonous_food"); ItemTag(String identifier) { register(identifier, this); diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index 11e092b57..49ee498b9 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -249,19 +249,17 @@ public final class ItemTranslator { String name = modifier.getName().replace("minecraft:", ""); // the namespace does not need to be present, but if it is, the java client ignores it as of pre-1.20.5 - String operationTotal; ModifierOperation operation = modifier.getOperation(); - if (operation == ModifierOperation.ADD) { - if (name.equals("generic.knockback_resistance")) { - amount *= 10; + String operationTotal = switch (operation) { + case ADD -> { + if (name.equals("generic.knockback_resistance")) { + amount *= 10; + } + yield ATTRIBUTE_FORMAT.format(amount); } - operationTotal = ATTRIBUTE_FORMAT.format(amount); - } else if (operation == ModifierOperation.ADD_MULTIPLIED_BASE || operation == ModifierOperation.ADD_MULTIPLIED_TOTAL) { - operationTotal = ATTRIBUTE_FORMAT.format(amount * 100) + "%"; - } else { - GeyserImpl.getInstance().getLogger().warning("Unhandled ModifierOperation while adding item attributes: " + operation); - return null; - } + case ADD_MULTIPLIED_BASE, ADD_MULTIPLIED_TOTAL -> + ATTRIBUTE_FORMAT.format(amount * 100) + "%"; + }; if (amount > 0) { operationTotal = "+" + operationTotal; } From abb1d7d9e9fb1de2c5959fc679cb5afbda7b0978 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 30 Apr 2024 18:50:41 -0400 Subject: [PATCH 138/272] Indicate Java 1.20.6 support --- README.md | 2 +- .../src/main/java/org/geysermc/geyser/network/GameProtocol.java | 2 +- gradle/libs.versions.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 314876d60..2fdc93fa1 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here! -### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.80 and Minecraft Java 1.20.5 +### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.80 and Minecraft Java 1.20.5/1.20.6 ## Setting Up Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser. diff --git a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java index cf80e8c6e..fdaecbb69 100644 --- a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java +++ b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java @@ -124,7 +124,7 @@ public final class GameProtocol { * @return the supported Minecraft: Java Edition version names */ public static List getJavaVersions() { - return List.of(DEFAULT_JAVA_CODEC.getMinecraftVersion()); + return List.of("1.20.5", DEFAULT_JAVA_CODEC.getMinecraftVersion()); } /** diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9e5a0a53f..e975ba0c8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "bc8526b" # Revert from jitpack after release +mcprotocollib = "209e79f8" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From 1e8d6b23cf5f5058f6bf11c362346e0f48871a20 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Wed, 1 May 2024 15:35:30 -0400 Subject: [PATCH 139/272] Different registry implementation; fix banner blocks with ViaVersion --- .../living/animal/tameable/WolfEntity.java | 2 +- .../geysermc/geyser/item/type/ArmorItem.java | 4 +- .../geysermc/geyser/item/type/BannerItem.java | 52 +++++++++------- .../geyser/session/cache/RegistryCache.java | 52 +++++----------- .../session/cache/registry/JavaRegistry.java | 56 ++++++++++++++++++ .../cache/registry/SimpleJavaRegistry.java | 59 +++++++++++++++++++ .../translator/text/MessageTranslator.java | 2 +- .../org/geysermc/geyser/util/ChunkUtils.java | 2 +- 8 files changed, 166 insertions(+), 63 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/session/cache/registry/JavaRegistry.java create mode 100644 core/src/main/java/org/geysermc/geyser/session/cache/registry/SimpleJavaRegistry.java diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java index ceb29695a..4573f0e7a 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java @@ -113,7 +113,7 @@ public class WolfEntity extends TameableEntity { // 1.20.5+ public void setWolfVariant(IntEntityMetadata entityMetadata) { - WolfVariant wolfVariant = session.getRegistryCache().wolfVariants().get(entityMetadata.getPrimitiveValue()); + WolfVariant wolfVariant = session.getRegistryCache().wolfVariants().byId(entityMetadata.getPrimitiveValue()); if (wolfVariant == null) { wolfVariant = WolfVariant.PALE; } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java index 76f951c66..fc0dd3ba4 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java @@ -56,8 +56,8 @@ public class ArmorItem extends Item { return; } - TrimMaterial material = session.getRegistryCache().trimMaterials().get(trim.material().id()); - TrimPattern pattern = session.getRegistryCache().trimPatterns().get(trim.pattern().id()); + TrimMaterial material = session.getRegistryCache().trimMaterials().byId(trim.material().id()); + TrimPattern pattern = session.getRegistryCache().trimPatterns().byId(trim.pattern().id()); NbtMapBuilder trimBuilder = NbtMap.builder(); // bedrock has an uppercase first letter key, and the value is not namespaced diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index 2f5d96b5a..6c2678db9 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -33,13 +33,14 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtList; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtType; -import org.cloudburstmc.protocol.common.util.Int2ObjectBiMap; import org.geysermc.geyser.inventory.item.BannerPattern; import org.geysermc.geyser.inventory.item.DyeColor; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.registry.JavaRegistry; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.mcprotocollib.protocol.data.game.Holder; +import org.geysermc.mcprotocollib.protocol.data.game.Identifier; import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; @@ -57,7 +58,6 @@ public class BannerItem extends BlockItem { * the correct ominous banner pattern if Bedrock pulls the item from creative. */ private static final List> OMINOUS_BANNER_PATTERN; - private static final List OMINOUS_BANNER_PATTERN_BLOCK; // TODO fix - we somehow need to be able to get the sessions banner pattern registry, which we don't have where we need this :/ private static final int[] ominousBannerPattern = new int[] { 21, 29, 30, 1, 34, 15, 3, 1 }; @@ -74,11 +74,6 @@ public class BannerItem extends BlockItem { Pair.of(BannerPattern.CIRCLE, DyeColor.LIGHT_GRAY), Pair.of(BannerPattern.BORDER, DyeColor.BLACK) ); - - OMINOUS_BANNER_PATTERN_BLOCK = new ArrayList<>(); - for (Pair pair : OMINOUS_BANNER_PATTERN) { - OMINOUS_BANNER_PATTERN_BLOCK.add(getJavaBannerPatternTag(pair.left(), pair.right())); - } } public static boolean isOminous(GeyserSession session, List patternLayers) { @@ -92,7 +87,7 @@ public class BannerItem extends BlockItem { !patternLayer.getPattern().isId()) { return false; } - BannerPattern bannerPattern = session.getRegistryCache().bannerPatterns().get(patternLayer.getPattern().id()); + BannerPattern bannerPattern = session.getRegistryCache().bannerPatterns().byId(patternLayer.getPattern().id()); if (bannerPattern != pair.left()) { return false; } @@ -101,7 +96,25 @@ public class BannerItem extends BlockItem { } public static boolean isOminous(List blockEntityPatterns) { - return OMINOUS_BANNER_PATTERN_BLOCK.equals(blockEntityPatterns); + // Cannot do a simple NBT equals check here because the IDs may not be full resource locations + // ViaVersion's fault, 1.20.4 -> 1.20.5, but it works on Java so we need to support it. + if (OMINOUS_BANNER_PATTERN.size() != blockEntityPatterns.size()) { + return false; + } + for (int i = 0; i < OMINOUS_BANNER_PATTERN.size(); i++) { + NbtMap patternLayer = blockEntityPatterns.get(i); + Pair pair = OMINOUS_BANNER_PATTERN.get(i); + DyeColor color = DyeColor.getByJavaIdentifier(patternLayer.getString("color")); + if (color != pair.right()) { + return false; + } + String id = Identifier.formalize(patternLayer.getString("pattern")); // Ouch + BannerPattern bannerPattern = BannerPattern.getByJavaIdentifier(id); + if (bannerPattern != pair.left()) { + return false; + } + } + return true; } /** @@ -133,7 +146,7 @@ public class BannerItem extends BlockItem { List patternList = new ArrayList<>(patterns.size()); for (BannerPatternLayer patternLayer : patterns) { patternLayer.getPattern().ifId(holder -> { - BannerPattern bannerPattern = session.getRegistryCache().bannerPatterns().get(holder.id()); + BannerPattern bannerPattern = session.getRegistryCache().bannerPatterns().byId(holder.id()); if (bannerPattern != null) { NbtMap tag = NbtMap.builder() .putString("Pattern", bannerPattern.getBedrockIdentifier()) @@ -154,7 +167,8 @@ public class BannerItem extends BlockItem { * @return The Bedrock edition format pattern nbt */ private static NbtMap getBedrockBannerPattern(NbtMap pattern) { - BannerPattern bannerPattern = BannerPattern.getByJavaIdentifier(pattern.getString("pattern")); + // ViaVersion 1.20.4 -> 1.20.5 can send without the namespace + BannerPattern bannerPattern = BannerPattern.getByJavaIdentifier(Identifier.formalize(pattern.getString("pattern"))); DyeColor dyeColor = DyeColor.getByJavaIdentifier(pattern.getString("color")); if (bannerPattern == null || dyeColor == null) { return null; @@ -166,13 +180,6 @@ public class BannerItem extends BlockItem { .build(); } - public static NbtMap getJavaBannerPatternTag(BannerPattern bannerPattern, DyeColor dyeColor) { - return NbtMap.builder() - .putString("pattern", bannerPattern.getJavaIdentifier()) - .putString("color", dyeColor.getJavaIdentifier()) - .build(); - } - /** * Convert the Bedrock edition banner pattern nbt to Java edition * @@ -180,11 +187,14 @@ public class BannerItem extends BlockItem { * @return The Java edition format pattern layer */ public static BannerPatternLayer getJavaBannerPattern(GeyserSession session, NbtMap pattern) { - Int2ObjectBiMap registry = session.getRegistryCache().bannerPatterns(); + JavaRegistry registry = session.getRegistryCache().bannerPatterns(); BannerPattern bannerPattern = BannerPattern.getByBedrockIdentifier(pattern.getString("Pattern")); DyeColor dyeColor = DyeColor.getById(15 - pattern.getInt("Color")); - if (bannerPattern != null && dyeColor != null && registry.containsValue(bannerPattern)) { - return new BannerPatternLayer(Holder.ofId(registry.get(bannerPattern)), dyeColor.ordinal()); + if (bannerPattern != null && dyeColor != null) { + int id = registry.byValue(bannerPattern); + if (id != -1) { + return new BannerPatternLayer(Holder.ofId(id), dyeColor.ordinal()); + } } return null; } diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java index 4dfc603ee..9581df253 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java @@ -27,25 +27,25 @@ package org.geysermc.geyser.session.cache; import it.unimi.dsi.fastutil.ints.Int2IntMap; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import lombok.AccessLevel; import lombok.Getter; import lombok.experimental.Accessors; import org.cloudburstmc.protocol.bedrock.data.TrimMaterial; import org.cloudburstmc.protocol.bedrock.data.TrimPattern; -import org.cloudburstmc.protocol.common.util.Int2ObjectBiMap; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.entity.type.living.animal.tameable.WolfEntity; import org.geysermc.geyser.inventory.item.BannerPattern; import org.geysermc.geyser.inventory.recipe.TrimRecipe; import org.geysermc.geyser.level.JavaDimension; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.registry.JavaRegistry; +import org.geysermc.geyser.session.cache.registry.SimpleJavaRegistry; import org.geysermc.geyser.text.TextDecoration; import org.geysermc.geyser.translator.level.BiomeTranslator; import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; import org.geysermc.mcprotocollib.protocol.packet.configuration.clientbound.ClientboundRegistryDataPacket; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -71,7 +71,7 @@ public final class RegistryCache { register("trim_material", cache -> cache.trimMaterials, TrimRecipe::readTrimMaterial); register("trim_pattern", cache -> cache.trimPatterns, TrimRecipe::readTrimPattern); register("worldgen/biome", (cache, array) -> cache.biomeTranslations = array, BiomeTranslator::loadServerBiome); - registerBannerRegistry(($, entry) -> BannerPattern.getByJavaIdentifier(entry.getId())); + register("banner_pattern", cache -> cache.bannerPatterns, ($, entry) -> BannerPattern.getByJavaIdentifier(entry.getId())); register("wolf_variant", cache -> cache.wolfVariants, ($, entry) -> WolfEntity.WolfVariant.getByJavaIdentifier(entry.getId())); } @@ -82,16 +82,16 @@ public final class RegistryCache { * Java -> Bedrock biome network IDs. */ private int[] biomeTranslations; - private final Int2ObjectMap chatTypes = new Int2ObjectOpenHashMap<>(7); + private final JavaRegistry chatTypes = new SimpleJavaRegistry<>(); /** * All dimensions that the client could possibly connect to. */ - private final Int2ObjectMap dimensions = new Int2ObjectOpenHashMap<>(4); - private final Int2ObjectMap trimMaterials = new Int2ObjectOpenHashMap<>(); - private final Int2ObjectMap trimPatterns = new Int2ObjectOpenHashMap<>(); + private final JavaRegistry dimensions = new SimpleJavaRegistry<>(); + private final JavaRegistry trimMaterials = new SimpleJavaRegistry<>(); + private final JavaRegistry trimPatterns = new SimpleJavaRegistry<>(); - private Int2ObjectBiMap bannerPatterns = new Int2ObjectBiMap<>(); - private final Int2ObjectMap wolfVariants = new Int2ObjectOpenHashMap<>(); + private final JavaRegistry bannerPatterns = new SimpleJavaRegistry<>(); + private final JavaRegistry wolfVariants = new SimpleJavaRegistry<>(); public RegistryCache(GeyserSession session) { this.session = session; @@ -109,47 +109,25 @@ public final class RegistryCache { } } - private static void registerBannerRegistry(BiFunction reader) { - REGISTRIES.put("minecraft:banner_pattern", ((registryCache, entries) -> { - // Clear each local cache every time a new registry entry is given to us - // (e.g. proxy server switches) - registryCache.bannerPatterns = new Int2ObjectBiMap<>(); // Cannot clear it, must re-create :( - for (int i = 0; i < entries.size(); i++) { - RegistryEntry entry = entries.get(i); - // This is what Geyser wants to keep as a value for this registry. - T cacheEntry = reader.apply(registryCache.session, entry); - if (cacheEntry != null) { - registryCache.bannerPatterns.put(i, (BannerPattern) cacheEntry); - } else { - // TODO - seems to be possible with viaversion :/ - GeyserImpl.getInstance().getLogger().warning("Was not able to translate entry: "); - } - } - })); - } - /** * @param registry the Java registry resource location, without the "minecraft:" prefix. * @param localCacheFunction which local field in RegistryCache are we caching entries for this registry? * @param reader converts the RegistryEntry NBT into a class file * @param the class that represents these entries. */ - private static void register(String registry, Function> localCacheFunction, BiFunction reader) { + private static void register(String registry, Function> localCacheFunction, BiFunction reader) { REGISTRIES.put("minecraft:" + registry, (registryCache, entries) -> { - Int2ObjectMap localCache = localCacheFunction.apply(registryCache); + JavaRegistry localCache = localCacheFunction.apply(registryCache); // Clear each local cache every time a new registry entry is given to us // (e.g. proxy server switches) - localCache.clear(); + List builder = new ArrayList<>(entries.size()); for (int i = 0; i < entries.size(); i++) { RegistryEntry entry = entries.get(i); // This is what Geyser wants to keep as a value for this registry. T cacheEntry = reader.apply(registryCache.session, entry); - localCache.put(i, cacheEntry); - } - // Trim registry down to needed size - if (localCache instanceof Int2ObjectOpenHashMap hashMap) { - hashMap.trim(); + builder.add(i, cacheEntry); } + localCache.reset(builder); }); } diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/registry/JavaRegistry.java b/core/src/main/java/org/geysermc/geyser/session/cache/registry/JavaRegistry.java new file mode 100644 index 000000000..d7c7782ea --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/session/cache/registry/JavaRegistry.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.session.cache.registry; + +import org.checkerframework.checker.index.qual.NonNegative; + +import java.util.List; + +/** + * A wrapper for a list, holding Java registry values. + */ +public interface JavaRegistry { + + /** + * Looks up a registry entry by its ID. The object can be null, or not present. + */ + T byId(@NonNegative int id); + + /** + * Reverse looks-up an object to return its network ID, or -1. + */ + int byValue(T value); + + /** + * Resets the objects by these IDs. + */ + void reset(List values); + + /** + * All values of this registry, as a list. + */ + List values(); +} diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/registry/SimpleJavaRegistry.java b/core/src/main/java/org/geysermc/geyser/session/cache/registry/SimpleJavaRegistry.java new file mode 100644 index 000000000..633e5fbd1 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/session/cache/registry/SimpleJavaRegistry.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.session.cache.registry; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.checkerframework.checker.index.qual.NonNegative; + +import java.util.List; + +public class SimpleJavaRegistry implements JavaRegistry { + protected final ObjectArrayList values = new ObjectArrayList<>(); + + @Override + public T byId(@NonNegative int id) { + if (id < 0 || id >= this.values.size()) { + return null; + } + return this.values.get(id); + } + + @Override + public int byValue(T value) { + return this.values.indexOf(value); + } + + @Override + public void reset(List values) { + this.values.addAll(values); + this.values.trim(); + } + + @Override + public List values() { + return this.values; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java index 884f05256..5a0121039 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java @@ -330,7 +330,7 @@ public class MessageTranslator { textPacket.setNeedsTranslation(false); - TextDecoration decoration = session.getRegistryCache().chatTypes().get(chatType); + TextDecoration decoration = session.getRegistryCache().chatTypes().byId(chatType); if (decoration != null) { // As of 1.19 - do this to apply all the styling for signed messages // Though, Bedrock cannot care about the signed stuff. diff --git a/core/src/main/java/org/geysermc/geyser/util/ChunkUtils.java b/core/src/main/java/org/geysermc/geyser/util/ChunkUtils.java index a542f7431..379162540 100644 --- a/core/src/main/java/org/geysermc/geyser/util/ChunkUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/ChunkUtils.java @@ -280,7 +280,7 @@ public class ChunkUtils { * This must be done after the player has switched dimensions so we know what their dimension is */ public static void loadDimension(GeyserSession session) { - JavaDimension dimension = session.getRegistryCache().dimensions().get(session.getDimension()); + JavaDimension dimension = session.getRegistryCache().dimensions().byId(session.getDimension()); session.setDimensionType(dimension); int minY = dimension.minY(); int maxY = dimension.maxY(); From cc635d4447abb15089065b3948565e0382493684 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Wed, 1 May 2024 15:41:27 -0400 Subject: [PATCH 140/272] This would probably end up being an issue... --- .../geyser/session/cache/registry/SimpleJavaRegistry.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/registry/SimpleJavaRegistry.java b/core/src/main/java/org/geysermc/geyser/session/cache/registry/SimpleJavaRegistry.java index 633e5fbd1..9839a1568 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/registry/SimpleJavaRegistry.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/registry/SimpleJavaRegistry.java @@ -48,6 +48,7 @@ public class SimpleJavaRegistry implements JavaRegistry { @Override public void reset(List values) { + this.values.clear(); this.values.addAll(values); this.values.trim(); } From 1291b89e64e0ff5e96e90ad6a354add0c0f94365 Mon Sep 17 00:00:00 2001 From: chris Date: Thu, 2 May 2024 00:29:33 +0200 Subject: [PATCH 141/272] Ensure proper Geyser starting/disabling when Geyser is used on a client (#4621) * Ensure proper Geyser starting/disabling when Geyser is used on a client * also set correct remote port * only use direct connection on server, not client, actually override remote port --- .../fabric/GeyserFabricBootstrap.java | 23 ++++++++++++++++--- .../neoforge/GeyserNeoForgeBootstrap.java | 19 +++++++++++++-- .../platform/mod/GeyserModBootstrap.java | 19 +++++++++++++-- .../mixin/client/IntegratedServerMixin.java | 6 +++-- 4 files changed, 58 insertions(+), 9 deletions(-) diff --git a/bootstrap/mod/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricBootstrap.java b/bootstrap/mod/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricBootstrap.java index 81e329c03..c363ade8f 100644 --- a/bootstrap/mod/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricBootstrap.java +++ b/bootstrap/mod/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricBootstrap.java @@ -28,14 +28,15 @@ package org.geysermc.geyser.platform.fabric; import me.lucko.fabric.api.permissions.v0.Permissions; import net.fabricmc.api.EnvType; import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents; import net.fabricmc.loader.api.FabricLoader; import net.minecraft.commands.CommandSourceStack; import net.minecraft.world.entity.player.Player; +import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.platform.mod.GeyserModBootstrap; import org.geysermc.geyser.platform.mod.GeyserModUpdateListener; -import org.checkerframework.checker.nullness.qual.NonNull; public class GeyserFabricBootstrap extends GeyserModBootstrap implements ModInitializer { @@ -45,21 +46,37 @@ public class GeyserFabricBootstrap extends GeyserModBootstrap implements ModInit @Override public void onInitialize() { - if (FabricLoader.getInstance().getEnvironmentType() == EnvType.SERVER) { + if (isServer()) { // Set as an event, so we can get the proper IP and port if needed ServerLifecycleEvents.SERVER_STARTED.register((server) -> { this.setServer(server); onGeyserEnable(); }); + } else { + ClientLifecycleEvents.CLIENT_STOPPING.register(($)-> { + onGeyserShutdown(); + }); } // These are only registered once - ServerLifecycleEvents.SERVER_STOPPING.register((server) -> onGeyserShutdown()); + ServerLifecycleEvents.SERVER_STOPPING.register((server) -> { + if (isServer()) { + onGeyserShutdown(); + } else { + onGeyserDisable(); + } + }); + ServerPlayConnectionEvents.JOIN.register((handler, $, $$) -> GeyserModUpdateListener.onPlayReady(handler.getPlayer())); this.onGeyserInitialize(); } + @Override + public boolean isServer() { + return FabricLoader.getInstance().getEnvironmentType().equals(EnvType.SERVER); + } + @Override public boolean hasPermission(@NonNull Player source, @NonNull String permissionNode) { return Permissions.check(source, permissionNode); diff --git a/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeBootstrap.java b/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeBootstrap.java index 67cad1683..1655dea91 100644 --- a/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeBootstrap.java +++ b/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeBootstrap.java @@ -27,10 +27,10 @@ package org.geysermc.geyser.platform.neoforge; import net.minecraft.commands.CommandSourceStack; import net.minecraft.world.entity.player.Player; -import net.neoforged.api.distmarker.Dist; import net.neoforged.fml.common.Mod; import net.neoforged.fml.loading.FMLLoader; import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.event.GameShuttingDownEvent; import net.neoforged.neoforge.event.entity.player.PlayerEvent; import net.neoforged.neoforge.event.server.ServerStartedEvent; import net.neoforged.neoforge.event.server.ServerStoppingEvent; @@ -46,9 +46,11 @@ public class GeyserNeoForgeBootstrap extends GeyserModBootstrap { public GeyserNeoForgeBootstrap() { super(new GeyserNeoForgePlatform()); - if (FMLLoader.getDist() == Dist.DEDICATED_SERVER) { + if (isServer()) { // Set as an event so we can get the proper IP and port if needed NeoForge.EVENT_BUS.addListener(this::onServerStarted); + } else { + NeoForge.EVENT_BUS.addListener(this::onClientStopping); } NeoForge.EVENT_BUS.addListener(this::onServerStopping); @@ -64,6 +66,14 @@ public class GeyserNeoForgeBootstrap extends GeyserModBootstrap { } private void onServerStopping(ServerStoppingEvent event) { + if (isServer()) { + this.onGeyserShutdown(); + } else { + this.onGeyserDisable(); + } + } + + private void onClientStopping(GameShuttingDownEvent ignored) { this.onGeyserShutdown(); } @@ -71,6 +81,11 @@ public class GeyserNeoForgeBootstrap extends GeyserModBootstrap { GeyserModUpdateListener.onPlayReady(event.getEntity()); } + @Override + public boolean isServer() { + return FMLLoader.getDist().isDedicatedServer(); + } + @Override public boolean hasPermission(@NonNull Player source, @NonNull String permissionNode) { return this.permissionHandler.hasPermission(source, permissionNode); diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java index db966ec1a..d3d3a9104 100644 --- a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java @@ -58,6 +58,7 @@ import org.geysermc.geyser.util.FileUtils; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.net.SocketAddress; import java.nio.file.Path; import java.util.Map; import java.util.UUID; @@ -127,7 +128,9 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap { // We want to do this late in the server startup process to allow other mods // To do their job injecting, then connect into *that* this.geyserInjector = new GeyserModInjector(server, this.platform); - this.geyserInjector.initializeLocalChannel(this); + if (isServer()) { + this.geyserInjector.initializeLocalChannel(this); + } // Start command building // Set just "geyser" as the help command @@ -242,7 +245,19 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap { @Override public int getServerPort() { - return ((GeyserServerPortGetter) server).geyser$getServerPort(); + if (isServer()) { + return ((GeyserServerPortGetter) server).geyser$getServerPort(); + } else { + // Set in the IntegratedServerMixin + return geyserConfig.getRemote().port(); + } + } + + public abstract boolean isServer(); + + @Override + public @Nullable SocketAddress getSocketAddress() { + return this.geyserInjector.getServerSocketAddress(); } @Override diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/mixin/client/IntegratedServerMixin.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/mixin/client/IntegratedServerMixin.java index 4db1165fc..ece2f730a 100644 --- a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/mixin/client/IntegratedServerMixin.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/mixin/client/IntegratedServerMixin.java @@ -54,8 +54,10 @@ public class IntegratedServerMixin implements GeyserServerPortGetter { private void onOpenToLan(GameType gameType, boolean cheatsAllowed, int port, CallbackInfoReturnable cir) { if (cir.getReturnValueZ()) { // If the LAN is opened, starts Geyser. - GeyserModBootstrap.getInstance().setServer((MinecraftServer) (Object) this); - GeyserModBootstrap.getInstance().onGeyserEnable(); + GeyserModBootstrap instance = GeyserModBootstrap.getInstance(); + instance.setServer((MinecraftServer) (Object) this); + instance.getGeyserConfig().getRemote().setPort(port); + instance.onGeyserEnable(); // Ensure player locale has been loaded, in case it's different from Java system language GeyserLocale.loadGeyserLocale(this.minecraft.options.languageCode); // Give indication that Geyser is loaded From fdae333351a6e4f9e6b5aa4536133dee7ea35e91 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Wed, 1 May 2024 19:00:39 -0400 Subject: [PATCH 142/272] Add data components hash code to translated NBT --- .../java/org/geysermc/geyser/item/type/Item.java | 4 ++++ .../inventory/PlayerInventoryTranslator.java | 6 ++++++ .../org/geysermc/geyser/util/InventoryUtils.java | 15 +++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/Item.java b/core/src/main/java/org/geysermc/geyser/item/type/Item.java index cc49f3785..bfcfb23d1 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/Item.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/Item.java @@ -151,6 +151,10 @@ public class Item { if (repairCost != null) { builder.putInt("RepairCost", repairCost); } + + // Prevents the client from trying to stack items with untranslated components + // Relies on correct hash code implementation, and some luck + builder.putInt("GeyserHash", components.hashCode()); // TODO: don't rely on this } /** diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java index 7459ccf30..36752e582 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java @@ -261,6 +261,8 @@ public class PlayerInventoryTranslator extends InventoryTranslator { GeyserItemStack sourceItem = inventory.getItem(sourceSlot); if (playerInv.getCursor().isEmpty()) { playerInv.setCursor(sourceItem.copy(0), session); + } else if (!InventoryUtils.canStack(sourceItem, playerInv.getCursor())) { + return rejectRequest(request); } playerInv.getCursor().add(transferAmount); @@ -272,6 +274,8 @@ public class PlayerInventoryTranslator extends InventoryTranslator { GeyserItemStack sourceItem = playerInv.getCursor(); if (inventory.getItem(destSlot).isEmpty()) { inventory.setItem(destSlot, sourceItem.copy(0), session); + } else if (!InventoryUtils.canStack(sourceItem, inventory.getItem(destSlot))) { + return rejectRequest(request); } inventory.getItem(destSlot).add(transferAmount); @@ -284,6 +288,8 @@ public class PlayerInventoryTranslator extends InventoryTranslator { GeyserItemStack sourceItem = inventory.getItem(sourceSlot); if (inventory.getItem(destSlot).isEmpty()) { inventory.setItem(destSlot, sourceItem.copy(0), session); + } else if (!InventoryUtils.canStack(sourceItem, inventory.getItem(destSlot))) { + return rejectRequest(request); } inventory.getItem(destSlot).add(transferAmount); diff --git a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java index 63644d5fc..64c95afdd 100644 --- a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java @@ -178,11 +178,26 @@ public class InventoryUtils { } public static boolean canStack(GeyserItemStack item1, GeyserItemStack item2) { + if (GeyserImpl.getInstance().getConfig().isDebugMode()) + canStackDebug(item1, item2); if (item1.isEmpty() || item2.isEmpty()) return false; return item1.getJavaId() == item2.getJavaId() && Objects.equals(item1.getComponents(), item2.getComponents()); } + private static void canStackDebug(GeyserItemStack item1, GeyserItemStack item2) { + DataComponents components1 = item1.getComponents(); + DataComponents components2 = item2.getComponents(); + if (components1 != null && components2 != null) { + if (components1.hashCode() == components2.hashCode() && !components1.equals(components2)) { + GeyserImpl.getInstance().getLogger().error("DEBUG: DataComponents hash collision"); + GeyserImpl.getInstance().getLogger().error("hash: " + components1.hashCode()); + GeyserImpl.getInstance().getLogger().error("components1: " + components1); + GeyserImpl.getInstance().getLogger().error("components2: " + components2); + } + } + } + /** * Checks to see if an item stack represents air or has no count. */ From d003818e73c07b6e5b31370439f46bb1fb83c46f Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Thu, 2 May 2024 03:47:30 -0400 Subject: [PATCH 143/272] Potion fixes --- .../geyser/entity/EntityDefinitions.java | 1 - .../entity/type/AreaEffectCloudEntity.java | 7 +++++- .../entity/type/ThrownPotionEntity.java | 8 +++--- .../geyser/inventory/item/Potion.java | 25 ++++++++++++------- .../geysermc/geyser/item/type/PotionItem.java | 2 +- 5 files changed, 27 insertions(+), 16 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index 6cd5f3fc2..2c5fe7a86 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -202,7 +202,6 @@ public final class EntityDefinitions { .type(EntityType.AREA_EFFECT_CLOUD) .height(0.5f).width(1.0f) .addTranslator(MetadataType.FLOAT, AreaEffectCloudEntity::setRadius) - .addTranslator(MetadataType.INT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityDataTypes.EFFECT_COLOR, entityMetadata.getValue())) .addTranslator(null) // Waiting .addTranslator(MetadataType.PARTICLE, AreaEffectCloudEntity::setParticle) .build(); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/AreaEffectCloudEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/AreaEffectCloudEntity.java index 4b8eea061..83484b732 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/AreaEffectCloudEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/AreaEffectCloudEntity.java @@ -34,6 +34,7 @@ import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.EntityEffectParticleData; import org.geysermc.mcprotocollib.protocol.data.game.level.particle.Particle; import java.util.UUID; @@ -51,7 +52,7 @@ public class AreaEffectCloudEntity extends Entity { dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_DURATION, Integer.MAX_VALUE); // This disabled client side shrink of the cloud - dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_RADIUS, 0.0f); + dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_RADIUS, 0.5f); dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_CHANGE_RATE, Float.MIN_VALUE); dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_CHANGE_ON_PICKUP, Float.MIN_VALUE); @@ -69,5 +70,9 @@ public class AreaEffectCloudEntity extends Entity { Particle particle = entityMetadata.getValue(); Registries.PARTICLES.map(particle.getType(), p -> p.levelEventType() instanceof ParticleType particleType ? particleType : null).ifPresent(type -> dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_PARTICLE, type)); + + if (particle.getData() instanceof EntityEffectParticleData effectParticleData) { + dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, effectParticleData.getColor()); + } } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java index bfe429f33..88cf4f8b9 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ThrownPotionEntity.java @@ -54,7 +54,7 @@ public class ThrownPotionEntity extends ThrowableItemEntity { public void setItem(EntityMetadata entityMetadata) { ItemStack itemStack = entityMetadata.getValue(); if (itemStack == null) { - dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, 0); + dirtyMetadata.put(EntityDataTypes.AUX_VALUE_DATA, (short) 0); setFlag(EntityFlag.ENCHANTED, false); setFlag(EntityFlag.LINGERING, false); } else { @@ -63,12 +63,12 @@ public class ThrownPotionEntity extends ThrowableItemEntity { if (components != null) { PotionContents potionContents = components.get(DataComponentType.POTION_CONTENTS); if (potionContents != null) { - Potion potion = Potion.VALUES[potionContents.getPotionId()]; + Potion potion = Potion.getByJavaId(potionContents.getPotionId()); if (potion != null) { - dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, (int) potion.getBedrockId()); + dirtyMetadata.put(EntityDataTypes.AUX_VALUE_DATA, potion.getBedrockId()); setFlag(EntityFlag.ENCHANTED, !NON_ENCHANTED_POTIONS.contains(potion)); } else { - dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, 0); + dirtyMetadata.put(EntityDataTypes.AUX_VALUE_DATA, (short) 0); GeyserImpl.getInstance().getLogger().debug("Unknown java potion: " + potionContents.getPotionId()); } } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java b/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java index 00a9b091e..cf3a37afd 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java @@ -43,16 +43,19 @@ public enum Potion { INVISIBILITY(7), LONG_INVISIBILITY(8), LEAPING(9), - STRONG_LEAPING(11), LONG_LEAPING(10), + STRONG_LEAPING(11), FIRE_RESISTANCE(12), LONG_FIRE_RESISTANCE(13), SWIFTNESS(14), - STRONG_SWIFTNESS(16), LONG_SWIFTNESS(15), + STRONG_SWIFTNESS(16), SLOWNESS(17), - STRONG_SLOWNESS(42), LONG_SLOWNESS(18), + STRONG_SLOWNESS(42), + TURTLE_MASTER(37), + LONG_TURTLE_MASTER(38), + STRONG_TURTLE_MASTER(39), WATER_BREATHING(19), LONG_WATER_BREATHING(20), HEALING(21), @@ -60,20 +63,17 @@ public enum Potion { HARMING(23), STRONG_HARMING(24), POISON(25), - STRONG_POISON(27), LONG_POISON(26), + STRONG_POISON(27), REGENERATION(28), - STRONG_REGENERATION(30), LONG_REGENERATION(29), + STRONG_REGENERATION(30), STRENGTH(31), - STRONG_STRENGTH(33), LONG_STRENGTH(32), + STRONG_STRENGTH(33), WEAKNESS(34), LONG_WEAKNESS(35), LUCK(2), //does not exist - TURTLE_MASTER(37), - STRONG_TURTLE_MASTER(39), - LONG_TURTLE_MASTER(38), SLOW_FALLING(40), LONG_SLOW_FALLING(41); @@ -91,6 +91,13 @@ public enum Potion { return new PotionContents(this.ordinal(), -1, Int2ObjectMaps.emptyMap()); } + public static @Nullable Potion getByJavaId(int javaId) { + if (javaId >= 0 && javaId < VALUES.length) { + return VALUES[javaId]; + } + return null; + } + public static @Nullable Potion getByBedrockId(int bedrockId) { for (Potion potion : VALUES) { if (potion.bedrockId == bedrockId) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java index b69f7d35f..e9889c882 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java @@ -50,7 +50,7 @@ public class PotionItem extends Item { if (potionContents != null) { ItemDefinition customItemDefinition = CustomItemTranslator.getCustomItem(components, mapping); if (customItemDefinition == null) { - Potion potion = Potion.VALUES[potionContents.getPotionId()]; + Potion potion = Potion.getByJavaId(potionContents.getPotionId()); if (potion != null) { return ItemData.builder() .definition(mapping.getBedrockDefinition()) From 29a613b85c59f030bcfbaf9f1b80b1fe1a8a2aba Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Thu, 2 May 2024 05:04:19 -0400 Subject: [PATCH 144/272] Use java default area effect cloud radius --- .../geysermc/geyser/entity/type/AreaEffectCloudEntity.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/AreaEffectCloudEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/AreaEffectCloudEntity.java index 83484b732..165495506 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/AreaEffectCloudEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/AreaEffectCloudEntity.java @@ -32,6 +32,7 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.util.MathUtils; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.level.particle.EntityEffectParticleData; @@ -52,7 +53,7 @@ public class AreaEffectCloudEntity extends Entity { dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_DURATION, Integer.MAX_VALUE); // This disabled client side shrink of the cloud - dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_RADIUS, 0.5f); + dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_RADIUS, 3.0f); dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_CHANGE_RATE, Float.MIN_VALUE); dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_CHANGE_ON_PICKUP, Float.MIN_VALUE); @@ -61,7 +62,7 @@ public class AreaEffectCloudEntity extends Entity { public void setRadius(FloatEntityMetadata entityMetadata) { // Anything less than 0.5 will cause the cloud to despawn - float value = Math.max(entityMetadata.getPrimitiveValue(), 0.5f); + float value = MathUtils.clamp(entityMetadata.getPrimitiveValue(), 0.5f, 32.0f); dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_RADIUS, value); dirtyMetadata.put(EntityDataTypes.WIDTH, 2.0f * value); } From 60f8532be3826cb6e7a70750d4996045d4b3f26a Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Thu, 2 May 2024 06:06:12 -0400 Subject: [PATCH 145/272] Fix attribute display text --- .../translator/item/ItemTranslator.java | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index 49ee498b9..768c94791 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -62,6 +62,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemAttribut import java.text.DecimalFormat; import java.util.ArrayList; +import java.util.EnumMap; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -71,9 +72,21 @@ public final class ItemTranslator { /** * The order of these slots is their display order on Java Edition clients */ - private static final ItemAttributeModifiers.EquipmentSlotGroup[] ALL_SLOTS = ItemAttributeModifiers.EquipmentSlotGroup.values(); + private static final EnumMap SLOT_NAMES; private static final DecimalFormat ATTRIBUTE_FORMAT = new DecimalFormat("0.#####"); + static { + // These are the only slots that are used and have translation strings + SLOT_NAMES = new EnumMap<>(ItemAttributeModifiers.EquipmentSlotGroup.class); + SLOT_NAMES.put(ItemAttributeModifiers.EquipmentSlotGroup.MAIN_HAND, "mainhand"); + SLOT_NAMES.put(ItemAttributeModifiers.EquipmentSlotGroup.OFF_HAND, "offhand"); + SLOT_NAMES.put(ItemAttributeModifiers.EquipmentSlotGroup.FEET, "feet"); + SLOT_NAMES.put(ItemAttributeModifiers.EquipmentSlotGroup.LEGS, "legs"); + SLOT_NAMES.put(ItemAttributeModifiers.EquipmentSlotGroup.CHEST, "chest"); + SLOT_NAMES.put(ItemAttributeModifiers.EquipmentSlotGroup.HEAD, "head"); + SLOT_NAMES.put(ItemAttributeModifiers.EquipmentSlotGroup.BODY, "body"); + } + private ItemTranslator() { } @@ -208,7 +221,7 @@ public final class ItemTranslator { ItemAttributeModifiers.EquipmentSlotGroup slotGroup = entry.getSlot(); if (slotGroup == ItemAttributeModifiers.EquipmentSlotGroup.ANY) { // modifier applies to all slots implicitly - for (var slot : ALL_SLOTS) { + for (var slot : SLOT_NAMES.keySet()) { slotsToModifiers.computeIfAbsent(slot, s -> new ArrayList<>()).add(loreEntry); } } else { @@ -218,7 +231,7 @@ public final class ItemTranslator { } // iterate through the small array, not the map, so that ordering matches Java Edition - for (var slot : ALL_SLOTS) { + for (var slot : SLOT_NAMES.keySet()) { List modifierStrings = slotsToModifiers.get(slot); if (modifierStrings == null || modifierStrings.isEmpty()) { continue; @@ -228,7 +241,7 @@ public final class ItemTranslator { Component slotComponent = Component.text() .resetStyle() .color(NamedTextColor.GRAY) - .append(Component.newline(), Component.translatable("item.modifiers." + slot)) + .append(Component.newline(), Component.translatable("item.modifiers." + SLOT_NAMES.get(slot))) .build(); builder.getOrCreateLore().add(MessageTranslator.convertMessage(slotComponent, language)); From f7c65f38d1b4bb606797bda161efb1ab276e6672 Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Thu, 2 May 2024 12:51:14 +0200 Subject: [PATCH 146/272] properly annotate methods in the ServerTransferEvent --- .../geyser/api/event/java/ServerTransferEvent.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java b/api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java index b3b580ec3..594e28ef0 100644 --- a/api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java +++ b/api/src/main/java/org/geysermc/geyser/api/event/java/ServerTransferEvent.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.api.event.java; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.common.value.qual.IntRange; import org.geysermc.geyser.api.connection.GeyserConnection; import org.geysermc.geyser.api.event.connection.ConnectionEvent; @@ -44,7 +45,8 @@ public class ServerTransferEvent extends ConnectionEvent { private int bedrockPort; private final Map cookies; - public ServerTransferEvent(@NonNull GeyserConnection connection, String host, int port, Map cookies) { + public ServerTransferEvent(@NonNull GeyserConnection connection, + @NonNull String host, int port, @NonNull Map cookies) { super(connection); this.host = host; this.port = port; @@ -58,7 +60,7 @@ public class ServerTransferEvent extends ConnectionEvent { * * @return the host */ - public String host() { + public @NonNull String host() { return this.host; } @@ -77,7 +79,7 @@ public class ServerTransferEvent extends ConnectionEvent { * * @return the host where the Bedrock client will be transferred to, or null if not set. */ - public String bedrockHost() { + public @Nullable String bedrockHost() { return this.bedrockHost; } From 6a214f235c21fb2c36e30a5ecbdbd15aa21706ff Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Thu, 2 May 2024 13:07:18 -0400 Subject: [PATCH 147/272] Remove duplicate method --- .../org/geysermc/geyser/platform/mod/GeyserModBootstrap.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java index 98024ae45..786faac93 100644 --- a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java @@ -260,11 +260,6 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap { public abstract boolean isServer(); - @Override - public @Nullable SocketAddress getSocketAddress() { - return this.geyserInjector.getServerSocketAddress(); - } - @Override public boolean testFloodgatePluginPresent() { return this.platform.testFloodgatePluginPresent(this); From cab1a20034c05302ac5e61b6c9c401f6a396cc2a Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Thu, 2 May 2024 13:08:09 -0400 Subject: [PATCH 148/272] Set mappings commit to master --- core/src/main/resources/mappings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/resources/mappings b/core/src/main/resources/mappings index cb2cbe9f2..7c01501ed 160000 --- a/core/src/main/resources/mappings +++ b/core/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit cb2cbe9f262d14640f7c46885f1c8c9d23f2beaa +Subproject commit 7c01501ed6a0ee8848a66d729000539f2661f785 From b39ed5de53fd9b820023a3ac9c603a9936fa3e63 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Thu, 2 May 2024 20:33:28 -0400 Subject: [PATCH 149/272] Panda eating particles are not necessarily bamboo --- .../geysermc/geyser/entity/type/living/animal/PandaEntity.java | 3 ++- .../org/geysermc/geyser/inventory/item/StoredItemMappings.java | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java index 595e79e32..79401f63f 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java @@ -61,7 +61,8 @@ public class PandaEntity extends AnimalEntity { EntityEventPacket packet = new EntityEventPacket(); packet.setRuntimeEntityId(geyserId); packet.setType(EntityEventType.EATING_ITEM); - packet.setData(session.getItemMappings().getStoredItems().bamboo().getBedrockDefinition().getRuntimeId() << 16); + // As of 1.20.5 - pandas can eat cake + packet.setData(this.hand.getDefinition().getRuntimeId() << 16); session.sendUpstreamPacket(packet); } } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/StoredItemMappings.java b/core/src/main/java/org/geysermc/geyser/inventory/item/StoredItemMappings.java index c15a5d3b4..0305df685 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/StoredItemMappings.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/StoredItemMappings.java @@ -40,7 +40,6 @@ import java.util.Map; @Getter @Accessors(fluent = true) public class StoredItemMappings { - private final ItemMapping bamboo; private final ItemMapping banner; private final ItemMapping barrier; private final ItemMapping compass; @@ -56,7 +55,6 @@ public class StoredItemMappings { private final ItemMapping writtenBook; public StoredItemMappings(Map itemMappings) { - this.bamboo = load(itemMappings, Items.BAMBOO); this.banner = load(itemMappings, Items.WHITE_BANNER); // As of 1.17.10, all banners have the same Bedrock ID this.barrier = load(itemMappings, Items.BARRIER); this.compass = load(itemMappings, Items.COMPASS); From a39cd65537cbcdbf8e958f0378e25588387df35e Mon Sep 17 00:00:00 2001 From: basaigh <53559772+basaigh@users.noreply.github.com> Date: Fri, 3 May 2024 12:53:47 +0100 Subject: [PATCH 150/272] Fix velocity ping passthrough (#4626) --- .../platform/velocity/GeyserVelocityPingPassthrough.java | 6 ++++++ gradle/libs.versions.toml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPingPassthrough.java b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPingPassthrough.java index 8944ea134..b2258d3a3 100644 --- a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPingPassthrough.java +++ b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPingPassthrough.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.platform.velocity; import com.velocitypowered.api.event.proxy.ProxyPingEvent; +import com.velocitypowered.api.network.ProtocolState; import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.api.proxy.InboundConnection; import com.velocitypowered.api.proxy.ProxyServer; @@ -88,6 +89,11 @@ public class GeyserVelocityPingPassthrough implements IGeyserPingPassthrough { public ProtocolVersion getProtocolVersion() { return ProtocolVersion.MAXIMUM_VERSION; } + + @Override + public ProtocolState getProtocolState() { + return ProtocolState.STATUS; + } } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 24d0d5050..2cca857f3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -28,7 +28,7 @@ viaversion = "4.9.2" adapters = "1.12-SNAPSHOT" commodore = "2.2" bungeecord = "a7c6ede" -velocity = "3.1.1" +velocity = "3.3.0-SNAPSHOT" viaproxy = "3.2.1" fabric-minecraft = "1.20.5" fabric-loader = "0.15.10" From 9d299ee83bf7e4b3bf7fd82048c85d8642248bab Mon Sep 17 00:00:00 2001 From: basaigh <53559772+basaigh@users.noreply.github.com> Date: Fri, 3 May 2024 15:29:15 +0100 Subject: [PATCH 151/272] Fix particle reading issues (#4631) --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2cca857f3..3756faa0e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "209e79f8" # Revert from jitpack after release +mcprotocollib = "9b96ebda" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From b8fe71a8bc9762443e0a2814a151a57f14c305cd Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Sat, 4 May 2024 01:06:59 -0400 Subject: [PATCH 152/272] Bump MCPL to fix ClientboundExplodePacket (#4635) --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3756faa0e..b00db373f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "9b96ebda" # Revert from jitpack after release +mcprotocollib = "c1786e2" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From 5770c96f48c4713be5786394963b73dc06806232 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sun, 5 May 2024 01:29:37 -0400 Subject: [PATCH 153/272] Indicate support for 1.20.81 --- README.md | 2 +- .../main/java/org/geysermc/geyser/network/GameProtocol.java | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2fdc93fa1..9257af9ac 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here! -### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.80 and Minecraft Java 1.20.5/1.20.6 +### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.80/81 and Minecraft Java 1.20.5/1.20.6 ## Setting Up Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser. diff --git a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java index fdaecbb69..f9292671f 100644 --- a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java +++ b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java @@ -50,7 +50,9 @@ public final class GameProtocol { * Default Bedrock codec that should act as a fallback. Should represent the latest available * release of the game that Geyser supports. */ - public static final BedrockCodec DEFAULT_BEDROCK_CODEC = CodecProcessor.processCodec(Bedrock_v671.CODEC); + public static final BedrockCodec DEFAULT_BEDROCK_CODEC = CodecProcessor.processCodec(Bedrock_v671.CODEC.toBuilder() + .minecraftVersion("1.20.81") + .build()); /** * A list of all supported Bedrock versions that can join Geyser @@ -77,7 +79,7 @@ public final class GameProtocol { .minecraftVersion("1.20.70/1.20.73") .build())); SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(DEFAULT_BEDROCK_CODEC.toBuilder() - .minecraftVersion("1.20.80") + .minecraftVersion("1.20.80/1.20.81") .build())); } From 8addcadb71993236730764963e3d776ac007b7a7 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Sun, 5 May 2024 02:24:28 -0400 Subject: [PATCH 154/272] Bump MCPL to increase NBT max depth (#4639) --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b00db373f..b1eb616b3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "d9d773e" -mcprotocollib = "c1786e2" # Revert from jitpack after release +mcprotocollib = "1234962" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From 0a261f1d9d2a6b1aae8880af8811064e7ccbacec Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Mon, 6 May 2024 21:40:32 -0400 Subject: [PATCH 155/272] Update MCPL and MCAuthLib (#4645) * Update MCPL and MCAuthLib * Bump MCPL --- .../java/org/geysermc/geyser/inventory/item/Potion.java | 4 ++-- .../geysermc/geyser/inventory/item/TippedArrowPotion.java | 7 +++++-- .../main/java/org/geysermc/geyser/item/type/ArrowItem.java | 5 +++-- gradle/libs.versions.toml | 4 ++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java b/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java index cf3a37afd..86c19de80 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.inventory.item; -import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; import lombok.Getter; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.mcprotocollib.protocol.data.game.item.component.PotionContents; +import java.util.Collections; import java.util.Locale; @Getter @@ -88,7 +88,7 @@ public enum Potion { } public PotionContents toComponent() { - return new PotionContents(this.ordinal(), -1, Int2ObjectMaps.emptyMap()); + return new PotionContents(this.ordinal(), -1, Collections.emptyList()); } public static @Nullable Potion getByJavaId(int javaId) { diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java b/core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java index ec6b10ec8..b849e07e2 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java @@ -95,8 +95,11 @@ public enum TippedArrowPotion { this.javaColor = arrowParticleColor.getColor(); } - public static TippedArrowPotion of(int id) { - return VALUES[id]; + public static @Nullable TippedArrowPotion of(int id) { + if (id >= 0 && id < VALUES.length) { + return VALUES[id]; + } + return null; } public static @Nullable TippedArrowPotion getByBedrockId(int bedrockId) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java index f2548e170..84c3b1a39 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.item.type; -import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.inventory.GeyserItemStack; @@ -36,6 +35,8 @@ import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.PotionContents; +import java.util.Collections; + public class ArrowItem extends Item { public ArrowItem(String javaIdentifier, Builder builder) { super(javaIdentifier, builder); @@ -47,7 +48,7 @@ public class ArrowItem extends Item { GeyserItemStack itemStack = super.translateToJava(itemData, mapping, mappings); if (tippedArrowPotion != null) { itemStack = Items.TIPPED_ARROW.newItemStack(itemStack.getAmount(), itemStack.getComponents()); - PotionContents contents = new PotionContents(tippedArrowPotion.ordinal(), -1, Int2ObjectMaps.emptyMap()); + PotionContents contents = new PotionContents(tippedArrowPotion.ordinal(), -1, Collections.emptyList()); itemStack.getOrCreateComponents().put(DataComponentType.POTION_CONTENTS, contents); } return itemStack; diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b1eb616b3..65a5e3a52 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,8 +14,8 @@ protocol = "3.0.0.Beta1-20240411.165033-129" protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" -mcauthlib = "d9d773e" -mcprotocollib = "1234962" # Revert from jitpack after release +mcauthlib = "e5b0bcc" +mcprotocollib = "42ea4a4" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From cda7a19a08f5b9d62ce492f6fdd87af3bc461e8b Mon Sep 17 00:00:00 2001 From: Eclipse <116838833+eclipseisoffline@users.noreply.github.com> Date: Tue, 7 May 2024 07:16:21 +0100 Subject: [PATCH 156/272] Fix discarding of custom trim patterns/materials (#4642) * Fix discarding of custom trim patterns/materials * Rename `stripNamespace` method to reflect its behaviour --- .../geyser/inventory/recipe/TrimRecipe.java | 12 +++++++---- .../geysermc/geyser/item/type/ArmorItem.java | 20 ++++++++++++++----- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java b/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java index 37eb905a4..9d9dbe0db 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java @@ -47,7 +47,7 @@ public final class TrimRecipe { public static final ItemDescriptorWithCount TEMPLATE = tagDescriptor("minecraft:trim_templates"); public static TrimMaterial readTrimMaterial(GeyserSession session, RegistryEntry entry) { - String key = stripNamespace(entry.getId()); + String key = stripMinecraftNamespace(entry.getId()); // Color is used when hovering over the item // Find the nearest legacy color from the RGB Java gives us to work with @@ -67,7 +67,7 @@ public final class TrimRecipe { } public static TrimPattern readTrimPattern(GeyserSession session, RegistryEntry entry) { - String key = stripNamespace(entry.getId()); + String key = stripMinecraftNamespace(entry.getId()); String itemIdentifier = entry.getData().getString("template_item"); ItemMapping itemMapping = session.getItemMappings().getMapping(itemIdentifier); @@ -79,10 +79,14 @@ public final class TrimRecipe { } // TODO find a good place for a stripNamespace util method - private static String stripNamespace(String identifier) { + private static String stripMinecraftNamespace(String identifier) { int i = identifier.indexOf(':'); if (i >= 0) { - return identifier.substring(i + 1); + String namespace = identifier.substring(0, i); + // Only strip minecraft namespace + if (namespace.equals("minecraft")) { + return identifier.substring(i + 1); + } } return identifier; } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java index fc0dd3ba4..0a25a8d4f 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java @@ -51,14 +51,15 @@ public class ArmorItem extends Item { ArmorTrim trim = components.get(DataComponentType.TRIM); if (trim != null) { - // discard custom trim patterns/materials to prevent visual glitches on bedrock - if (trim.material().isCustom() || trim.pattern().isCustom()) { - return; - } - TrimMaterial material = session.getRegistryCache().trimMaterials().byId(trim.material().id()); TrimPattern pattern = session.getRegistryCache().trimPatterns().byId(trim.pattern().id()); + // discard custom trim patterns/materials to prevent visual glitches on bedrock + if (!getNamespace(material.getMaterialId()).equals("minecraft") + || !getNamespace(pattern.getPatternId()).equals("minecraft")) { + return; + } + NbtMapBuilder trimBuilder = NbtMap.builder(); // bedrock has an uppercase first letter key, and the value is not namespaced trimBuilder.put("Material", material.getMaterialId()); @@ -71,4 +72,13 @@ public class ArmorItem extends Item { public boolean isValidRepairItem(Item other) { return material.getRepairIngredient() == other; } + + // TODO maybe some kind of namespace util? + private static String getNamespace(String identifier) { + int i = identifier.indexOf(':'); + if (i >= 0) { + return identifier.substring(0, i); + } + return "minecraft"; + } } From 627c2babe9380c64692728581339c0c60869eb6c Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Tue, 7 May 2024 19:26:31 -0400 Subject: [PATCH 157/272] Fix various mob attack animations (#4627) * Fix various mob attack animations * Fix error * Don't set piglin target unless attacking * Fix piglin and hoglin shaking effect * Fix piglin attack animation when switching weapons --- .../geyser/entity/EntityDefinitions.java | 7 ++- .../geyser/entity/type/LivingEntity.java | 9 +++ .../type/living/animal/HoglinEntity.java | 8 +++ .../monster/AbstractSkeletonEntity.java | 14 +++++ .../type/living/monster/BasePiglinEntity.java | 18 ++++++ .../type/living/monster/PiglinEntity.java | 56 ++++++++++++++++++- .../type/living/monster/ZoglinEntity.java | 7 +++ .../type/living/monster/ZombieEntity.java | 5 ++ .../living/monster/raid/PillagerEntity.java | 40 ++++++++++--- .../living/monster/raid/RavagerEntity.java | 54 ++++++++++++++++++ .../living/monster/raid/VindicatorEntity.java | 7 +++ .../inventory/item/StoredItemMappings.java | 2 + .../java/entity/JavaAnimateTranslator.java | 11 ++++ 13 files changed, 226 insertions(+), 12 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/RavagerEntity.java diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index 2c5fe7a86..991b95571 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.entity; +import org.geysermc.geyser.entity.type.living.monster.raid.RavagerEntity; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.MetadataType; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; @@ -132,7 +133,7 @@ public final class EntityDefinitions { public static final EntityDefinition POTION; public static final EntityDefinition PUFFERFISH; public static final EntityDefinition RABBIT; - public static final EntityDefinition RAVAGER; + public static final EntityDefinition RAVAGER; public static final EntityDefinition SALMON; public static final EntityDefinition SHEEP; public static final EntityDefinition SHULKER; @@ -745,9 +746,9 @@ public final class EntityDefinitions { .type(EntityType.PILLAGER) .height(1.8f).width(0.6f) .offset(1.62f) - .addTranslator(null) // Charging; doesn't have an equivalent on Bedrock //TODO check + .addTranslator(MetadataType.BOOLEAN, PillagerEntity::setChargingCrossbow) .build(); - RAVAGER = EntityDefinition.inherited(raidParticipantEntityBase.factory(), raidParticipantEntityBase) + RAVAGER = EntityDefinition.inherited(RavagerEntity::new, raidParticipantEntityBase) .type(EntityType.RAVAGER) .height(1.9f).width(1.2f) .build(); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java index d27fa3cad..499084555 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/LivingEntity.java @@ -352,6 +352,15 @@ public class LivingEntity extends Entity { session.sendUpstreamPacket(offHandPacket); } + /** + * Called when a SWING_ARM animation packet is received + * + * @return true if an ATTACK_START event should be used instead + */ + public boolean useArmSwingAttack() { + return false; + } + /** * Attributes are properties of an entity that are generally more runtime-based instead of permanent properties. * Movement speed, current attack damage with a weapon, current knockback resistance. diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java index 46cafad02..74c937417 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java @@ -27,6 +27,7 @@ package org.geysermc.geyser.entity.type.living.animal; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; +import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; @@ -40,6 +41,8 @@ public class HoglinEntity extends AnimalEntity { public HoglinEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); + dirtyMetadata.put(EntityDataTypes.TARGET_EID, session.getPlayerEntity().getGeyserId()); + setFlag(EntityFlag.SHAKING, isShaking()); } public void setImmuneToZombification(BooleanEntityMetadata entityMetadata) { @@ -68,4 +71,9 @@ public class HoglinEntity extends AnimalEntity { protected boolean isEnemy() { return true; } + + @Override + public boolean useArmSwingAttack() { + return true; + } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/AbstractSkeletonEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/AbstractSkeletonEntity.java index 3fbdda245..d08fff06a 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/AbstractSkeletonEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/AbstractSkeletonEntity.java @@ -26,7 +26,9 @@ package org.geysermc.geyser.entity.type.living.monster; import org.cloudburstmc.math.vector.Vector3f; +import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; +import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; @@ -45,5 +47,17 @@ public class AbstractSkeletonEntity extends MonsterEntity { byte xd = entityMetadata.getPrimitiveValue(); // A bit of a loophole so the hands get raised - set the target ID to its own ID dirtyMetadata.put(EntityDataTypes.TARGET_EID, ((xd & 4) == 4) ? geyserId : 0); + + if ((xd & 4) == 4) { + ItemDefinition bow = session.getItemMappings().getStoredItems().bow().getBedrockDefinition(); + setFlag(EntityFlag.FACING_TARGET_TO_RANGE_ATTACK, this.hand.getDefinition() == bow || this.offhand.getDefinition() == bow); + } else { + setFlag(EntityFlag.FACING_TARGET_TO_RANGE_ATTACK, false); + } + } + + @Override + public boolean useArmSwingAttack() { + return true; } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BasePiglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BasePiglinEntity.java index 09bd28cd0..9258cd3b8 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BasePiglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BasePiglinEntity.java @@ -26,10 +26,13 @@ package org.geysermc.geyser.entity.type.living.monster; import org.cloudburstmc.math.vector.Vector3f; +import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; import java.util.UUID; @@ -38,6 +41,16 @@ public class BasePiglinEntity extends MonsterEntity { public BasePiglinEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); + // Both TARGET_EID and BLOCK are needed for melee attack animation + dirtyMetadata.put(EntityDataTypes.BLOCK, session.getBlockMappings().getDefinition(1)); + setFlag(EntityFlag.SHAKING, isShaking()); + } + + @Override + public void setMobFlags(ByteEntityMetadata entityMetadata) { + super.setMobFlags(entityMetadata); + byte xd = entityMetadata.getPrimitiveValue(); + dirtyMetadata.put(EntityDataTypes.TARGET_EID, (xd & 4) == 4 ? session.getPlayerEntity().getGeyserId() : 0); } public void setImmuneToZombification(BooleanEntityMetadata entityMetadata) { @@ -50,4 +63,9 @@ public class BasePiglinEntity extends MonsterEntity { protected boolean isShaking() { return (!isImmuneToZombification && !session.getDimensionType().piglinSafe()) || super.isShaking(); } + + @Override + public boolean useArmSwingAttack() { + return true; + } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java index f0f01272f..19b6d8e69 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/PiglinEntity.java @@ -27,16 +27,22 @@ package org.geysermc.geyser.entity.type.living.monster; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; +import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; +import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerId; +import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; +import org.cloudburstmc.protocol.bedrock.packet.MobEquipmentPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; +import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import java.util.UUID; @@ -55,13 +61,61 @@ public class PiglinEntity extends BasePiglinEntity { } public void setChargingCrossbow(BooleanEntityMetadata entityMetadata) { - setFlag(EntityFlag.CHARGING, entityMetadata.getPrimitiveValue()); + boolean charging = entityMetadata.getPrimitiveValue(); + setFlag(EntityFlag.CHARGING, charging); + dirtyMetadata.put(EntityDataTypes.CHARGE_AMOUNT, charging ? (byte) 64 : (byte) 0); // TODO: gradually increase } public void setDancing(BooleanEntityMetadata entityMetadata) { setFlag(EntityFlag.DANCING, entityMetadata.getPrimitiveValue()); } + @Override + public void setHand(ItemStack stack) { + ItemMapping crossbow = session.getItemMappings().getStoredItems().crossbow(); + boolean toCrossbow = stack != null && stack.getId() == crossbow.getJavaItem().javaId(); + + if (toCrossbow ^ this.hand.getDefinition() == crossbow.getBedrockDefinition()) { // If switching to/from crossbow + dirtyMetadata.put(EntityDataTypes.BLOCK, session.getBlockMappings().getDefinition(toCrossbow ? 0 : 1)); + dirtyMetadata.put(EntityDataTypes.CHARGE_AMOUNT, (byte) 0); + setFlag(EntityFlag.CHARGED, false); + setFlag(EntityFlag.USING_ITEM, false); + updateBedrockMetadata(); + + if (this.hand.isValid()) { + MobEquipmentPacket mobEquipmentPacket = new MobEquipmentPacket(); + mobEquipmentPacket.setRuntimeEntityId(geyserId); + mobEquipmentPacket.setContainerId(ContainerId.INVENTORY); + mobEquipmentPacket.setInventorySlot(0); + mobEquipmentPacket.setHotbarSlot(-1); + mobEquipmentPacket.setItem(ItemData.AIR); + session.sendUpstreamPacket(mobEquipmentPacket); + } + } + + super.setHand(stack); + } + + @Override + public void updateMainHand(GeyserSession session) { + super.updateMainHand(session); + + if (this.hand.getDefinition() == session.getItemMappings().getStoredItems().crossbow().getBedrockDefinition()) { + if (this.hand.getTag() != null && this.hand.getTag().containsKey("chargedItem")) { + dirtyMetadata.put(EntityDataTypes.CHARGE_AMOUNT, Byte.MAX_VALUE); + setFlag(EntityFlag.CHARGING, false); + setFlag(EntityFlag.CHARGED, true); + setFlag(EntityFlag.USING_ITEM, true); + } else if (getFlag(EntityFlag.CHARGED)) { + dirtyMetadata.put(EntityDataTypes.CHARGE_AMOUNT, (byte) 0); + setFlag(EntityFlag.CHARGED, false); + setFlag(EntityFlag.USING_ITEM, false); + } + } + + updateBedrockMetadata(); + } + @Override public void updateOffHand(GeyserSession session) { // Check if the Piglin is holding Gold and set the ADMIRING flag accordingly so its pose updates diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java index 7eb950e21..206746fb9 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.entity.type.living.monster; import org.cloudburstmc.math.vector.Vector3f; +import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; @@ -37,6 +38,7 @@ public class ZoglinEntity extends MonsterEntity { public ZoglinEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); + dirtyMetadata.put(EntityDataTypes.TARGET_EID, session.getPlayerEntity().getGeyserId()); } public void setBaby(BooleanEntityMetadata entityMetadata) { @@ -64,4 +66,9 @@ public class ZoglinEntity extends MonsterEntity { protected boolean isEnemy() { return true; } + + @Override + public boolean useArmSwingAttack() { + return true; + } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieEntity.java index b8351089d..b07afd742 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZombieEntity.java @@ -57,4 +57,9 @@ public class ZombieEntity extends MonsterEntity { protected boolean isShaking() { return convertingToDrowned || super.isShaking(); } + + @Override + public boolean useArmSwingAttack() { + return true; + } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/PillagerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/PillagerEntity.java index 1d2d9115b..fd7448e29 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/PillagerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/PillagerEntity.java @@ -26,10 +26,13 @@ package org.geysermc.geyser.entity.type.living.monster.raid; import org.cloudburstmc.math.vector.Vector3f; +import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; +import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import java.util.UUID; @@ -39,16 +42,22 @@ public class PillagerEntity extends AbstractIllagerEntity { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); } + public void setChargingCrossbow(BooleanEntityMetadata entityMetadata) { + boolean charging = entityMetadata.getPrimitiveValue(); + setFlag(EntityFlag.CHARGING, charging); + dirtyMetadata.put(EntityDataTypes.CHARGE_AMOUNT, charging ? (byte) 64 : (byte) 0); // TODO: gradually increase + } + @Override - public void updateMainHand(GeyserSession session) { //TODO - checkForCrossbow(); + public void updateMainHand(GeyserSession session) { + updateCrossbow(); super.updateMainHand(session); } @Override public void updateOffHand(GeyserSession session) { - checkForCrossbow(); + updateCrossbow(); super.updateOffHand(session); } @@ -56,12 +65,27 @@ public class PillagerEntity extends AbstractIllagerEntity { /** * Check for a crossbow in either the mainhand or offhand. If one exists, indicate that the pillager should be posing */ - protected void checkForCrossbow() { + protected void updateCrossbow() { ItemMapping crossbow = session.getItemMappings().getStoredItems().crossbow(); - boolean hasCrossbow = this.hand.getDefinition() == crossbow.getBedrockDefinition() - || this.offhand.getDefinition() == crossbow.getBedrockDefinition(); - setFlag(EntityFlag.USING_ITEM, hasCrossbow); - setFlag(EntityFlag.CHARGED, hasCrossbow); + ItemData activeCrossbow = null; + if (this.hand.getDefinition() == crossbow.getBedrockDefinition()) { + activeCrossbow = this.hand; + } else if (this.offhand.getDefinition() == crossbow.getBedrockDefinition()) { + activeCrossbow = this.offhand; + } + + if (activeCrossbow != null) { + if (activeCrossbow.getTag() != null && activeCrossbow.getTag().containsKey("chargedItem")) { + dirtyMetadata.put(EntityDataTypes.CHARGE_AMOUNT, Byte.MAX_VALUE); + setFlag(EntityFlag.CHARGING, false); + setFlag(EntityFlag.CHARGED, true); + setFlag(EntityFlag.USING_ITEM, true); + } else if (getFlag(EntityFlag.CHARGED)) { + dirtyMetadata.put(EntityDataTypes.CHARGE_AMOUNT, (byte) 0); + setFlag(EntityFlag.CHARGED, false); + setFlag(EntityFlag.USING_ITEM, false); + } + } updateBedrockMetadata(); } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/RavagerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/RavagerEntity.java new file mode 100644 index 000000000..6190bae10 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/RavagerEntity.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.entity.type.living.monster.raid; + +import org.cloudburstmc.math.vector.Vector3f; +import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; +import org.geysermc.geyser.entity.EntityDefinition; +import org.geysermc.geyser.session.GeyserSession; + +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +public class RavagerEntity extends RaidParticipantEntity { + + public RavagerEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { + super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); + } + + @Override + public boolean useArmSwingAttack() { + setFlag(EntityFlag.DELAYED_ATTACK, false); + updateBedrockMetadata(); + + session.scheduleInEventLoop(() -> { + setFlag(EntityFlag.DELAYED_ATTACK, true); + updateBedrockMetadata(); + }, 75, TimeUnit.MILLISECONDS); + + return true; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/VindicatorEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/VindicatorEntity.java index 04a58addd..a2557e75a 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/VindicatorEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/raid/VindicatorEntity.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.entity.type.living.monster.raid; import org.cloudburstmc.math.vector.Vector3f; +import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; @@ -37,6 +38,7 @@ public class VindicatorEntity extends AbstractIllagerEntity { public VindicatorEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); + dirtyMetadata.put(EntityDataTypes.TARGET_EID, session.getPlayerEntity().getGeyserId()); } @Override @@ -46,4 +48,9 @@ public class VindicatorEntity extends AbstractIllagerEntity { byte xd = entityMetadata.getPrimitiveValue(); setFlag(EntityFlag.ANGRY, (xd & 4) == 4); } + + @Override + public boolean useArmSwingAttack() { + return true; + } } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/StoredItemMappings.java b/core/src/main/java/org/geysermc/geyser/inventory/item/StoredItemMappings.java index 0305df685..05f6ba6cc 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/StoredItemMappings.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/StoredItemMappings.java @@ -42,6 +42,7 @@ import java.util.Map; public class StoredItemMappings { private final ItemMapping banner; private final ItemMapping barrier; + private final ItemMapping bow; private final ItemMapping compass; private final ItemMapping crossbow; private final ItemMapping egg; @@ -57,6 +58,7 @@ public class StoredItemMappings { public StoredItemMappings(Map itemMappings) { this.banner = load(itemMappings, Items.WHITE_BANNER); // As of 1.17.10, all banners have the same Bedrock ID this.barrier = load(itemMappings, Items.BARRIER); + this.bow = load(itemMappings, Items.BOW); this.compass = load(itemMappings, Items.COMPASS); this.crossbow = load(itemMappings, Items.CROSSBOW); this.egg = load(itemMappings, Items.EGG); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaAnimateTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaAnimateTranslator.java index 8bd4bad10..bf6dfe684 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaAnimateTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaAnimateTranslator.java @@ -26,10 +26,13 @@ package org.geysermc.geyser.translator.protocol.java.entity; import org.cloudburstmc.math.vector.Vector3f; +import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; import org.cloudburstmc.protocol.bedrock.packet.AnimateEntityPacket; import org.cloudburstmc.protocol.bedrock.packet.AnimatePacket; +import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket; import org.cloudburstmc.protocol.bedrock.packet.SpawnParticleEffectPacket; import org.geysermc.geyser.entity.type.Entity; +import org.geysermc.geyser.entity.type.LivingEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; @@ -57,6 +60,14 @@ public class JavaAnimateTranslator extends PacketTranslator { + if (entity instanceof LivingEntity livingEntity && livingEntity.useArmSwingAttack()) { + EntityEventPacket entityEventPacket = new EntityEventPacket(); + entityEventPacket.setRuntimeEntityId(entity.getGeyserId()); + entityEventPacket.setType(EntityEventType.ATTACK_START); + session.sendUpstreamPacket(entityEventPacket); + return; + } + animatePacket.setAction(AnimatePacket.Action.SWING_ARM); if (entity.getEntityId() == session.getPlayerEntity().getEntityId()) { session.activateArmAnimationTicking(); From e697eb3ae38bbda0b1b4803ea03a73067881dec2 Mon Sep 17 00:00:00 2001 From: chris Date: Fri, 10 May 2024 23:58:27 +0200 Subject: [PATCH 158/272] Feat: Make connection data exposed in api less prone to throw errors (#4604) * Feat: Make connection data exposed in api less prone to throw errors * address reviews * review --- .../connection/ConnectionRequestEvent.java | 26 +++++++++++++++++-- .../network/GeyserServerInitializer.java | 5 ---- .../geyser/network/UpstreamPacketHandler.java | 4 +++ .../geyser/session/GeyserSession.java | 12 +++++---- 4 files changed, 35 insertions(+), 12 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/event/connection/ConnectionRequestEvent.java b/api/src/main/java/org/geysermc/geyser/api/event/connection/ConnectionRequestEvent.java index 5c1f4ef51..b36ee8bfb 100644 --- a/api/src/main/java/org/geysermc/geyser/api/event/connection/ConnectionRequestEvent.java +++ b/api/src/main/java/org/geysermc/geyser/api/event/connection/ConnectionRequestEvent.java @@ -46,13 +46,35 @@ public final class ConnectionRequestEvent implements Event, Cancellable { this.proxyIp = proxyIp; } + /** + * The IP address of the client attempting to connect + * + * @return the IP address of the client attempting to connect + * @deprecated Use {@link #inetSocketAddress()} instead + */ + @NonNull @Deprecated(forRemoval = true) + public InetSocketAddress getInetSocketAddress() { + return ip; + } + + /** + * The IP address of the proxy handling the connection. It will return null if there is no proxy. + * + * @return the IP address of the proxy handling the connection + * @deprecated Use {@link #proxyIp()} instead + */ + @Nullable @Deprecated(forRemoval = true) + public InetSocketAddress getProxyIp() { + return proxyIp; + } + /** * The IP address of the client attempting to connect * * @return the IP address of the client attempting to connect */ @NonNull - public InetSocketAddress getInetSocketAddress() { + public InetSocketAddress inetSocketAddress() { return ip; } @@ -62,7 +84,7 @@ public final class ConnectionRequestEvent implements Event, Cancellable { * @return the IP address of the proxy handling the connection */ @Nullable - public InetSocketAddress getProxyIp() { + public InetSocketAddress proxyIp() { return proxyIp; } diff --git a/core/src/main/java/org/geysermc/geyser/network/GeyserServerInitializer.java b/core/src/main/java/org/geysermc/geyser/network/GeyserServerInitializer.java index 662e2f4c7..5c83702ae 100644 --- a/core/src/main/java/org/geysermc/geyser/network/GeyserServerInitializer.java +++ b/core/src/main/java/org/geysermc/geyser/network/GeyserServerInitializer.java @@ -25,11 +25,8 @@ package org.geysermc.geyser.network; -import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; -import io.netty.channel.ChannelHandlerContext; import io.netty.channel.DefaultEventLoopGroup; -import io.netty.channel.SimpleChannelInboundHandler; import io.netty.util.concurrent.DefaultThreadFactory; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.BedrockPeer; @@ -37,7 +34,6 @@ import org.cloudburstmc.protocol.bedrock.BedrockServerSession; import org.cloudburstmc.protocol.bedrock.netty.codec.packet.BedrockPacketCodec; import org.cloudburstmc.protocol.bedrock.netty.initializer.BedrockServerInitializer; import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.api.event.bedrock.SessionInitializeEvent; import org.geysermc.geyser.session.GeyserSession; import java.net.InetSocketAddress; @@ -72,7 +68,6 @@ public class GeyserServerInitializer extends BedrockServerInitializer { channel.pipeline().addAfter(BedrockPacketCodec.NAME, InvalidPacketHandler.NAME, new InvalidPacketHandler(session)); bedrockServerSession.setPacketHandler(new UpstreamPacketHandler(this.geyser, session)); - this.geyser.eventBus().fire(new SessionInitializeEvent(session)); } catch (Throwable e) { // Error must be caught or it will be swallowed this.geyser.getLogger().error("Error occurred while initializing player!", e); diff --git a/core/src/main/java/org/geysermc/geyser/network/UpstreamPacketHandler.java b/core/src/main/java/org/geysermc/geyser/network/UpstreamPacketHandler.java index 59485b2cd..23ab1697f 100644 --- a/core/src/main/java/org/geysermc/geyser/network/UpstreamPacketHandler.java +++ b/core/src/main/java/org/geysermc/geyser/network/UpstreamPacketHandler.java @@ -54,6 +54,7 @@ import org.cloudburstmc.protocol.common.PacketSignal; import org.cloudburstmc.protocol.common.util.Zlib; import org.geysermc.geyser.Constants; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.api.event.bedrock.SessionInitializeEvent; import org.geysermc.geyser.api.network.AuthType; import org.geysermc.geyser.api.pack.PackCodec; import org.geysermc.geyser.api.pack.ResourcePack; @@ -188,6 +189,9 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { return PacketSignal.HANDLED; } + // Fire SessionInitializeEvent here as we now know the client data + geyser.eventBus().fire(new SessionInitializeEvent(session)); + PlayStatusPacket playStatus = new PlayStatusPacket(); playStatus.setStatus(PlayStatusPacket.Status.LOGIN_SUCCESS); session.sendUpstreamPacket(playStatus); diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index d10a20b3d..617087f71 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -1077,9 +1077,11 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { if (!closed) { loggedIn = false; - // Fire SessionDisconnectEvent SessionDisconnectEvent disconnectEvent = new SessionDisconnectEvent(this, reason); - geyser.getEventBus().fire(disconnectEvent); + if (authData != null && clientData != null) { // can occur if player disconnects before Bedrock auth finishes + // Fire SessionDisconnectEvent + geyser.getEventBus().fire(disconnectEvent); + } // Disconnect downstream if necessary if (downstream != null) { @@ -1404,7 +1406,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { @Override public String name() { - return null; + return playerEntity != null ? javaUsername() : bedrockUsername(); } @Override @@ -1941,12 +1943,12 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { @Override public @MonotonicNonNull String javaUsername() { - return playerEntity.getUsername(); + return playerEntity != null ? playerEntity.getUsername() : null; } @Override public UUID javaUuid() { - return playerEntity.getUuid(); + return playerEntity != null ? playerEntity.getUuid() : null ; } @Override From 7801e357fb3c8e8ffecd9fb01c143d1c8343106c Mon Sep 17 00:00:00 2001 From: Teelair Date: Fri, 10 May 2024 17:20:52 -0600 Subject: [PATCH 159/272] Map new Mace enchantments for Bedrock clients (#4653) * Map new Mace enchantments for Bedrock clients * Move to using a map for Java-only enchantments. * Change to using null check for translationKey --- .../org/geysermc/geyser/item/type/Item.java | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/Item.java b/core/src/main/java/org/geysermc/geyser/item/type/Item.java index bfcfb23d1..fc4fda07c 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/Item.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/Item.java @@ -53,6 +53,16 @@ import java.util.List; import java.util.Map; public class Item { + /** + * This is a map from Java-only enchantments to their translation keys so that we can + * map these enchantments to Bedrock clients, since they don't actually exist there. + */ + private static final Map ENCHANTMENT_TRANSLATION_KEYS = Map.of( + Enchantment.JavaEnchantment.SWEEPING_EDGE, "enchantment.minecraft.sweeping", + Enchantment.JavaEnchantment.DENSITY, "enchantment.minecraft.density", + Enchantment.JavaEnchantment.BREACH, "enchantment.minecraft.breach", + Enchantment.JavaEnchantment.WIND_BURST, "enchantment.minecraft.wind_burst"); + private final String javaIdentifier; private int javaId = -1; private final int stackSize; @@ -227,8 +237,10 @@ public class Item { // TODO verify // TODO streamline Enchantment process Enchantment.JavaEnchantment enchantment = Enchantment.JavaEnchantment.of(enchantId); - if (enchantment == Enchantment.JavaEnchantment.SWEEPING_EDGE) { - addSweeping(session, builder, level); + String translationKey = ENCHANTMENT_TRANSLATION_KEYS.get(enchantment); + if (translationKey != null) { + String enchantmentTranslation = MinecraftLocale.getLocaleString(translationKey, session.locale()); + addJavaOnlyEnchantment(session, builder, enchantmentTranslation, level); return null; } if (enchantment == null) { @@ -242,11 +254,10 @@ public class Item { .build(); } - private void addSweeping(GeyserSession session, BedrockItemBuilder builder, int level) { - String sweepingTranslation = MinecraftLocale.getLocaleString("enchantment.minecraft.sweeping", session.locale()); + private void addJavaOnlyEnchantment(GeyserSession session, BedrockItemBuilder builder, String enchantmentName, int level) { String lvlTranslation = MinecraftLocale.getLocaleString("enchantment.level." + level, session.locale()); - builder.getOrCreateLore().add(ChatColor.RESET + ChatColor.GRAY + sweepingTranslation + " " + lvlTranslation); + builder.getOrCreateLore().add(ChatColor.RESET + ChatColor.GRAY + enchantmentName + " " + lvlTranslation); } /* Translation methods end */ From 86dafbc108fbc86a5d100b84804321a30f438883 Mon Sep 17 00:00:00 2001 From: chris Date: Sun, 12 May 2024 10:49:08 +0200 Subject: [PATCH 160/272] Ensure we load mod resources correctly on Geyser-NeoForge (#4651) * correctly load jar resource files on neoforge * also add support for neoforge-floodgate --- bootstrap/mod/neoforge/build.gradle.kts | 4 ++- .../neoforge/GeyserNeoForgeBootstrap.java | 5 ++-- .../neoforge/GeyserNeoForgePlatform.java | 25 ++++++++++++++++--- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/bootstrap/mod/neoforge/build.gradle.kts b/bootstrap/mod/neoforge/build.gradle.kts index ff77bcc5c..92ffae7e5 100644 --- a/bootstrap/mod/neoforge/build.gradle.kts +++ b/bootstrap/mod/neoforge/build.gradle.kts @@ -31,7 +31,9 @@ dependencies { // Let's shade in our own api shadow(projects.api) { isTransitive = false } - shadow(projects.common) { isTransitive = false } + + // cannot be shaded, since neoforge will complain if floodgate-neoforge tries to provide this + include(projects.common) // Include all transitive deps of core via JiJ includeTransitive(projects.core) diff --git a/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeBootstrap.java b/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeBootstrap.java index 1655dea91..b97e42389 100644 --- a/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeBootstrap.java +++ b/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeBootstrap.java @@ -27,6 +27,7 @@ package org.geysermc.geyser.platform.neoforge; import net.minecraft.commands.CommandSourceStack; import net.minecraft.world.entity.player.Player; +import net.neoforged.fml.ModContainer; import net.neoforged.fml.common.Mod; import net.neoforged.fml.loading.FMLLoader; import net.neoforged.neoforge.common.NeoForge; @@ -43,8 +44,8 @@ public class GeyserNeoForgeBootstrap extends GeyserModBootstrap { private final GeyserNeoForgePermissionHandler permissionHandler = new GeyserNeoForgePermissionHandler(); - public GeyserNeoForgeBootstrap() { - super(new GeyserNeoForgePlatform()); + public GeyserNeoForgeBootstrap(ModContainer container) { + super(new GeyserNeoForgePlatform(container)); if (isServer()) { // Set as an event so we can get the proper IP and port if needed diff --git a/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgePlatform.java b/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgePlatform.java index 63abe4a4a..41562baf3 100644 --- a/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgePlatform.java +++ b/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgePlatform.java @@ -26,20 +26,29 @@ package org.geysermc.geyser.platform.neoforge; import net.minecraft.server.MinecraftServer; +import net.neoforged.fml.ModContainer; +import net.neoforged.fml.ModList; import net.neoforged.fml.loading.FMLPaths; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; -import org.geysermc.geyser.GeyserBootstrap; import org.geysermc.geyser.api.util.PlatformType; import org.geysermc.geyser.dump.BootstrapDumpInfo; import org.geysermc.geyser.platform.mod.GeyserModBootstrap; import org.geysermc.geyser.platform.mod.platform.GeyserModPlatform; +import java.io.IOException; import java.io.InputStream; +import java.nio.file.Files; import java.nio.file.Path; public class GeyserNeoForgePlatform implements GeyserModPlatform { + private final ModContainer container; + + public GeyserNeoForgePlatform(ModContainer container) { + this.container = container; + } + @Override public @NonNull PlatformType platformType() { return PlatformType.NEOFORGE; @@ -62,11 +71,21 @@ public class GeyserNeoForgePlatform implements GeyserModPlatform { @Override public boolean testFloodgatePluginPresent(@NonNull GeyserModBootstrap bootstrap) { - return false; // No Floodgate mod for NeoForge yet + if (ModList.get().isLoaded("floodgate")) { + Path floodgateDataFolder = FMLPaths.CONFIGDIR.get().resolve("floodgate"); + bootstrap.getGeyserConfig().loadFloodgate(bootstrap, floodgateDataFolder); + return true; + } + return false; } @Override public @Nullable InputStream resolveResource(@NonNull String resource) { - return GeyserBootstrap.class.getClassLoader().getResourceAsStream(resource); + try { + Path path = container.getModInfo().getOwningFile().getFile().findResource(resource); + return Files.newInputStream(path); + } catch (IOException e) { + return null; + } } } From b11a6d7176bb046dbc0b91a8d2faf251342978e5 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Tue, 14 May 2024 13:22:54 +0100 Subject: [PATCH 161/272] Remove unofficial skin sources and add skin event for extensions (#4507) * Remove ears and unoffical skin sources * Remove supplyEars * Cleanup and add SkinApplyEvent * Add failed back to skin * Accept suggestion on SkinGeometry Co-authored-by: chris * Add javadoc and update copyright * Remove old config options * Make SkinApplyEvent a ConnectionEvent * Add warning about third-party config options * Update warning message * Add javadoc to event * Fix javadoc * Ajust for review and bump version to 2.2.4 * Get rid of array and preserve original skin data * Add originalSkin method to event * Handle NonNull in SessionSkinApplyEvent * Revert default copyright change --------- Co-authored-by: chris --- .idea/copyright/Geyser.xml | 3 +- .../event/bedrock/SessionSkinApplyEvent.java | 144 +++++++ .../org/geysermc/geyser/api/skin/Cape.java | 40 ++ .../org/geysermc/geyser/api/skin/Skin.java | 39 ++ .../geysermc/geyser/api/skin/SkinData.java | 32 ++ .../geyser/api/skin/SkinGeometry.java | 48 +++ .../configuration/GeyserConfiguration.java | 4 +- .../geyser/pack/SkullResourcePackManager.java | 4 +- .../geyser/skin/FakeHeadProvider.java | 36 +- .../geysermc/geyser/skin/ProvidedSkins.java | 9 +- .../org/geysermc/geyser/skin/SkinManager.java | 42 +- .../geysermc/geyser/skin/SkinProvider.java | 406 ++++-------------- .../geyser/skin/SkullSkinManager.java | 14 +- .../bedrock/skin/geometry.humanoid.ears.json | 249 ----------- .../skin/geometry.humanoid.earsSlim.json | 249 ----------- core/src/main/resources/config.yml | 8 - gradle.properties | 2 +- 17 files changed, 444 insertions(+), 885 deletions(-) create mode 100644 api/src/main/java/org/geysermc/geyser/api/event/bedrock/SessionSkinApplyEvent.java create mode 100644 api/src/main/java/org/geysermc/geyser/api/skin/Cape.java create mode 100644 api/src/main/java/org/geysermc/geyser/api/skin/Skin.java create mode 100644 api/src/main/java/org/geysermc/geyser/api/skin/SkinData.java create mode 100644 api/src/main/java/org/geysermc/geyser/api/skin/SkinGeometry.java delete mode 100644 core/src/main/resources/bedrock/skin/geometry.humanoid.ears.json delete mode 100644 core/src/main/resources/bedrock/skin/geometry.humanoid.earsSlim.json diff --git a/.idea/copyright/Geyser.xml b/.idea/copyright/Geyser.xml index c6b553aaf..758c31cbd 100644 --- a/.idea/copyright/Geyser.xml +++ b/.idea/copyright/Geyser.xml @@ -1,6 +1,7 @@ - \ No newline at end of file diff --git a/api/src/main/java/org/geysermc/geyser/api/event/bedrock/SessionSkinApplyEvent.java b/api/src/main/java/org/geysermc/geyser/api/event/bedrock/SessionSkinApplyEvent.java new file mode 100644 index 000000000..f22241e41 --- /dev/null +++ b/api/src/main/java/org/geysermc/geyser/api/event/bedrock/SessionSkinApplyEvent.java @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.api.event.bedrock; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.geysermc.geyser.api.connection.GeyserConnection; +import org.geysermc.geyser.api.event.connection.ConnectionEvent; +import org.geysermc.geyser.api.skin.Cape; +import org.geysermc.geyser.api.skin.Skin; +import org.geysermc.geyser.api.skin.SkinData; +import org.geysermc.geyser.api.skin.SkinGeometry; + +import java.util.UUID; + +/** + * Called when a skin is applied to a player. + *

+ * Won't be called when a fake player is spawned for a player skull. + */ +public abstract class SessionSkinApplyEvent extends ConnectionEvent { + + private final String username; + private final UUID uuid; + private final boolean slim; + private final boolean bedrock; + private final SkinData originalSkinData; + + public SessionSkinApplyEvent(@NonNull GeyserConnection connection, String username, UUID uuid, boolean slim, boolean bedrock, SkinData skinData) { + super(connection); + this.username = username; + this.uuid = uuid; + this.slim = slim; + this.bedrock = bedrock; + this.originalSkinData = skinData; + } + + /** + * The username of the player. + * + * @return the username of the player + */ + public @NonNull String username() { + return username; + } + + /** + * The UUID of the player. + * + * @return the UUID of the player + */ + public @NonNull UUID uuid() { + return uuid; + } + + /** + * If the player is using a slim model. + * + * @return if the player is using a slim model + */ + public boolean slim() { + return slim; + } + + /** + * If the player is a Bedrock player. + * + * @return if the player is a Bedrock player + */ + public boolean bedrock() { + return bedrock; + } + + /** + * The original skin data of the player. + * + * @return the original skin data of the player + */ + public @NonNull SkinData originalSkin() { + return originalSkinData; + } + + /** + * The skin data of the player. + * + * @return the current skin data of the player + */ + public abstract @NonNull SkinData skinData(); + + /** + * Change the skin of the player. + * + * @param newSkin the new skin + */ + public abstract void skin(@NonNull Skin newSkin); + + /** + * Change the cape of the player. + * + * @param newCape the new cape + */ + public abstract void cape(@NonNull Cape newCape); + + /** + * Change the geometry of the player. + * + * @param newGeometry the new geometry + */ + public abstract void geometry(@NonNull SkinGeometry newGeometry); + + /** + * Change the geometry of the player. + *

+ * Constructs a generic {@link SkinGeometry} object with the given data. + * + * @param geometryName the name of the geometry + * @param geometryData the data of the geometry + */ + public void geometry(@NonNull String geometryName, @NonNull String geometryData) { + geometry(new SkinGeometry("{\"geometry\" :{\"default\" :\"" + geometryName + "\"}}", geometryData)); + } +} diff --git a/api/src/main/java/org/geysermc/geyser/api/skin/Cape.java b/api/src/main/java/org/geysermc/geyser/api/skin/Cape.java new file mode 100644 index 000000000..1e7341ae4 --- /dev/null +++ b/api/src/main/java/org/geysermc/geyser/api/skin/Cape.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.api.skin; + +/** + * Represents a cape. + * + * @param textureUrl The URL of the cape texture + * @param capeId The ID of the cape + * @param capeData The raw cape image data in ARGB format + * @param failed If the cape failed to load, this is for things like fallback capes + */ +public record Cape(String textureUrl, String capeId, byte[] capeData, boolean failed) { + public Cape(String textureUrl, String capeId, byte[] capeData) { + this(textureUrl, capeId, capeData, false); + } +} diff --git a/api/src/main/java/org/geysermc/geyser/api/skin/Skin.java b/api/src/main/java/org/geysermc/geyser/api/skin/Skin.java new file mode 100644 index 000000000..9b39ddfe8 --- /dev/null +++ b/api/src/main/java/org/geysermc/geyser/api/skin/Skin.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.api.skin; + +/** + * Represents a skin. + * + * @param textureUrl The URL/ID of the skin texture + * @param skinData The raw skin image data in ARGB + * @param failed If the skin failed to load, this is for things like fallback skins + */ +public record Skin(String textureUrl, byte[] skinData, boolean failed) { + public Skin(String textureUrl, byte[] skinData) { + this(textureUrl, skinData, false); + } +} diff --git a/api/src/main/java/org/geysermc/geyser/api/skin/SkinData.java b/api/src/main/java/org/geysermc/geyser/api/skin/SkinData.java new file mode 100644 index 000000000..9de4a3534 --- /dev/null +++ b/api/src/main/java/org/geysermc/geyser/api/skin/SkinData.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.api.skin; + +/** + * Represents a full package of {@link Skin}, {@link Cape}, and {@link SkinGeometry}. + */ +public record SkinData(Skin skin, Cape cape, SkinGeometry geometry) { +} diff --git a/api/src/main/java/org/geysermc/geyser/api/skin/SkinGeometry.java b/api/src/main/java/org/geysermc/geyser/api/skin/SkinGeometry.java new file mode 100644 index 000000000..5b40d2022 --- /dev/null +++ b/api/src/main/java/org/geysermc/geyser/api/skin/SkinGeometry.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.api.skin; + +/** + * Represents geometry of a skin. + * + * @param geometryName The name of the geometry (JSON) + * @param geometryData The geometry data (JSON) + */ +public record SkinGeometry(String geometryName, String geometryData) { + + public static SkinGeometry WIDE = getLegacy(false); + public static SkinGeometry SLIM = getLegacy(true); + + /** + * Generate generic geometry + * + * @param isSlim if true, it will be the slimmer alex model + * @return The generic geometry object + */ + private static SkinGeometry getLegacy(boolean isSlim) { + return new SkinGeometry("{\"geometry\" :{\"default\" :\"geometry.humanoid.custom" + (isSlim ? "Slim" : "") + "\"}}", ""); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/configuration/GeyserConfiguration.java b/core/src/main/java/org/geysermc/geyser/configuration/GeyserConfiguration.java index d12ab79e9..88bb98171 100644 --- a/core/src/main/java/org/geysermc/geyser/configuration/GeyserConfiguration.java +++ b/core/src/main/java/org/geysermc/geyser/configuration/GeyserConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -72,8 +72,10 @@ public interface GeyserConfiguration { boolean isDebugMode(); + @Deprecated boolean isAllowThirdPartyCapes(); + @Deprecated boolean isAllowThirdPartyEars(); String getShowCooldown(); diff --git a/core/src/main/java/org/geysermc/geyser/pack/SkullResourcePackManager.java b/core/src/main/java/org/geysermc/geyser/pack/SkullResourcePackManager.java index f0faa4244..59651d139 100644 --- a/core/src/main/java/org/geysermc/geyser/pack/SkullResourcePackManager.java +++ b/core/src/main/java/org/geysermc/geyser/pack/SkullResourcePackManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -118,7 +118,7 @@ public class SkullResourcePackManager { return; } - BufferedImage image = SkinProvider.requestImage(skinUrl, null); + BufferedImage image = SkinProvider.requestImage(skinUrl, false); // Resize skins to 48x16 to save on space and memory BufferedImage skullTexture = new BufferedImage(48, 16, image.getType()); // Reorder skin parts to fit into the space diff --git a/core/src/main/java/org/geysermc/geyser/skin/FakeHeadProvider.java b/core/src/main/java/org/geysermc/geyser/skin/FakeHeadProvider.java index d2a45b614..ef3ff3293 100644 --- a/core/src/main/java/org/geysermc/geyser/skin/FakeHeadProvider.java +++ b/core/src/main/java/org/geysermc/geyser/skin/FakeHeadProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,6 +38,10 @@ import lombok.Getter; import lombok.Setter; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.api.skin.Cape; +import org.geysermc.geyser.api.skin.Skin; +import org.geysermc.geyser.api.skin.SkinData; +import org.geysermc.geyser.api.skin.SkinGeometry; import org.geysermc.geyser.entity.type.LivingEntity; import org.geysermc.geyser.entity.type.player.PlayerEntity; import org.geysermc.geyser.session.GeyserSession; @@ -59,27 +63,27 @@ import java.util.concurrent.TimeUnit; * Responsible for modifying a player's skin when wearing a player head */ public class FakeHeadProvider { - private static final LoadingCache MERGED_SKINS_LOADING_CACHE = CacheBuilder.newBuilder() + private static final LoadingCache MERGED_SKINS_LOADING_CACHE = CacheBuilder.newBuilder() .expireAfterAccess(1, TimeUnit.HOURS) .maximumSize(10000) .build(new CacheLoader<>() { @Override - public SkinProvider.SkinData load(@NonNull FakeHeadEntry fakeHeadEntry) throws Exception { - SkinProvider.SkinData skinData = SkinProvider.getOrDefault(SkinProvider.requestSkinData(fakeHeadEntry.getEntity()), null, 5); + public SkinData load(@NonNull FakeHeadEntry fakeHeadEntry) throws Exception { + SkinData skinData = SkinProvider.getOrDefault(SkinProvider.requestSkinData(fakeHeadEntry.getEntity(), fakeHeadEntry.getSession()), null, 5); if (skinData == null) { throw new Exception("Couldn't load player's original skin"); } - SkinProvider.Skin skin = skinData.skin(); - SkinProvider.Cape cape = skinData.cape(); - SkinProvider.SkinGeometry geometry = skinData.geometry().geometryName().equals("{\"geometry\" :{\"default\" :\"geometry.humanoid.customSlim\"}}") + Skin skin = skinData.skin(); + Cape cape = skinData.cape(); + SkinGeometry geometry = skinData.geometry().geometryName().equals("{\"geometry\" :{\"default\" :\"geometry.humanoid.customSlim\"}}") ? SkinProvider.WEARING_CUSTOM_SKULL_SLIM : SkinProvider.WEARING_CUSTOM_SKULL; - SkinProvider.Skin headSkin = SkinProvider.getOrDefault( + Skin headSkin = SkinProvider.getOrDefault( SkinProvider.requestSkin(fakeHeadEntry.getEntity().getUuid(), fakeHeadEntry.getFakeHeadSkinUrl(), false), SkinProvider.EMPTY_SKIN, 5); - BufferedImage originalSkinImage = SkinProvider.imageDataToBufferedImage(skin.getSkinData(), 64, skin.getSkinData().length / 4 / 64); - BufferedImage headSkinImage = SkinProvider.imageDataToBufferedImage(headSkin.getSkinData(), 64, headSkin.getSkinData().length / 4 / 64); + BufferedImage originalSkinImage = SkinProvider.imageDataToBufferedImage(skin.skinData(), 64, skin.skinData().length / 4 / 64); + BufferedImage headSkinImage = SkinProvider.imageDataToBufferedImage(headSkin.skinData(), 64, headSkin.skinData().length / 4 / 64); Graphics2D graphics2D = originalSkinImage.createGraphics(); graphics2D.setComposite(AlphaComposite.Clear); @@ -90,14 +94,15 @@ public class FakeHeadProvider { // Make the skin key a combination of the current skin data and the new skin data // Don't tie it to a player - that player *can* change skins in-game - String skinKey = "customPlayerHead_" + fakeHeadEntry.getFakeHeadSkinUrl() + "_" + skin.getTextureUrl(); + String skinKey = "customPlayerHead_" + fakeHeadEntry.getFakeHeadSkinUrl() + "_" + skin.textureUrl(); byte[] targetSkinData = SkinProvider.bufferedImageToImageData(originalSkinImage); - SkinProvider.Skin mergedSkin = new SkinProvider.Skin(fakeHeadEntry.getEntity().getUuid(), skinKey, targetSkinData, System.currentTimeMillis(), false, false); + Skin mergedSkin = new Skin(skinKey, targetSkinData); // Avoiding memory leak fakeHeadEntry.setEntity(null); + fakeHeadEntry.setSession(null); - return new SkinProvider.SkinData(mergedSkin, cape, geometry); + return new SkinData(mergedSkin, cape, geometry); } }); @@ -164,7 +169,7 @@ public class FakeHeadProvider { String texturesProperty = entity.getTexturesProperty(); SkinProvider.getExecutorService().execute(() -> { try { - SkinProvider.SkinData mergedSkinData = MERGED_SKINS_LOADING_CACHE.get(new FakeHeadEntry(texturesProperty, fakeHeadSkinUrl, entity)); + SkinData mergedSkinData = MERGED_SKINS_LOADING_CACHE.get(new FakeHeadEntry(texturesProperty, fakeHeadSkinUrl, entity, session)); SkinManager.sendSkinPacket(session, entity, mergedSkinData); } catch (ExecutionException e) { GeyserImpl.getInstance().getLogger().error("Couldn't merge skin of " + entity.getUsername() + " with head skin url " + fakeHeadSkinUrl, e); @@ -181,7 +186,7 @@ public class FakeHeadProvider { return; } - SkinProvider.requestSkinData(entity).whenCompleteAsync((skinData, throwable) -> { + SkinProvider.requestSkinData(entity, session).whenCompleteAsync((skinData, throwable) -> { if (throwable != null) { GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.skin.fail", entity.getUuid()), throwable); return; @@ -198,6 +203,7 @@ public class FakeHeadProvider { private final String texturesProperty; private final String fakeHeadSkinUrl; private PlayerEntity entity; + private GeyserSession session; @Override public boolean equals(Object o) { diff --git a/core/src/main/java/org/geysermc/geyser/skin/ProvidedSkins.java b/core/src/main/java/org/geysermc/geyser/skin/ProvidedSkins.java index 58c8f0072..ba74fbb42 100644 --- a/core/src/main/java/org/geysermc/geyser/skin/ProvidedSkins.java +++ b/core/src/main/java/org/geysermc/geyser/skin/ProvidedSkins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,6 +26,7 @@ package org.geysermc.geyser.skin; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.api.skin.Skin; import org.geysermc.geyser.util.AssetUtils; import javax.imageio.ImageIO; @@ -67,7 +68,7 @@ public final class ProvidedSkins { } public static final class ProvidedSkin { - private SkinProvider.Skin data; + private Skin data; private final boolean slim; ProvidedSkin(String asset, boolean slim) { @@ -94,14 +95,14 @@ public final class ProvidedSkins { image.flush(); String identifier = "geysermc:" + assetName + "_" + (slim ? "slim" : "wide"); - this.data = new SkinProvider.Skin(-1, identifier, byteData); + this.data = new Skin(identifier, byteData, true); } catch (IOException e) { e.printStackTrace(); } })); } - public SkinProvider.Skin getData() { + public Skin getData() { // Fall back to the default skin if we can't load our skins, or it's not loaded yet. return Objects.requireNonNullElse(data, SkinProvider.EMPTY_SKIN); } diff --git a/core/src/main/java/org/geysermc/geyser/skin/SkinManager.java b/core/src/main/java/org/geysermc/geyser/skin/SkinManager.java index 4f3a94688..7b126c136 100644 --- a/core/src/main/java/org/geysermc/geyser/skin/SkinManager.java +++ b/core/src/main/java/org/geysermc/geyser/skin/SkinManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -34,6 +34,10 @@ import org.cloudburstmc.protocol.bedrock.data.skin.SerializedSkin; import org.cloudburstmc.protocol.bedrock.packet.PlayerListPacket; import org.cloudburstmc.protocol.bedrock.packet.PlayerSkinPacket; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.api.skin.Cape; +import org.geysermc.geyser.api.skin.Skin; +import org.geysermc.geyser.api.skin.SkinData; +import org.geysermc.geyser.api.skin.SkinGeometry; import org.geysermc.geyser.entity.type.player.PlayerEntity; import org.geysermc.geyser.entity.type.player.SkullPlayerEntity; import org.geysermc.geyser.session.GeyserSession; @@ -56,21 +60,21 @@ public class SkinManager { public static PlayerListPacket.Entry buildCachedEntry(GeyserSession session, PlayerEntity playerEntity) { // First: see if we have the cached skin texture ID. GameProfileData data = GameProfileData.from(playerEntity); - SkinProvider.Skin skin = null; - SkinProvider.Cape cape = null; - SkinProvider.SkinGeometry geometry = SkinProvider.SkinGeometry.WIDE; + Skin skin = null; + Cape cape = null; + SkinGeometry geometry = SkinGeometry.WIDE; if (data != null) { // GameProfileData is not null = server provided us with textures data to work with. skin = SkinProvider.getCachedSkin(data.skinUrl()); cape = SkinProvider.getCachedCape(data.capeUrl()); - geometry = data.isAlex() ? SkinProvider.SkinGeometry.SLIM : SkinProvider.SkinGeometry.WIDE; + geometry = data.isAlex() ? SkinGeometry.SLIM : SkinGeometry.WIDE; } if (skin == null || cape == null) { // The server either didn't have a texture to send, or we didn't have the texture ID cached. // Let's see if this player is a Bedrock player, and if so, let's pull their skin. // Otherwise, grab the default player skin - SkinProvider.SkinData fallbackSkinData = SkinProvider.determineFallbackSkinData(playerEntity.getUuid()); + SkinData fallbackSkinData = SkinProvider.determineFallbackSkinData(playerEntity.getUuid()); if (skin == null) { skin = fallbackSkinData.skin(); geometry = fallbackSkinData.geometry(); @@ -95,10 +99,10 @@ public class SkinManager { * With all the information needed, build a Bedrock player entry with translated skin information. */ public static PlayerListPacket.Entry buildEntryManually(GeyserSession session, UUID uuid, String username, long geyserId, - SkinProvider.Skin skin, - SkinProvider.Cape cape, - SkinProvider.SkinGeometry geometry) { - SerializedSkin serializedSkin = getSkin(skin.getTextureUrl(), skin, cape, geometry); + Skin skin, + Cape cape, + SkinGeometry geometry) { + SerializedSkin serializedSkin = getSkin(skin.textureUrl(), skin, cape, geometry); // This attempts to find the XUID of the player so profile images show up for Xbox accounts String xuid = ""; @@ -128,10 +132,10 @@ public class SkinManager { return entry; } - public static void sendSkinPacket(GeyserSession session, PlayerEntity entity, SkinProvider.SkinData skinData) { - SkinProvider.Skin skin = skinData.skin(); - SkinProvider.Cape cape = skinData.cape(); - SkinProvider.SkinGeometry geometry = skinData.geometry(); + public static void sendSkinPacket(GeyserSession session, PlayerEntity entity, SkinData skinData) { + Skin skin = skinData.skin(); + Cape cape = skinData.cape(); + SkinGeometry geometry = skinData.geometry(); if (entity.getUuid().equals(session.getPlayerEntity().getUuid())) { // TODO is this special behavior needed? @@ -153,23 +157,23 @@ public class SkinManager { PlayerSkinPacket packet = new PlayerSkinPacket(); packet.setUuid(entity.getUuid()); packet.setOldSkinName(""); - packet.setNewSkinName(skin.getTextureUrl()); - packet.setSkin(getSkin(skin.getTextureUrl(), skin, cape, geometry)); + packet.setNewSkinName(skin.textureUrl()); + packet.setSkin(getSkin(skin.textureUrl(), skin, cape, geometry)); packet.setTrustedSkin(true); session.sendUpstreamPacket(packet); } } - private static SerializedSkin getSkin(String skinId, SkinProvider.Skin skin, SkinProvider.Cape cape, SkinProvider.SkinGeometry geometry) { + private static SerializedSkin getSkin(String skinId, Skin skin, Cape cape, SkinGeometry geometry) { return SerializedSkin.of(skinId, "", geometry.geometryName(), - ImageData.of(skin.getSkinData()), Collections.emptyList(), + ImageData.of(skin.skinData()), Collections.emptyList(), ImageData.of(cape.capeData()), geometry.geometryData(), "", true, false, false, cape.capeId(), skinId); } public static void requestAndHandleSkinAndCape(PlayerEntity entity, GeyserSession session, Consumer skinAndCapeConsumer) { - SkinProvider.requestSkinData(entity).whenCompleteAsync((skinData, throwable) -> { + SkinProvider.requestSkinData(entity, session).whenCompleteAsync((skinData, throwable) -> { if (skinData == null) { if (skinAndCapeConsumer != null) { skinAndCapeConsumer.accept(null); diff --git a/core/src/main/java/org/geysermc/geyser/skin/SkinProvider.java b/core/src/main/java/org/geysermc/geyser/skin/SkinProvider.java index 683712c22..3b31dfff8 100644 --- a/core/src/main/java/org/geysermc/geyser/skin/SkinProvider.java +++ b/core/src/main/java/org/geysermc/geyser/skin/SkinProvider.java @@ -35,7 +35,12 @@ import lombok.NoArgsConstructor; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.api.event.bedrock.SessionSkinApplyEvent; import org.geysermc.geyser.api.network.AuthType; +import org.geysermc.geyser.api.skin.Cape; +import org.geysermc.geyser.api.skin.Skin; +import org.geysermc.geyser.api.skin.SkinData; +import org.geysermc.geyser.api.skin.SkinGeometry; import org.geysermc.geyser.entity.type.player.PlayerEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.GeyserLocale; @@ -45,7 +50,6 @@ import org.geysermc.geyser.util.WebUtils; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; @@ -57,11 +61,10 @@ import java.util.concurrent.*; import java.util.function.Predicate; public class SkinProvider { - private static final boolean ALLOW_THIRD_PARTY_CAPES = GeyserImpl.getInstance().getConfig().isAllowThirdPartyCapes(); private static ExecutorService EXECUTOR_SERVICE; static final Skin EMPTY_SKIN; - static final Cape EMPTY_CAPE = new Cape("", "no-cape", ByteArrays.EMPTY_ARRAY, -1, true); + static final Cape EMPTY_CAPE = new Cape("", "no-cape", ByteArrays.EMPTY_ARRAY, true); private static final Cache CACHED_JAVA_CAPES = CacheBuilder.newBuilder() .expireAfterAccess(1, TimeUnit.HOURS) @@ -88,9 +91,6 @@ public class SkinProvider { */ private static final Predicate IS_NPC = uuid -> uuid.version() == 2; - private static final boolean ALLOW_THIRD_PARTY_EARS = GeyserImpl.getInstance().getConfig().isAllowThirdPartyEars(); - private static final String EARS_GEOMETRY; - private static final String EARS_GEOMETRY_SLIM; static final SkinGeometry SKULL_GEOMETRY; static final SkinGeometry WEARING_CUSTOM_SKULL; static final SkinGeometry WEARING_CUSTOM_SKULL_SLIM; @@ -114,28 +114,27 @@ public class SkinProvider { outputStream.write((rgba >> 24) & 0xFF); // Alpha } } - EMPTY_SKIN = new Skin(-1, "geysermc:empty", outputStream.toByteArray()); - - /* Load in the normal ears geometry */ - EARS_GEOMETRY = new String(FileUtils.readAllBytes("bedrock/skin/geometry.humanoid.ears.json"), StandardCharsets.UTF_8); - - /* Load in the slim ears geometry */ - EARS_GEOMETRY_SLIM = new String(FileUtils.readAllBytes("bedrock/skin/geometry.humanoid.earsSlim.json"), StandardCharsets.UTF_8); + EMPTY_SKIN = new Skin("geysermc:empty", outputStream.toByteArray(), true); /* Load in the custom skull geometry */ String skullData = new String(FileUtils.readAllBytes("bedrock/skin/geometry.humanoid.customskull.json"), StandardCharsets.UTF_8); - SKULL_GEOMETRY = new SkinGeometry("{\"geometry\" :{\"default\" :\"geometry.humanoid.customskull\"}}", skullData, false); + SKULL_GEOMETRY = new SkinGeometry("{\"geometry\" :{\"default\" :\"geometry.humanoid.customskull\"}}", skullData); /* Load in the player head skull geometry */ String wearingCustomSkull = new String(FileUtils.readAllBytes("bedrock/skin/geometry.humanoid.wearingCustomSkull.json"), StandardCharsets.UTF_8); - WEARING_CUSTOM_SKULL = new SkinGeometry("{\"geometry\" :{\"default\" :\"geometry.humanoid.wearingCustomSkull\"}}", wearingCustomSkull, false); + WEARING_CUSTOM_SKULL = new SkinGeometry("{\"geometry\" :{\"default\" :\"geometry.humanoid.wearingCustomSkull\"}}", wearingCustomSkull); String wearingCustomSkullSlim = new String(FileUtils.readAllBytes("bedrock/skin/geometry.humanoid.wearingCustomSkullSlim.json"), StandardCharsets.UTF_8); - WEARING_CUSTOM_SKULL_SLIM = new SkinGeometry("{\"geometry\" :{\"default\" :\"geometry.humanoid.wearingCustomSkullSlim\"}}", wearingCustomSkullSlim, false); + WEARING_CUSTOM_SKULL_SLIM = new SkinGeometry("{\"geometry\" :{\"default\" :\"geometry.humanoid.wearingCustomSkullSlim\"}}", wearingCustomSkullSlim); + + GeyserImpl geyser = GeyserImpl.getInstance(); + if (geyser.getConfig().isAllowThirdPartyEars() || geyser.getConfig().isAllowThirdPartyCapes()) { + geyser.getLogger().warning("Third-party ears/capes have been removed from Geyser, if you still wish to have this functionality please use the extension: https://github.com/GeyserMC/ThirdPartyCosmetics"); + } } public static ExecutorService getExecutorService() { if (EXECUTOR_SERVICE == null) { - EXECUTOR_SERVICE = Executors.newFixedThreadPool(ALLOW_THIRD_PARTY_CAPES ? 21 : 14); + EXECUTOR_SERVICE = Executors.newFixedThreadPool(14); } return EXECUTOR_SERVICE; } @@ -204,7 +203,7 @@ public class SkinProvider { // We don't have a skin for the player right now. Fall back to a default. ProvidedSkins.ProvidedSkin providedSkin = ProvidedSkins.getDefaultPlayerSkin(uuid); skin = providedSkin.getData(); - geometry = providedSkin.isSlim() ? SkinProvider.SkinGeometry.SLIM : SkinProvider.SkinGeometry.WIDE; + geometry = providedSkin.isSlim() ? SkinGeometry.SLIM : SkinGeometry.WIDE; } if (cape == null) { @@ -238,7 +237,7 @@ public class SkinProvider { return CACHED_JAVA_CAPES.getIfPresent(capeUrl); } - static CompletableFuture requestSkinData(PlayerEntity entity) { + static CompletableFuture requestSkinData(PlayerEntity entity, GeyserSession session) { SkinManager.GameProfileData data = SkinManager.GameProfileData.from(entity); if (data == null) { // This player likely does not have a textures property @@ -260,42 +259,33 @@ public class SkinProvider { cape = getCachedBedrockCape(entity.getUuid()); } - if (cape.failed() && ALLOW_THIRD_PARTY_CAPES) { - cape = getOrDefault(requestUnofficialCape( - cape, entity.getUuid(), - entity.getUsername(), false - ), EMPTY_CAPE, CapeProvider.VALUES.length * 3); - } - - boolean isDeadmau5 = "deadmau5".equals(entity.getUsername()); - // Not a bedrock player check for ears - if (geometry.failed() && (ALLOW_THIRD_PARTY_EARS || isDeadmau5)) { - boolean isEars; - - // Its deadmau5, gotta support his skin :) - if (isDeadmau5) { - isEars = true; - } else { - // Get the ears texture for the player - skin = getOrDefault(requestUnofficialEars( - skin, entity.getUuid(), entity.getUsername(), false - ), skin, 3); - - isEars = skin.isEars(); + // Call event to allow extensions to modify the skin, cape and geo + boolean isBedrock = GeyserImpl.getInstance().connectionByUuid(entity.getUuid()) != null; + SkinData skinData = new SkinData(skin, cape, geometry); + final EventSkinData eventSkinData = new EventSkinData(skinData); + GeyserImpl.getInstance().eventBus().fire(new SessionSkinApplyEvent(session, entity.getUsername(), entity.getUuid(), data.isAlex(), isBedrock, skinData) { + @Override + public SkinData skinData() { + return eventSkinData.skinData(); } - // Does the skin have an ears texture - if (isEars) { - // Get the new geometry - geometry = SkinGeometry.getEars(data.isAlex()); - - // Store the skin and geometry for the ears - storeEarSkin(skin); - storeEarGeometry(entity.getUuid(), data.isAlex()); + @Override + public void skin(@NonNull Skin newSkin) { + eventSkinData.skinData(new SkinData(Objects.requireNonNull(newSkin), skinData.cape(), skinData.geometry())); } - } - return new SkinData(skin, cape, geometry); + @Override + public void cape(@NonNull Cape newCape) { + eventSkinData.skinData(new SkinData(skinData.skin(), Objects.requireNonNull(newCape), skinData.geometry())); + } + + @Override + public void geometry(@NonNull SkinGeometry newGeometry) { + eventSkinData.skinData(new SkinData(skinData.skin(), skinData.cape(), Objects.requireNonNull(newGeometry))); + } + }); + + return eventSkinData.skinData(); } catch (Exception e) { GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.skin.fail", entity.getUuid()), e); } @@ -308,10 +298,9 @@ public class SkinProvider { return CompletableFuture.supplyAsync(() -> { long time = System.currentTimeMillis(); - CapeProvider provider = capeUrl != null ? CapeProvider.MINECRAFT : null; SkinAndCape skinAndCape = new SkinAndCape( getOrDefault(requestSkin(playerId, skinUrl, false), EMPTY_SKIN, 5), - getOrDefault(requestCape(capeUrl, provider, false), EMPTY_CAPE, 5) + getOrDefault(requestCape(capeUrl, false), EMPTY_CAPE, 5) ); GeyserImpl.getInstance().getLogger().debug("Took " + (System.currentTimeMillis() - time) + "ms for " + playerId); @@ -336,7 +325,6 @@ public class SkinProvider { if (newThread) { future = CompletableFuture.supplyAsync(() -> supplySkin(playerId, textureUrl), getExecutorService()) .whenCompleteAsync((skin, throwable) -> { - skin.updated = true; CACHED_JAVA_SKINS.put(textureUrl, skin); requestedSkins.remove(textureUrl); }); @@ -349,7 +337,7 @@ public class SkinProvider { return future; } - private static CompletableFuture requestCape(String capeUrl, CapeProvider provider, boolean newThread) { + private static CompletableFuture requestCape(String capeUrl, boolean newThread) { if (capeUrl == null || capeUrl.isEmpty()) return CompletableFuture.completedFuture(EMPTY_CAPE); CompletableFuture requestedCape = requestedCapes.get(capeUrl); if (requestedCape != null) { @@ -363,128 +351,48 @@ public class SkinProvider { CompletableFuture future; if (newThread) { - future = CompletableFuture.supplyAsync(() -> supplyCape(capeUrl, provider), getExecutorService()) + future = CompletableFuture.supplyAsync(() -> supplyCape(capeUrl), getExecutorService()) .whenCompleteAsync((cape, throwable) -> { CACHED_JAVA_CAPES.put(capeUrl, cape); requestedCapes.remove(capeUrl); }); requestedCapes.put(capeUrl, future); } else { - Cape cape = supplyCape(capeUrl, provider); // blocking + Cape cape = supplyCape(capeUrl); // blocking future = CompletableFuture.completedFuture(cape); CACHED_JAVA_CAPES.put(capeUrl, cape); } return future; } - private static CompletableFuture requestUnofficialCape(Cape officialCape, UUID playerId, - String username, boolean newThread) { - if (officialCape.failed() && ALLOW_THIRD_PARTY_CAPES) { - for (CapeProvider provider : CapeProvider.VALUES) { - if (provider.type != CapeUrlType.USERNAME && IS_NPC.test(playerId)) { - continue; - } - - Cape cape1 = getOrDefault( - requestCape(provider.getUrlFor(playerId, username), provider, newThread), - EMPTY_CAPE, 4 - ); - if (!cape1.failed()) { - return CompletableFuture.completedFuture(cape1); - } - } - } - return CompletableFuture.completedFuture(officialCape); - } - - private static CompletableFuture requestEars(String earsUrl, boolean newThread, Skin skin) { - if (earsUrl == null || earsUrl.isEmpty()) return CompletableFuture.completedFuture(skin); - - CompletableFuture future; - if (newThread) { - future = CompletableFuture.supplyAsync(() -> supplyEars(skin, earsUrl), getExecutorService()) - .whenCompleteAsync((outSkin, throwable) -> { }); - } else { - Skin ears = supplyEars(skin, earsUrl); // blocking - future = CompletableFuture.completedFuture(ears); - } - return future; - } - - /** - * Try and find an ear texture for a Java player - * - * @param officialSkin The current players skin - * @param playerId The players UUID - * @param username The players username - * @param newThread Should we start in a new thread - * @return The updated skin with ears - */ - private static CompletableFuture requestUnofficialEars(Skin officialSkin, UUID playerId, String username, boolean newThread) { - for (EarsProvider provider : EarsProvider.VALUES) { - if (provider.type != CapeUrlType.USERNAME && IS_NPC.test(playerId)) { - continue; - } - - Skin skin1 = getOrDefault( - requestEars(provider.getUrlFor(playerId, username), newThread, officialSkin), - officialSkin, 4 - ); - if (skin1.isEars()) { - return CompletableFuture.completedFuture(skin1); - } - } - - return CompletableFuture.completedFuture(officialSkin); - } - static void storeBedrockSkin(UUID playerID, String skinId, byte[] skinData) { - Skin skin = new Skin(playerID, skinId, skinData, System.currentTimeMillis(), true, false); - CACHED_BEDROCK_SKINS.put(skin.getTextureUrl(), skin); + Skin skin = new Skin(skinId, skinData); + CACHED_BEDROCK_SKINS.put(skin.textureUrl(), skin); } static void storeBedrockCape(String capeId, byte[] capeData) { - Cape cape = new Cape(capeId, capeId, capeData, System.currentTimeMillis(), false); + Cape cape = new Cape(capeId, capeId, capeData); CACHED_BEDROCK_CAPES.put(capeId, cape); } static void storeBedrockGeometry(UUID playerID, byte[] geometryName, byte[] geometryData) { - SkinGeometry geometry = new SkinGeometry(new String(geometryName), new String(geometryData), false); + SkinGeometry geometry = new SkinGeometry(new String(geometryName), new String(geometryData)); cachedGeometry.put(playerID, geometry); } - /** - * Stores the adjusted skin with the ear texture to the cache - * - * @param skin The skin to cache - */ - public static void storeEarSkin(Skin skin) { - CACHED_JAVA_SKINS.put(skin.getTextureUrl(), skin); - } - - /** - * Stores the geometry for a Java player with ears - * - * @param playerID The UUID to cache it against - * @param isSlim If the player is using an slim base - */ - private static void storeEarGeometry(UUID playerID, boolean isSlim) { - cachedGeometry.put(playerID, SkinGeometry.getEars(isSlim)); - } - private static Skin supplySkin(UUID uuid, String textureUrl) { try { - byte[] skin = requestImageData(textureUrl, null); - return new Skin(uuid, textureUrl, skin, System.currentTimeMillis(), false, false); + byte[] skin = requestImageData(textureUrl, false); + return new Skin(textureUrl, skin); } catch (Exception ignored) {} // just ignore I guess - return new Skin(uuid, "empty", EMPTY_SKIN.getSkinData(), System.currentTimeMillis(), false, false); + return new Skin("empty", EMPTY_SKIN.skinData(), true); } - private static Cape supplyCape(String capeUrl, CapeProvider provider) { + private static Cape supplyCape(String capeUrl) { byte[] cape = EMPTY_CAPE.capeData(); try { - cape = requestImageData(capeUrl, provider); + cape = requestImageData(capeUrl, true); } catch (Exception ignored) { } // just ignore I guess @@ -494,54 +402,12 @@ public class SkinProvider { capeUrl, urlSection[urlSection.length - 1], // get the texture id and use it as cape id cape, - System.currentTimeMillis(), cape.length == 0 ); } - /** - * Get the ears texture and place it on the skin from the given URL - * - * @param existingSkin The players current skin - * @param earsUrl The URL to get the ears texture from - * @return The updated skin with ears - */ - private static Skin supplyEars(Skin existingSkin, String earsUrl) { - try { - // Get the ears texture - BufferedImage ears = ImageIO.read(new URL(earsUrl)); - if (ears == null) throw new NullPointerException(); - - // Convert the skin data to a BufferedImage - int height = (existingSkin.getSkinData().length / 4 / 64); - BufferedImage skinImage = imageDataToBufferedImage(existingSkin.getSkinData(), 64, height); - - // Create a new image with the ears texture over it - BufferedImage newSkin = new BufferedImage(skinImage.getWidth(), skinImage.getHeight(), BufferedImage.TYPE_INT_ARGB); - Graphics2D g = (Graphics2D) newSkin.getGraphics(); - g.drawImage(skinImage, 0, 0, null); - g.drawImage(ears, 24, 0, null); - - // Turn the buffered image back into an array of bytes - byte[] data = bufferedImageToImageData(newSkin); - skinImage.flush(); - - // Create a new skin object with the new infomation - return new Skin( - existingSkin.getSkinOwner(), - existingSkin.getTextureUrl(), - data, - System.currentTimeMillis(), - true, - true - ); - } catch (Exception ignored) {} // just ignore I guess - - return existingSkin; - } - @SuppressWarnings("ResultOfMethodCallIgnored") - public static BufferedImage requestImage(String imageUrl, CapeProvider provider) throws IOException { + public static BufferedImage requestImage(String imageUrl, boolean isCape) throws IOException { BufferedImage image = null; // First see if we have a cached file. We also update the modification stamp so we know when the file was last used @@ -556,7 +422,7 @@ public class SkinProvider { // If no image we download it if (image == null) { - image = downloadImage(imageUrl, provider); + image = downloadImage(imageUrl); GeyserImpl.getInstance().getLogger().debug("Downloaded " + imageUrl); // Write to cache if we are allowed @@ -572,7 +438,7 @@ public class SkinProvider { } // if the requested image is a cape - if (provider != null) { + if (isCape) { if (image.getWidth() > 64 || image.getHeight() > 32) { // Prevent weirdly-scaled capes from being cut off BufferedImage newImage = new BufferedImage(128, 64, BufferedImage.TYPE_INT_ARGB); @@ -604,8 +470,8 @@ public class SkinProvider { return image; } - private static byte[] requestImageData(String imageUrl, CapeProvider provider) throws Exception { - BufferedImage image = requestImage(imageUrl, provider); + private static byte[] requestImageData(String imageUrl, boolean isCape) throws Exception { + BufferedImage image = requestImage(imageUrl, isCape); byte[] data = bufferedImageToImageData(image); image.flush(); return data; @@ -668,35 +534,20 @@ public class SkinProvider { }); } - private static BufferedImage downloadImage(String imageUrl, CapeProvider provider) throws IOException { - BufferedImage image; - if (provider == CapeProvider.FIVEZIG) { - image = readFiveZigCape(imageUrl); - } else { - HttpURLConnection con = (HttpURLConnection) new URL(imageUrl).openConnection(); - con.setRequestProperty("User-Agent", WebUtils.getUserAgent()); - con.setConnectTimeout(10000); - con.setReadTimeout(10000); + private static BufferedImage downloadImage(String imageUrl) throws IOException { + HttpURLConnection con = (HttpURLConnection) new URL(imageUrl).openConnection(); + con.setRequestProperty("User-Agent", WebUtils.getUserAgent()); + con.setConnectTimeout(10000); + con.setReadTimeout(10000); - image = ImageIO.read(con.getInputStream()); - } + BufferedImage image = ImageIO.read(con.getInputStream()); if (image == null) { - throw new IllegalArgumentException("Failed to read image from: %s (cape provider=%s)".formatted(imageUrl, provider)); + throw new IllegalArgumentException("Failed to read image from: %s".formatted(imageUrl)); } return image; } - private static @Nullable BufferedImage readFiveZigCape(String url) throws IOException { - JsonNode element = GeyserImpl.JSON_MAPPER.readTree(WebUtils.getBody(url)); - if (element != null && element.isObject()) { - JsonNode capeElement = element.get("d"); - if (capeElement == null || capeElement.isNull()) return null; - return ImageIO.read(new ByteArrayInputStream(Base64.getDecoder().decode(capeElement.textValue()))); - } - return null; - } - public static BufferedImage scale(BufferedImage bufferedImage, int newWidth, int newHeight) { BufferedImage resized = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = resized.createGraphics(); @@ -770,124 +621,19 @@ public class SkinProvider { public record SkinAndCape(Skin skin, Cape cape) { } - /** - * Represents a full package of skin, cape, and geometry. - */ - public record SkinData(Skin skin, Cape cape, SkinGeometry geometry) { - } + public static class EventSkinData { + private SkinData skinData; - @AllArgsConstructor - @Getter - public static class Skin { - private UUID skinOwner; - private final String textureUrl; - private final byte[] skinData; - private final long requestedOn; - private boolean updated; - private boolean ears; + public EventSkinData(SkinData skinData) { + this.skinData = skinData; + } - Skin(long requestedOn, String textureUrl, byte[] skinData) { - this.requestedOn = requestedOn; - this.textureUrl = textureUrl; + public SkinData skinData() { + return skinData; + } + + public void skinData(SkinData skinData) { this.skinData = skinData; } } - - public record Cape(String textureUrl, String capeId, byte[] capeData, long requestedOn, boolean failed) { - } - - public record SkinGeometry(String geometryName, String geometryData, boolean failed) { - public static SkinGeometry WIDE = getLegacy(false); - public static SkinGeometry SLIM = getLegacy(true); - - /** - * Generate generic geometry - * - * @param isSlim Should it be the alex model - * @return The generic geometry object - */ - private static SkinGeometry getLegacy(boolean isSlim) { - return new SkinProvider.SkinGeometry("{\"geometry\" :{\"default\" :\"geometry.humanoid.custom" + (isSlim ? "Slim" : "") + "\"}}", "", true); - } - - /** - * Generate basic geometry with ears - * - * @param isSlim Should it be the alex model - * @return The generated geometry for the ears model - */ - private static SkinGeometry getEars(boolean isSlim) { - return new SkinProvider.SkinGeometry("{\"geometry\" :{\"default\" :\"geometry.humanoid.ears" + (isSlim ? "Slim" : "") + "\"}}", (isSlim ? EARS_GEOMETRY_SLIM : EARS_GEOMETRY), false); - } - } - - /* - * Sorted by 'priority' - */ - @AllArgsConstructor - @NoArgsConstructor - @Getter - public enum CapeProvider { - MINECRAFT, - OPTIFINE("https://optifine.net/capes/%s.png", CapeUrlType.USERNAME), - LABYMOD("https://dl.labymod.net/capes/%s", CapeUrlType.UUID_DASHED), - FIVEZIG("https://textures.5zigreborn.eu/profile/%s", CapeUrlType.UUID_DASHED), - MINECRAFTCAPES("https://api.minecraftcapes.net/profile/%s/cape", CapeUrlType.UUID); - - public static final CapeProvider[] VALUES = Arrays.copyOfRange(values(), 1, 5); - private String url; - private CapeUrlType type; - - public String getUrlFor(String type) { - return String.format(url, type); - } - - public String getUrlFor(UUID uuid, String username) { - return getUrlFor(toRequestedType(type, uuid, username)); - } - - public static String toRequestedType(CapeUrlType type, UUID uuid, String username) { - return switch (type) { - case UUID -> uuid.toString().replace("-", ""); - case UUID_DASHED -> uuid.toString(); - default -> username; - }; - } - } - - public enum CapeUrlType { - USERNAME, - UUID, - UUID_DASHED - } - - /* - * Sorted by 'priority' - */ - @AllArgsConstructor - @NoArgsConstructor - @Getter - public enum EarsProvider { - MINECRAFTCAPES("https://api.minecraftcapes.net/profile/%s/ears", CapeUrlType.UUID); - - public static final EarsProvider[] VALUES = values(); - private String url; - private CapeUrlType type; - - public String getUrlFor(String type) { - return String.format(url, type); - } - - public String getUrlFor(UUID uuid, String username) { - return getUrlFor(toRequestedType(type, uuid, username)); - } - - public static String toRequestedType(CapeUrlType type, UUID uuid, String username) { - return switch (type) { - case UUID -> uuid.toString().replace("-", ""); - case UUID_DASHED -> uuid.toString(); - default -> username; - }; - } - } } diff --git a/core/src/main/java/org/geysermc/geyser/skin/SkullSkinManager.java b/core/src/main/java/org/geysermc/geyser/skin/SkullSkinManager.java index 18edc8079..e3f00d3b7 100644 --- a/core/src/main/java/org/geysermc/geyser/skin/SkullSkinManager.java +++ b/core/src/main/java/org/geysermc/geyser/skin/SkullSkinManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,6 +29,8 @@ import org.cloudburstmc.protocol.bedrock.data.skin.ImageData; import org.cloudburstmc.protocol.bedrock.data.skin.SerializedSkin; import org.cloudburstmc.protocol.bedrock.packet.PlayerSkinPacket; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.api.skin.Skin; +import org.geysermc.geyser.api.skin.SkinData; import org.geysermc.geyser.entity.type.player.SkullPlayerEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.GeyserLocale; @@ -50,14 +52,14 @@ public class SkullSkinManager extends SkinManager { } public static void requestAndHandleSkin(SkullPlayerEntity entity, GeyserSession session, - Consumer skinConsumer) { - BiConsumer applySkin = (skin, throwable) -> { + Consumer skinConsumer) { + BiConsumer applySkin = (skin, throwable) -> { try { PlayerSkinPacket packet = new PlayerSkinPacket(); packet.setUuid(entity.getUuid()); packet.setOldSkinName(""); - packet.setNewSkinName(skin.getTextureUrl()); - packet.setSkin(buildSkullEntryManually(skin.getTextureUrl(), skin.getSkinData())); + packet.setNewSkinName(skin.textureUrl()); + packet.setSkin(buildSkullEntryManually(skin.textureUrl(), skin.skinData())); packet.setTrustedSkin(true); session.sendUpstreamPacket(packet); } catch (Exception e) { @@ -74,7 +76,7 @@ public class SkullSkinManager extends SkinManager { GeyserImpl.getInstance().getLogger().debug("Using fallback skin for skull at " + entity.getSkullPosition() + " with texture value: " + entity.getTexturesProperty() + " and UUID: " + entity.getSkullUUID()); // No texture available, fallback using the UUID - SkinProvider.SkinData fallback = SkinProvider.determineFallbackSkinData(entity.getSkullUUID()); + SkinData fallback = SkinProvider.determineFallbackSkinData(entity.getSkullUUID()); applySkin.accept(fallback.skin(), null); } else { SkinProvider.requestSkin(entity.getUuid(), data.skinUrl(), true) diff --git a/core/src/main/resources/bedrock/skin/geometry.humanoid.ears.json b/core/src/main/resources/bedrock/skin/geometry.humanoid.ears.json deleted file mode 100644 index 5571655b8..000000000 --- a/core/src/main/resources/bedrock/skin/geometry.humanoid.ears.json +++ /dev/null @@ -1,249 +0,0 @@ -{ - "format_version": "1.14.0", - "minecraft:geometry": [ - { - "bones": [ - { - "name" : "root", - "pivot" : [ 0.0, 0.0, 0.0 ] - }, - - { - "name" : "waist", - "parent" : "root", - "pivot" : [ 0.0, 12.0, 0.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes" : [] - }, - - - { - "name": "body", - "parent" : "waist", - "pivot": [ 0.0, 24.0, 0.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes": [ - { - "origin": [ -4.0, 12.0, -2.0 ], - "size": [ 8, 12, 4 ], - "uv": [ 16, 16 ] - } - ] - }, - - { - "name": "jacket", - "parent" : "body", - "pivot": [ 0.0, 24.0, 0.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes": [ - { - "origin": [ -4.0, 12.0, -2.0 ], - "size": [ 8, 12, 4 ], - "uv": [ 16, 32 ], - "inflate": 0.25 - } - ] - }, - - - { - "name": "head", - "parent" : "body", - "pivot": [ 0.0, 24.0, 0.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes": [ - { - "origin": [ -4.0, 24.0, -4.0 ], - "size": [ 8, 8, 8 ], - "uv": [ 0, 0 ] - } - ] - }, - - { - "name": "hat", - "parent" : "head", - "pivot": [ 0.0, 24.0, 0.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes": [ - { - "origin": [ -4.0, 24.0, -4.0 ], - "size": [ 8, 8, 8 ], - "uv": [ 32, 0 ], - "inflate": 0.5 - } - ] - }, - - - { - "name": "leftArm", - "parent" : "body", - "pivot": [ 5.0, 22.0, 0.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes": [ - { - "origin": [ 4.0, 12.0, -2.0 ], - "size": [ 4, 12, 4 ], - "uv": [ 32, 48 ] - } - ] - }, - { - "name": "rightArm", - "parent" : "body", - "pivot": [ -5.0, 22.0, 0.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes": [ - { - "origin": [ -8.0, 12.0, -2.0 ], - "size": [ 4, 12, 4 ], - "uv": [ 40, 16 ] - } - ] - }, - - { - "name": "leftSleeve", - "parent" : "leftArm", - "pivot": [ 5.0, 22.0, 0.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes": [ - { - "origin": [ 4.0, 12.0, -2.0 ], - "size": [ 4, 12, 4 ], - "uv": [ 48, 48 ], - "inflate": 0.25 - } - ] - }, - - { - "name": "rightSleeve", - "parent" : "rightArm", - "pivot": [ -5.0, 22.0, 0.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes": [ - { - "origin": [ -8.0, 12.0, -2.0 ], - "size": [ 4, 12, 4 ], - "uv": [ 40, 32 ], - "inflate": 0.25 - } - ] - }, - - - { - "name": "leftLeg", - "parent" : "root", - "pivot": [ 1.9, 12.0, 0.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes": [ - { - "origin": [ -0.1, 0.0, -2.0 ], - "size": [ 4, 12, 4 ], - "uv": [ 0, 16 ] - } - ] - }, - - { - "name": "rightLeg", - "parent" : "root", - "pivot": [ -1.9, 12.0, 0.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes": [ - { - "origin": [ -3.9, 0.0, -2.0 ], - "size": [ 4, 12, 4 ], - "uv": [ 0, 16 ] - } - ] - }, - - { - "name": "leftPants", - "parent" : "leftLeg", - "pivot": [1.9, 12.0, 0.0], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes": [ - { - "origin": [ -0.1, 0.0, -2.0 ], - "size": [ 4, 12, 4 ], - "uv": [ 0, 48 ], - "inflate": 0.25 - } - ] - }, - - { - "name": "rightPants", - "parent" : "rightLeg", - "pivot": [ -1.9, 12.0, 0.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes": [ - { - "origin": [ -3.9, 0.0, -2.0] , - "size": [ 4, 12, 4 ], - "uv": [ 0, 32], - "inflate": 0.25 - } - ] - }, - - - { - "name" : "rightItem", - "parent" : "rightArm", - "pivot" : [ -6.0, 15.0, 1.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes" : [] - }, - - { - "name" : "leftItem", - "parent" : "leftArm", - "pivot" : [ 6.0, 15.0, 1.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes" : [] - }, - - - { - "name": "leftEar", - "parent" : "head", - "pivot": [ -1.9, 12.0, 0.0 ], - "cubes": [ - { - "origin": [ 3.0, 31.0, -0.5 ], - "size": [ 6, 6, 1 ], - "uv": [ 24, 0 ], - "inflate": 0.5 - } - ] - }, - - { - "name": "rightEar", - "parent" : "head", - "pivot": [ -1.9, 12.0, 0.0 ], - "cubes": [ - { - "origin": [ -9.0, 31.0, -0.5 ], - "size": [ 6, 6, 1 ], - "uv": [ 24, 0 ], - "inflate": 0.5 - } - ] - } - ], - "description": { - "identifier": "geometry.humanoid.ears", - "texture_height": 64, - "texture_width": 64 - } - } - ] -} \ No newline at end of file diff --git a/core/src/main/resources/bedrock/skin/geometry.humanoid.earsSlim.json b/core/src/main/resources/bedrock/skin/geometry.humanoid.earsSlim.json deleted file mode 100644 index 70c44f854..000000000 --- a/core/src/main/resources/bedrock/skin/geometry.humanoid.earsSlim.json +++ /dev/null @@ -1,249 +0,0 @@ -{ - "format_version": "1.14.0", - "minecraft:geometry": [ - { - "bones": [ - { - "name" : "root", - "pivot" : [ 0.0, 0.0, 0.0 ] - }, - - { - "name" : "waist", - "parent" : "root", - "pivot" : [ 0.0, 12.0, 0.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes" : [] - }, - - - { - "name": "body", - "parent" : "waist", - "pivot": [ 0.0, 24.0, 0.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes": [ - { - "origin": [ -4.0, 12.0, -2.0 ], - "size": [ 8, 12, 4 ], - "uv": [ 16, 16 ] - } - ] - }, - - { - "name": "jacket", - "parent" : "body", - "pivot": [ 0.0, 24.0, 0.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes": [ - { - "origin": [ -4.0, 12.0, -2.0 ], - "size": [ 8, 12, 4 ], - "uv": [ 16, 32 ], - "inflate": 0.25 - } - ] - }, - - - { - "name": "head", - "parent" : "body", - "pivot": [ 0.0, 24.0, 0.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes": [ - { - "origin": [ -4.0, 24.0, -4.0 ], - "size": [ 8, 8, 8 ], - "uv": [ 0, 0 ] - } - ] - }, - - { - "name": "hat", - "parent" : "head", - "pivot": [ 0.0, 24.0, 0.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes": [ - { - "origin": [ -4.0, 24.0, -4.0 ], - "size": [ 8, 8, 8 ], - "uv": [ 32, 0 ], - "inflate": 0.5 - } - ] - }, - - - { - "name": "leftArm", - "parent" : "body", - "pivot": [ 5.0, 21.5, 0.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes": [ - { - "origin": [ 4.0, 12, -2.0 ], - "size": [ 3, 12, 4 ], - "uv": [ 32, 48 ] - } - ] - }, - { - "name": "rightArm", - "parent" : "body", - "pivot": [ -5.0, 21.5, 0.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes": [ - { - "origin": [ -7.0, 12, -2.0 ], - "size": [ 3, 12, 4 ], - "uv": [ 40, 16 ] - } - ] - }, - - { - "name": "leftSleeve", - "parent" : "leftArm", - "pivot": [ 5.0, 21.5, 0.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes": [ - { - "origin": [ 4.0, 11.5, -2.0 ], - "size": [ 3, 12, 4 ], - "uv": [ 48, 48 ], - "inflate": 0.25 - } - ] - }, - - { - "name": "rightSleeve", - "parent" : "rightArm", - "pivot": [ -5.0, 21.5, 0.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes": [ - { - "origin": [ -7.0, 11.5, -2.0 ], - "size": [ 3, 12, 4 ], - "uv": [ 40, 32 ], - "inflate": 0.25 - } - ] - }, - - - { - "name": "leftLeg", - "parent" : "root", - "pivot": [ 1.9, 12.0, 0.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes": [ - { - "origin": [ -0.1, 0.0, -2.0 ], - "size": [ 4, 12, 4 ], - "uv": [ 0, 16 ] - } - ] - }, - - { - "name": "rightLeg", - "parent" : "root", - "pivot": [ -1.9, 12.0, 0.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes": [ - { - "origin": [ -3.9, 0.0, -2.0 ], - "size": [ 4, 12, 4 ], - "uv": [ 0, 16 ] - } - ] - }, - - { - "name": "leftPants", - "parent" : "leftLeg", - "pivot": [1.9, 12.0, 0.0], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes": [ - { - "origin": [ -0.1, 0.0, -2.0 ], - "size": [ 4, 12, 4 ], - "uv": [ 0, 48 ], - "inflate": 0.25 - } - ] - }, - - { - "name": "rightPants", - "parent" : "rightLeg", - "pivot": [ -1.9, 12.0, 0.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes": [ - { - "origin": [ -3.9, 0.0, -2.0] , - "size": [ 4, 12, 4 ], - "uv": [ 0, 32], - "inflate": 0.25 - } - ] - }, - - - { - "name" : "rightItem", - "parent" : "rightArm", - "pivot" : [ -6.0, 15.0, 1.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes" : [] - }, - - { - "name" : "leftItem", - "parent" : "leftArm", - "pivot" : [ 6.0, 15.0, 1.0 ], - "rotation" : [ 0.0, 0.0, 0.0 ], - "cubes" : [] - }, - - - { - "name": "leftEar", - "parent" : "head", - "pivot": [ -1.9, 12.0, 0.0 ], - "cubes": [ - { - "origin": [ 3.0, 31.0, -0.5 ], - "size": [ 6, 6, 1 ], - "uv": [ 24, 0 ], - "inflate": 0.5 - } - ] - }, - - { - "name": "rightEar", - "parent" : "head", - "pivot": [ -1.9, 12.0, 0.0 ], - "cubes": [ - { - "origin": [ -9.0, 31.0, -0.5 ], - "size": [ 6, 6, 1 ], - "uv": [ 24, 0 ], - "inflate": 0.5 - } - ] - } - ], - "description": { - "identifier": "geometry.humanoid.earsSlim", - "texture_height": 64, - "texture_width": 64 - } - } - ] -} \ No newline at end of file diff --git a/core/src/main/resources/config.yml b/core/src/main/resources/config.yml index c70b0d7ab..fc0cd83f1 100644 --- a/core/src/main/resources/config.yml +++ b/core/src/main/resources/config.yml @@ -113,14 +113,6 @@ max-players: 100 # If debug messages should be sent through console debug-mode: false -# Allow third party capes to be visible. Currently allowing: -# OptiFine capes, LabyMod capes, 5Zig capes and MinecraftCapes -allow-third-party-capes: false - -# Allow third party deadmau5 ears to be visible. Currently allowing: -# MinecraftCapes -allow-third-party-ears: false - # Allow a fake cooldown indicator to be sent. Bedrock players otherwise do not see a cooldown as they still use 1.8 combat. # Please note: if the cooldown is enabled, some users may see a black box during the cooldown sequence, like below: # https://cdn.discordapp.com/attachments/613170125696270357/957075682230419466/Screenshot_from_2022-03-25_20-35-08.png diff --git a/gradle.properties b/gradle.properties index dd61d2556..40d8a36db 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,5 +7,5 @@ org.gradle.vfs.watch=false group=org.geysermc id=geyser -version=2.3.0-SNAPSHOT +version=2.3.1-SNAPSHOT description=Allows for players from Minecraft: Bedrock Edition to join Minecraft: Java Edition servers. From 4d61766d0adf17849ecd66538c3889f76a763b3f Mon Sep 17 00:00:00 2001 From: rtm516 Date: Tue, 14 May 2024 16:38:51 +0100 Subject: [PATCH 162/272] Fix SessionSkinApplyEvent not keeping altered skin data (#4663) --- .../main/java/org/geysermc/geyser/skin/SkinProvider.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/skin/SkinProvider.java b/core/src/main/java/org/geysermc/geyser/skin/SkinProvider.java index 3b31dfff8..5b16bc3a3 100644 --- a/core/src/main/java/org/geysermc/geyser/skin/SkinProvider.java +++ b/core/src/main/java/org/geysermc/geyser/skin/SkinProvider.java @@ -271,17 +271,17 @@ public class SkinProvider { @Override public void skin(@NonNull Skin newSkin) { - eventSkinData.skinData(new SkinData(Objects.requireNonNull(newSkin), skinData.cape(), skinData.geometry())); + eventSkinData.skinData(new SkinData(Objects.requireNonNull(newSkin), eventSkinData.skinData().cape(), eventSkinData.skinData().geometry())); } @Override public void cape(@NonNull Cape newCape) { - eventSkinData.skinData(new SkinData(skinData.skin(), Objects.requireNonNull(newCape), skinData.geometry())); + eventSkinData.skinData(new SkinData(eventSkinData.skinData().skin(), Objects.requireNonNull(newCape), eventSkinData.skinData().geometry())); } @Override public void geometry(@NonNull SkinGeometry newGeometry) { - eventSkinData.skinData(new SkinData(skinData.skin(), skinData.cape(), Objects.requireNonNull(newGeometry))); + eventSkinData.skinData(new SkinData(eventSkinData.skinData().skin(), eventSkinData.skinData().cape(), Objects.requireNonNull(newGeometry))); } }); From 6c4b2cb173bb5e36396a3ee031286ee2ab3f8ed4 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Wed, 15 May 2024 13:40:57 -0400 Subject: [PATCH 163/272] Don't create a property manager if an entity has no properties --- .../geysermc/geyser/entity/type/Entity.java | 4 +- .../java/JavaSelectKnownPacksTranslator.java | 62 +++++++++++++++++++ 2 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSelectKnownPacksTranslator.java diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java index fecd72f67..da9a28451 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java @@ -134,7 +134,7 @@ public class Entity implements GeyserEntity { this.valid = false; - this.propertyManager = new GeyserEntityPropertyManager(definition.registeredProperties()); + this.propertyManager = definition.registeredProperties() == null ? null : new GeyserEntityPropertyManager(definition.registeredProperties()); setPosition(position); setAirSupply(getMaxAir()); @@ -361,7 +361,7 @@ public class Entity implements GeyserEntity { return; } - if (propertyManager.hasProperties()) { + if (propertyManager != null && propertyManager.hasProperties()) { SetEntityDataPacket entityDataPacket = new SetEntityDataPacket(); entityDataPacket.setRuntimeEntityId(geyserId); propertyManager.applyIntProperties(entityDataPacket.getProperties().getIntProperties()); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSelectKnownPacksTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSelectKnownPacksTranslator.java new file mode 100644 index 000000000..6b1c8c645 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSelectKnownPacksTranslator.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.translator.protocol.java; + +import org.geysermc.geyser.network.GameProtocol; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.protocol.PacketTranslator; +import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.data.game.KnownPack; +import org.geysermc.mcprotocollib.protocol.packet.configuration.clientbound.ClientboundSelectKnownPacks; +import org.geysermc.mcprotocollib.protocol.packet.configuration.serverbound.ServerboundSelectKnownPacks; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +@Translator(packet = ClientboundSelectKnownPacks.class) +public class JavaSelectKnownPacksTranslator extends PacketTranslator { + // todo: dump from client? + private static final Set KNOWN_PACK_IDS = Set.of("core", "update_1_21", "bundle", "trade_rebalance"); + + @Override + public void translate(GeyserSession session, ClientboundSelectKnownPacks packet) { + List knownPacks = new ArrayList<>(1); + for (KnownPack pack : packet.getKnownPacks()) { + if ("minecraft".equals(pack.getNamespace()) && GameProtocol.getJavaMinecraftVersion().equals(pack.getVersion())) { + // Implementation note: these won't always necessarily be equal. + // 1.20.5 versus 1.20.6 for example - same protocol version. A vanilla server for either version will gracefully accept either. + // If the versions mismatch, the registry will be sent over the network, though. + // For vanilla compliancy, to minimize network traffic, and for potential future behavior, + // We'll implement how the Java client does it. + if (KNOWN_PACK_IDS.contains(pack.getId())) { + knownPacks.add(pack); + } + } + } + session.sendDownstreamPacket(new ServerboundSelectKnownPacks(knownPacks)); + } +} From 423d2e3a362ccd0cbf5dc0eafaed4b67d3728757 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Wed, 15 May 2024 13:41:31 -0400 Subject: [PATCH 164/272] Emulate vanilla behavior with existing registries --- .../geyser/session/GeyserSession.java | 88 ++++++++++++------- .../geyser/session/cache/RegistryCache.java | 37 +++++++- 2 files changed, 90 insertions(+), 35 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 617087f71..c0ff1fb71 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -28,35 +28,6 @@ package org.geysermc.geyser.session; import com.github.steveice10.mc.auth.data.GameProfile; import com.github.steveice10.mc.auth.exception.request.RequestException; import com.github.steveice10.mc.auth.service.MsaAuthenticationService; -import org.geysermc.mcprotocollib.protocol.MinecraftConstants; -import org.geysermc.mcprotocollib.protocol.MinecraftProtocol; -import org.geysermc.mcprotocollib.protocol.data.ProtocolState; -import org.geysermc.mcprotocollib.protocol.data.UnexpectedEncryptionException; -import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; -import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; -import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; -import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; -import org.geysermc.mcprotocollib.protocol.data.game.entity.player.HandPreference; -import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerAction; -import org.geysermc.mcprotocollib.protocol.data.game.setting.ChatVisibility; -import org.geysermc.mcprotocollib.protocol.data.game.setting.SkinPart; -import org.geysermc.mcprotocollib.protocol.data.game.statistic.CustomStatistic; -import org.geysermc.mcprotocollib.protocol.data.game.statistic.Statistic; -import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundClientInformationPacket; -import org.geysermc.mcprotocollib.protocol.packet.handshake.serverbound.ClientIntentionPacket; -import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundChatCommandSignedPacket; -import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundChatPacket; -import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosPacket; -import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundPlayerAbilitiesPacket; -import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundPlayerActionPacket; -import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundUseItemPacket; -import org.geysermc.mcprotocollib.protocol.packet.login.serverbound.ServerboundCustomQueryAnswerPacket; -import org.geysermc.mcprotocollib.network.BuiltinFlags; -import org.geysermc.mcprotocollib.network.Session; -import org.geysermc.mcprotocollib.network.event.session.*; -import org.geysermc.mcprotocollib.network.packet.Packet; -import org.geysermc.mcprotocollib.network.tcp.TcpClientSession; -import org.geysermc.mcprotocollib.network.tcp.TcpSession; import io.netty.channel.Channel; import io.netty.channel.EventLoop; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; @@ -145,6 +116,38 @@ import org.geysermc.geyser.util.ChunkUtils; import org.geysermc.geyser.util.DimensionUtils; import org.geysermc.geyser.util.EntityUtils; import org.geysermc.geyser.util.LoginEncryptionUtils; +import org.geysermc.mcprotocollib.network.BuiltinFlags; +import org.geysermc.mcprotocollib.network.Session; +import org.geysermc.mcprotocollib.network.event.session.*; +import org.geysermc.mcprotocollib.network.packet.Packet; +import org.geysermc.mcprotocollib.network.tcp.TcpClientSession; +import org.geysermc.mcprotocollib.network.tcp.TcpSession; +import org.geysermc.mcprotocollib.protocol.ClientListener; +import org.geysermc.mcprotocollib.protocol.MinecraftConstants; +import org.geysermc.mcprotocollib.protocol.MinecraftProtocol; +import org.geysermc.mcprotocollib.protocol.data.ProtocolState; +import org.geysermc.mcprotocollib.protocol.data.UnexpectedEncryptionException; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.HandPreference; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerAction; +import org.geysermc.mcprotocollib.protocol.data.game.setting.ChatVisibility; +import org.geysermc.mcprotocollib.protocol.data.game.setting.SkinPart; +import org.geysermc.mcprotocollib.protocol.data.game.statistic.CustomStatistic; +import org.geysermc.mcprotocollib.protocol.data.game.statistic.Statistic; +import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundClientInformationPacket; +import org.geysermc.mcprotocollib.protocol.packet.configuration.clientbound.ClientboundFinishConfigurationPacket; +import org.geysermc.mcprotocollib.protocol.packet.configuration.serverbound.ServerboundFinishConfigurationPacket; +import org.geysermc.mcprotocollib.protocol.packet.handshake.serverbound.ClientIntentionPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundChatCommandSignedPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundChatPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundPlayerAbilitiesPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundPlayerActionPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundUseItemPacket; +import org.geysermc.mcprotocollib.protocol.packet.login.serverbound.ServerboundCustomQueryAnswerPacket; import java.net.ConnectException; import java.net.InetSocketAddress; @@ -646,9 +649,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { sentSpawnPacket = true; syncEntityProperties(); - // Set the hardcoded shield ID to the ID we just defined in StartGamePacket - // upstream.getSession().getHardcodedBlockingId().set(this.itemMappings.getStoredItems().shield().getBedrockId()); - if (GeyserImpl.getInstance().getConfig().isAddNonBedrockItems()) { ItemComponentPacket componentPacket = new ItemComponentPacket(); componentPacket.getItems().addAll(itemMappings.getComponentItemData()); @@ -875,6 +875,8 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { // Start ticking tickThread = eventLoop.scheduleAtFixedRate(this::tick, 50, 50, TimeUnit.MILLISECONDS); + this.protocol.setUseDefaultListeners(false); + TcpSession downstream; if (geyser.getBootstrap().getSocketAddress() != null) { // We're going to connect through the JVM and not through TCP @@ -904,6 +906,25 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { // Let Geyser handle sending the keep alive downstream.setFlag(MinecraftConstants.AUTOMATIC_KEEP_ALIVE_MANAGEMENT, false); } + // We'll handle this since we have the registry data on hand + downstream.setFlag(MinecraftConstants.SEND_BLANK_KNOWN_PACKS_RESPONSE, false); + + // This isn't a great solution, but... we want to make sure the finish configuration packet cannot be sent + // before the KnownPacks packet. + this.downstream.getSession().addListener(new ClientListener(ProtocolState.LOGIN, loginEvent.transferring()) { + @Override + public void packetReceived(Session session, Packet packet) { + if (protocol.getState() == ProtocolState.CONFIGURATION) { + if (packet instanceof ClientboundFinishConfigurationPacket) { + // Prevent + GeyserSession.this.ensureInEventLoop(() -> GeyserSession.this.sendDownstreamPacket(new ServerboundFinishConfigurationPacket())); + return; + } + } + super.packetReceived(session, packet); + } + }); + downstream.addListener(new SessionAdapter() { @Override public void packetSending(PacketSendingEvent event) { @@ -1543,8 +1564,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { startGamePacket.setEnchantmentSeed(0); startGamePacket.setMultiplayerCorrelationId(""); - startGamePacket.setItemDefinitions(this.itemMappings.getItemDefinitions().values().stream().toList()); // TODO - // startGamePacket.setBlockPalette(this.blockMappings.getBedrockBlockPalette()); + startGamePacket.getItemDefinitions().addAll(this.itemMappings.getItemDefinitions().values()); // Needed for custom block mappings and custom skulls system startGamePacket.getBlockProperties().addAll(this.blockMappings.getBlockProperties()); diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java index 9581df253..fa4503635 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java @@ -30,6 +30,8 @@ import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import lombok.AccessLevel; import lombok.Getter; import lombok.experimental.Accessors; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.data.TrimMaterial; import org.cloudburstmc.protocol.bedrock.data.TrimPattern; import org.geysermc.geyser.GeyserImpl; @@ -42,6 +44,7 @@ import org.geysermc.geyser.session.cache.registry.JavaRegistry; import org.geysermc.geyser.session.cache.registry.SimpleJavaRegistry; import org.geysermc.geyser.text.TextDecoration; import org.geysermc.geyser.translator.level.BiomeTranslator; +import org.geysermc.mcprotocollib.protocol.MinecraftProtocol; import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; import org.geysermc.mcprotocollib.protocol.packet.configuration.clientbound.ClientboundRegistryDataPacket; @@ -63,6 +66,7 @@ import java.util.function.ToIntFunction; @Accessors(fluent = true) @Getter public final class RegistryCache { + private static final Map> DEFAULTS; private static final Map>> REGISTRIES = new HashMap<>(); static { @@ -73,6 +77,24 @@ public final class RegistryCache { register("worldgen/biome", (cache, array) -> cache.biomeTranslations = array, BiomeTranslator::loadServerBiome); register("banner_pattern", cache -> cache.bannerPatterns, ($, entry) -> BannerPattern.getByJavaIdentifier(entry.getId())); register("wolf_variant", cache -> cache.wolfVariants, ($, entry) -> WolfEntity.WolfVariant.getByJavaIdentifier(entry.getId())); + + // Load from MCProtocolLib's classloader + NbtMap tag = MinecraftProtocol.loadNetworkCodec(); + Map> defaults = new HashMap<>(); + // Don't create a keySet - no need to create the cached object in HashMap if we don't use it again + REGISTRIES.forEach((key, $) -> { + List rawValues = tag.getCompound(key) + .getList("value", NbtType.COMPOUND); + Map values = new HashMap<>(); + for (NbtMap value : rawValues) { + String name = value.getString("name"); + values.put(name, value.getCompound("element")); + } + // Can make these maps immutable and as efficient as possible after initialization + defaults.put(key, Map.copyOf(values)); + }); + + DEFAULTS = Map.copyOf(defaults); } @Getter(AccessLevel.NONE) @@ -116,13 +138,22 @@ public final class RegistryCache { * @param the class that represents these entries. */ private static void register(String registry, Function> localCacheFunction, BiFunction reader) { - REGISTRIES.put("minecraft:" + registry, (registryCache, entries) -> { + String key = "minecraft:" + registry; + REGISTRIES.put(key, (registryCache, entries) -> { + Map localRegistry = null; JavaRegistry localCache = localCacheFunction.apply(registryCache); // Clear each local cache every time a new registry entry is given to us // (e.g. proxy server switches) List builder = new ArrayList<>(entries.size()); for (int i = 0; i < entries.size(); i++) { RegistryEntry entry = entries.get(i); + // If the data is null, that's the server telling us we need to use our default values. + if (entry.getData() == null) { + if (localRegistry == null) { // Lazy initialize + localRegistry = DEFAULTS.get(key); + } + entry = new RegistryEntry(entry.getId(), localRegistry.get(entry.getId())); + } // This is what Geyser wants to keep as a value for this registry. T cacheEntry = reader.apply(registryCache.session, entry); builder.add(i, cacheEntry); @@ -156,4 +187,8 @@ public final class RegistryCache { localCacheFunction.accept(registryCache, array); }); } + + public static void init() { + // no-op + } } From 9bca012194211b34583e1688bc9e925e138c77f1 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Wed, 15 May 2024 15:31:02 -0400 Subject: [PATCH 165/272] Bump Erosion --- bootstrap/spigot/build.gradle.kts | 6 +++++ .../manager/GeyserSpigotWorldManager.java | 17 ++++++------ .../java/org/geysermc/geyser/GeyserImpl.java | 6 ++++- .../erosion/GeyserboundPacketHandlerImpl.java | 16 +++--------- .../geyser/level/GeyserWorldManager.java | 5 ++-- .../geysermc/geyser/level/WorldManager.java | 26 +++++++++++++++++++ .../protocol/java/JavaLoginTranslator.java | 4 +++ gradle/libs.versions.toml | 7 ++--- 8 files changed, 61 insertions(+), 26 deletions(-) diff --git a/bootstrap/spigot/build.gradle.kts b/bootstrap/spigot/build.gradle.kts index 8143d96a1..7ccb50484 100644 --- a/bootstrap/spigot/build.gradle.kts +++ b/bootstrap/spigot/build.gradle.kts @@ -4,6 +4,12 @@ dependencies { isTransitive = false } + implementation(libs.erosion.bukkit.nms) { + attributes { + attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 21) + } + } + implementation(variantOf(libs.adapters.spigot) { classifier("all") // otherwise the unshaded jar is used without the shaded NMS implementations }) diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java index 8a0e0b70d..47086d36c 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java @@ -25,9 +25,7 @@ package org.geysermc.geyser.platform.spigot.world.manager; -import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityInfo; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.World; @@ -39,6 +37,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMap; import org.geysermc.erosion.bukkit.BukkitLecterns; import org.geysermc.erosion.bukkit.BukkitUtils; +import org.geysermc.erosion.bukkit.PickBlockUtils; import org.geysermc.erosion.bukkit.SchedulerUtils; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.level.GameRule; @@ -47,6 +46,9 @@ import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.BlockEntityUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityInfo; import java.util.List; import java.util.Objects; @@ -205,17 +207,16 @@ public class GeyserSpigotWorldManager extends WorldManager { @Override public @NonNull CompletableFuture<@Nullable DataComponents> getPickItemComponents(GeyserSession session, int x, int y, int z, boolean addNbtData) { - CompletableFuture<@Nullable DataComponents> future = new CompletableFuture<>(); Player bukkitPlayer; if ((bukkitPlayer = Bukkit.getPlayer(session.getPlayerEntity().getUuid())) == null) { - future.complete(null); - return future; + return CompletableFuture.completedFuture(null); } + CompletableFuture> future = new CompletableFuture<>(); Block block = bukkitPlayer.getWorld().getBlockAt(x, y, z); // Paper 1.19.3 complains about async access otherwise. // java.lang.IllegalStateException: Tile is null, asynchronous access? - SchedulerUtils.runTask(this.plugin, () -> future.complete(/*PickBlockUtils.pickBlock(block)*/ null), block); // TODO fix erosion once clear how to handle this - return future; + SchedulerUtils.runTask(this.plugin, () -> future.complete(PickBlockUtils.pickBlock(block)), block); + return future.thenApply(RAW_TRANSFORMER); } /** diff --git a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java index d5635acf9..a60a14ea0 100644 --- a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java +++ b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java @@ -45,6 +45,7 @@ import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec; import org.geysermc.api.Geyser; import org.geysermc.cumulus.form.Form; import org.geysermc.cumulus.form.util.FormBuilder; +import org.geysermc.erosion.packet.Packets; import org.geysermc.floodgate.crypto.AesCipher; import org.geysermc.floodgate.crypto.AesKeyProducer; import org.geysermc.floodgate.crypto.Base64Topping; @@ -77,6 +78,7 @@ import org.geysermc.geyser.scoreboard.ScoreboardUpdater; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.PendingMicrosoftAuthentication; import org.geysermc.geyser.session.SessionManager; +import org.geysermc.geyser.session.cache.RegistryCache; import org.geysermc.geyser.skin.FloodgateSkinUploader; import org.geysermc.geyser.skin.ProvidedSkins; import org.geysermc.geyser.skin.SkinProvider; @@ -211,6 +213,8 @@ public class GeyserImpl implements GeyserApi { Registries.init(); BlockRegistries.init(); + RegistryCache.init(); + /* Initialize translators */ EntityDefinitions.init(); MessageTranslator.init(); @@ -383,7 +387,7 @@ public class GeyserImpl implements GeyserApi { this.newsHandler = new NewsHandler(BRANCH, this.buildNumber()); - //Packets.initGeyser(); + Packets.initGeyser(); if (Epoll.isAvailable()) { this.erosionUnixListener = new UnixSocketClientListener(); diff --git a/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java b/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java index a62f9ec49..7d5bba1e8 100644 --- a/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java +++ b/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.erosion; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.PistonValueType; import io.netty.channel.Channel; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; @@ -43,14 +41,7 @@ import org.geysermc.erosion.packet.ErosionPacketHandler; import org.geysermc.erosion.packet.ErosionPacketSender; import org.geysermc.erosion.packet.backendbound.BackendboundInitializePacket; import org.geysermc.erosion.packet.backendbound.BackendboundPacket; -import org.geysermc.erosion.packet.geyserbound.GeyserboundBatchBlockIdPacket; -import org.geysermc.erosion.packet.geyserbound.GeyserboundBlockEntityPacket; -import org.geysermc.erosion.packet.geyserbound.GeyserboundBlockIdPacket; -import org.geysermc.erosion.packet.geyserbound.GeyserboundBlockLookupFailPacket; -import org.geysermc.erosion.packet.geyserbound.GeyserboundBlockPlacePacket; -import org.geysermc.erosion.packet.geyserbound.GeyserboundHandshakePacket; -import org.geysermc.erosion.packet.geyserbound.GeyserboundPickBlockPacket; -import org.geysermc.erosion.packet.geyserbound.GeyserboundPistonEventPacket; +import org.geysermc.erosion.packet.geyserbound.*; import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.physics.Direction; import org.geysermc.geyser.network.GameProtocol; @@ -58,6 +49,7 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.PistonCache; import org.geysermc.geyser.translator.level.block.entity.PistonBlockEntity; import org.geysermc.geyser.util.BlockEntityUtils; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.PistonValueType; import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicInteger; @@ -71,7 +63,7 @@ public final class GeyserboundPacketHandlerImpl extends AbstractGeyserboundPacke @Setter private CompletableFuture pendingBatchLookup = null; @Setter - private CompletableFuture pickBlockLookup = null; + private CompletableFuture> pickBlockLookup = null; private final AtomicInteger nextTransactionId = new AtomicInteger(1); @@ -147,7 +139,7 @@ public final class GeyserboundPacketHandlerImpl extends AbstractGeyserboundPacke @Override public void handlePickBlock(GeyserboundPickBlockPacket packet) { if (this.pickBlockLookup != null) { - //this.pickBlockLookup.complete(packet.getTag()); // TODO 1.20.5 + this.pickBlockLookup.complete(packet.getComponents()); } } diff --git a/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java b/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java index 08611a5e1..3144f0cb2 100644 --- a/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java +++ b/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.level; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -179,9 +180,9 @@ public class GeyserWorldManager extends WorldManager { if (erosionHandler == null) { return super.getPickItemComponents(session, x, y, z, addNbtData); } - CompletableFuture future = new CompletableFuture<>(); + CompletableFuture> future = new CompletableFuture<>(); erosionHandler.setPickBlockLookup(future); erosionHandler.sendPacket(new BackendboundPickBlockPacket(Vector3i.from(x, y, z))); - return future; + return future.thenApply(RAW_TRANSFORMER); } } diff --git a/core/src/main/java/org/geysermc/geyser/level/WorldManager.java b/core/src/main/java/org/geysermc/geyser/level/WorldManager.java index a1b16a1d5..cd6c9e824 100644 --- a/core/src/main/java/org/geysermc/geyser/level/WorldManager.java +++ b/core/src/main/java/org/geysermc/geyser/level/WorldManager.java @@ -25,19 +25,29 @@ package org.geysermc.geyser.level; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3i; import org.geysermc.erosion.util.BlockPositionIterator; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponent; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemCodecHelper; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityInfo; import org.geysermc.mcprotocollib.protocol.data.game.setting.Difficulty; +import java.util.HashMap; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.concurrent.CompletableFuture; +import java.util.function.Function; /** * Class that manages or retrieves various information @@ -223,4 +233,20 @@ public abstract class WorldManager { public CompletableFuture<@Nullable DataComponents> getPickItemComponents(GeyserSession session, int x, int y, int z, boolean addExtraData) { return CompletableFuture.completedFuture(null); } + + protected static final Function, DataComponents> RAW_TRANSFORMER = map -> { + try { + Map, DataComponent> components = new HashMap<>(); + Int2ObjectMaps.fastForEach(map, entry -> { + DataComponentType type = DataComponentType.from(entry.getIntKey()); + ByteBuf buf = Unpooled.wrappedBuffer(entry.getValue()); + DataComponent value = type.readDataComponent(ItemCodecHelper.INSTANCE, buf); + components.put(type, value); + }); + return new DataComponents(components); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + }; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java index fe4401dca..33d5a88b9 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; +import org.geysermc.erosion.Constants; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerSpawnInfo; import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundLoginPacket; @@ -45,6 +46,8 @@ import org.geysermc.geyser.util.ChunkUtils; import org.geysermc.geyser.util.DimensionUtils; import org.geysermc.geyser.util.EntityUtils; +import java.nio.charset.StandardCharsets; + @Translator(packet = ClientboundLoginPacket.class) public class JavaLoginTranslator extends PacketTranslator { @@ -134,6 +137,7 @@ public class JavaLoginTranslator extends PacketTranslator Date: Thu, 16 May 2024 23:12:06 -0400 Subject: [PATCH 166/272] Block refactory --- .../world/GeyserSpigotBlockPlaceListener.java | 3 +- .../GeyserSpigotNativeWorldManager.java | 3 +- .../manager/GeyserSpigotWorldManager.java | 8 +- .../java/org/geysermc/geyser/GeyserImpl.java | 13 + .../geyser/entity/type/FishingHookEntity.java | 3 +- .../erosion/GeyserboundPacketHandlerImpl.java | 3 +- .../geyser/level/block/BlockStateValues.java | 21 +- .../geysermc/geyser/level/block/Blocks.java | 2820 +++++++++++++++++ .../level/block/property/ChestType.java | 34 + .../level/block/property/Properties.java | 146 + .../geyser/level/block/property/Property.java | 43 + .../geyser/level/block/type/BannerBlock.java | 39 + .../geyser/level/block/type/BedBlock.java | 39 + .../geyser/level/block/type/Block.java | 152 + .../geyser/level/block/type/BlockState.java | 64 + .../geyser/registry/BlockRegistries.java | 12 +- .../geyser/registry/ListRegistry.java | 103 + .../populator/BlockRegistryPopulator.java | 2 - .../geyser/session/GeyserSession.java | 3 - .../geyser/session/cache/ChunkCache.java | 13 +- .../inventory/ShulkerInventoryTranslator.java | 3 +- .../chest/DoubleChestInventoryTranslator.java | 7 +- .../entity/BannerBlockEntityTranslator.java | 10 +- .../entity/BeaconBlockEntityTranslator.java | 3 +- .../entity/BedBlockEntityTranslator.java | 12 +- .../block/entity/BedrockOnlyBlockEntity.java | 3 +- .../block/entity/BlockEntityTranslator.java | 5 +- .../BrushableBlockEntityTranslator.java | 7 +- .../entity/CampfireBlockEntityTranslator.java | 3 +- .../CommandBlockBlockEntityTranslator.java | 7 +- .../DecoratedPotBlockEntityTranslator.java | 3 +- .../DoubleChestBlockEntityTranslator.java | 46 +- .../entity/EmptyBlockEntityTranslator.java | 3 +- .../EndGatewayBlockEntityTranslator.java | 3 +- .../FlowerPotBlockEntityTranslator.java | 7 +- .../JigsawBlockBlockEntityTranslator.java | 5 +- .../level/block/entity/PistonBlockEntity.java | 15 +- .../ShulkerBoxBlockEntityTranslator.java | 12 +- .../entity/SignBlockEntityTranslator.java | 3 +- .../entity/SkullBlockEntityTranslator.java | 15 +- .../entity/SpawnerBlockEntityTranslator.java | 5 +- .../StructureBlockBlockEntityTranslator.java | 5 +- .../TrialSpawnerBlockEntityTranslator.java | 3 +- .../BedrockBlockPickRequestTranslator.java | 3 +- ...BedrockInventoryTransactionTranslator.java | 3 +- .../player/BedrockActionTranslator.java | 3 +- .../level/JavaBlockEntityDataTranslator.java | 11 +- .../java/level/JavaBlockEventTranslator.java | 3 +- .../java/level/JavaExplodeTranslator.java | 3 +- .../JavaLevelChunkWithLightTranslator.java | 13 +- .../org/geysermc/geyser/util/ChunkUtils.java | 14 +- .../org/geysermc/geyser/util/SoundUtils.java | 3 +- .../geysermc/geyser/util/StatisticsUtils.java | 9 +- gradle/libs.versions.toml | 3 +- 54 files changed, 3620 insertions(+), 157 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/Blocks.java create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/property/ChestType.java create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/property/Properties.java create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/property/Property.java create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/type/BannerBlock.java create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/type/BedBlock.java create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/type/Block.java create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java create mode 100644 core/src/main/java/org/geysermc/geyser/registry/ListRegistry.java diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserSpigotBlockPlaceListener.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserSpigotBlockPlaceListener.java index 71aba11f9..b5f4bd4f9 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserSpigotBlockPlaceListener.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserSpigotBlockPlaceListener.java @@ -34,6 +34,7 @@ import org.bukkit.event.Listener; import org.bukkit.event.block.BlockPlaceEvent; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.platform.spigot.world.manager.GeyserSpigotWorldManager; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.session.GeyserSession; @@ -59,7 +60,7 @@ public class GeyserSpigotBlockPlaceListener implements Listener { event.getBlockPlaced().getX(), event.getBlockPlaced().getY(), event.getBlockPlaced().getZ()))); } else { String javaBlockId = event.getBlockPlaced().getBlockData().getAsString(); - placeBlockSoundPacket.setExtraData(session.getBlockMappings().getBedrockBlockId(BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getOrDefault(javaBlockId, BlockStateValues.JAVA_AIR_ID))); + placeBlockSoundPacket.setExtraData(session.getBlockMappings().getBedrockBlockId(BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getOrDefault(javaBlockId, Block.JAVA_AIR_ID))); } placeBlockSoundPacket.setIdentifier(":"); session.sendUpstreamPacket(placeBlockSoundPacket); diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotNativeWorldManager.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotNativeWorldManager.java index 45e84d254..c99ca4e78 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotNativeWorldManager.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotNativeWorldManager.java @@ -34,6 +34,7 @@ import org.geysermc.geyser.adapters.WorldAdapter; import org.geysermc.geyser.adapters.paper.PaperAdapters; import org.geysermc.geyser.adapters.spigot.SpigotAdapters; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.session.GeyserSession; public class GeyserSpigotNativeWorldManager extends GeyserSpigotWorldManager { @@ -52,7 +53,7 @@ public class GeyserSpigotNativeWorldManager extends GeyserSpigotWorldManager { public int getBlockAt(GeyserSession session, int x, int y, int z) { Player player = Bukkit.getPlayer(session.getPlayerEntity().getUsername()); if (player == null) { - return BlockStateValues.JAVA_AIR_ID; + return Block.JAVA_AIR_ID; } return adapter.getBlockAt(player.getWorld(), x, y, z); } diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java index 47086d36c..a04c60126 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java @@ -70,12 +70,12 @@ public class GeyserSpigotWorldManager extends WorldManager { public int getBlockAt(GeyserSession session, int x, int y, int z) { Player bukkitPlayer; if ((bukkitPlayer = Bukkit.getPlayer(session.getPlayerEntity().getUsername())) == null) { - return BlockStateValues.JAVA_AIR_ID; + return org.geysermc.geyser.level.block.type.Block.JAVA_AIR_ID; } World world = bukkitPlayer.getWorld(); if (!world.isChunkLoaded(x >> 4, z >> 4)) { // If the chunk isn't loaded, how could we even be here? - return BlockStateValues.JAVA_AIR_ID; + return org.geysermc.geyser.level.block.type.Block.JAVA_AIR_ID; } return getBlockNetworkId(world.getBlockAt(x, y, z)); @@ -86,9 +86,9 @@ public class GeyserSpigotWorldManager extends WorldManager { // Terrible behavior, but this is basically what's always been happening behind the scenes anyway. CompletableFuture blockData = new CompletableFuture<>(); Bukkit.getRegionScheduler().execute(this.plugin, block.getLocation(), () -> blockData.complete(block.getBlockData().getAsString())); - return BlockRegistries.JAVA_IDENTIFIER_TO_ID.getOrDefault(blockData.join(), BlockStateValues.JAVA_AIR_ID); + return BlockRegistries.JAVA_IDENTIFIER_TO_ID.getOrDefault(blockData.join(), org.geysermc.geyser.level.block.type.Block.JAVA_AIR_ID); } - return BlockRegistries.JAVA_IDENTIFIER_TO_ID.getOrDefault(block.getBlockData().getAsString(), BlockStateValues.JAVA_AIR_ID); + return BlockRegistries.JAVA_IDENTIFIER_TO_ID.getOrDefault(block.getBlockData().getAsString(), org.geysermc.geyser.level.block.type.Block.JAVA_AIR_ID); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java index a60a14ea0..4f572ef63 100644 --- a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java +++ b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java @@ -69,6 +69,7 @@ import org.geysermc.geyser.event.GeyserEventBus; import org.geysermc.geyser.extension.GeyserExtensionManager; import org.geysermc.geyser.impl.MinecraftVersionImpl; import org.geysermc.geyser.level.WorldManager; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.network.netty.GeyserServer; import org.geysermc.geyser.registry.BlockRegistries; @@ -256,6 +257,18 @@ public class GeyserImpl implements GeyserApi { } VersionCheckUtils.checkForOutdatedJava(logger); + + Blocks.VAULT.javaId(); + for (int i = 0; i < BlockRegistries.JAVA_BLOCKS.get().length; i++) { + String cleanIdentifier = BlockRegistries.JAVA_BLOCKS.get(i).getCleanJavaIdentifier(); + String newIdentifier = BlockRegistries.BLOCK_STATES.get(i).block().javaIdentifier(); + if (!cleanIdentifier.equals(newIdentifier)) { + System.out.println("Check block " + BlockRegistries.BLOCK_STATES.get(i).block().javaIdentifier()); + break; + } + } + System.out.println(BlockRegistries.JAVA_BLOCKS.get().length); + System.out.println(BlockRegistries.BLOCK_STATES.get().size()); } private void startInstance() { diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java index f4c0cea36..26a64bcae 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java @@ -33,6 +33,7 @@ import org.geysermc.erosion.util.BlockPositionIterator; import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.type.player.PlayerEntity; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.level.physics.BoundingBox; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.collision.BlockCollision; @@ -162,7 +163,7 @@ public class FishingHookEntity extends ThrowableEntity { */ protected boolean isInAir() { int block = session.getGeyser().getWorldManager().getBlockAt(session, position.toInt()); - return block == BlockStateValues.JAVA_AIR_ID; + return block == Block.JAVA_AIR_ID; } @Override diff --git a/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java b/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java index 7d5bba1e8..b76dc0b85 100644 --- a/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java +++ b/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java @@ -43,6 +43,7 @@ import org.geysermc.erosion.packet.backendbound.BackendboundInitializePacket; import org.geysermc.erosion.packet.backendbound.BackendboundPacket; import org.geysermc.erosion.packet.geyserbound.*; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.level.physics.Direction; import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.session.GeyserSession; @@ -119,7 +120,7 @@ public final class GeyserboundPacketHandlerImpl extends AbstractGeyserboundPacke } CompletableFuture future = this.asyncPendingLookups.remove(transactionId); if (future != null) { - future.complete(BlockStateValues.JAVA_AIR_ID); + future.complete(Block.JAVA_AIR_ID); } } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java b/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java index 52759c709..205486ced 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java @@ -29,6 +29,7 @@ import com.fasterxml.jackson.databind.JsonNode; import it.unimi.dsi.fastutil.ints.*; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.level.physics.Direction; import org.geysermc.geyser.level.physics.PistonBehavior; import org.geysermc.geyser.registry.BlockRegistries; @@ -48,7 +49,6 @@ public final class BlockStateValues { private static final Int2IntMap BANNER_COLORS = new FixedInt2IntMap(); private static final Int2ByteMap BED_COLORS = new FixedInt2ByteMap(); private static final Int2IntMap BRUSH_PROGRESS = new Int2IntOpenHashMap(); - private static final Int2ByteMap COMMAND_BLOCK_VALUES = new Int2ByteOpenHashMap(); private static final Int2ObjectMap DOUBLE_CHEST_VALUES = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap FLOWER_POT_VALUES = new Int2ObjectOpenHashMap<>(); private static final IntSet HORIZONTAL_FACING_JIGSAWS = new IntOpenHashSet(); @@ -110,11 +110,6 @@ public final class BlockStateValues { } } - if (javaId.contains("command_block")) { - COMMAND_BLOCK_VALUES.put(javaBlockState, javaId.contains("conditional=true") ? (byte) 1 : (byte) 0); - return; - } - if (blockData.get("double_chest_position") != null) { boolean isX = (blockData.get("x") != null); boolean isDirectionPositive = ((blockData.get("x") != null && blockData.get("x").asBoolean()) || @@ -277,16 +272,6 @@ public final class BlockStateValues { return ALL_CAULDRONS.contains(state); } - /** - * The block state in Java and Bedrock both contain the conditional bit, however command block block entity tags - * in Bedrock need the conditional information. - * - * @return the list of all command blocks and if they are conditional (1 or 0) - */ - public static Int2ByteMap getCommandBlockValues() { - return COMMAND_BLOCK_VALUES; - } - /** * All double chest values are part of the block state in Java and part of the block entity tag in Bedrock. * This gives the DoubleChestValue that can be calculated into the final tag. @@ -356,7 +341,7 @@ public final class BlockStateValues { * @return Block state for the piston head */ public static int getPistonHead(Direction direction) { - return PISTON_HEADS.getOrDefault(direction, BlockStateValues.JAVA_AIR_ID); + return PISTON_HEADS.getOrDefault(direction, Block.JAVA_AIR_ID); } /** @@ -420,7 +405,7 @@ public final class BlockStateValues { } public static boolean canPistonMoveBlock(int javaId, boolean isPushing) { - if (javaId == JAVA_AIR_ID) { + if (javaId == Block.JAVA_AIR_ID) { return true; } // Pistons can only be moved if they aren't extended diff --git a/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java b/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java new file mode 100644 index 000000000..426895269 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java @@ -0,0 +1,2820 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block; + +import org.geysermc.geyser.level.block.type.BannerBlock; +import org.geysermc.geyser.level.block.type.BedBlock; +import org.geysermc.geyser.level.block.type.Block; +import org.geysermc.geyser.level.physics.Axis; +import org.geysermc.geyser.level.physics.Direction; +import org.geysermc.geyser.registry.BlockRegistries; + +import static org.geysermc.geyser.level.block.property.Properties.*; +import static org.geysermc.geyser.level.block.type.Block.builder; + +@SuppressWarnings("unused") +public final class Blocks { + public static final Block AIR = register(new Block("air", builder())); + public static final Block STONE = register(new Block("stone", builder())); + public static final Block GRANITE = register(new Block("granite", builder())); + public static final Block POLISHED_GRANITE = register(new Block("polished_granite", builder())); + public static final Block DIORITE = register(new Block("diorite", builder())); + public static final Block POLISHED_DIORITE = register(new Block("polished_diorite", builder())); + public static final Block ANDESITE = register(new Block("andesite", builder())); + public static final Block POLISHED_ANDESITE = register(new Block("polished_andesite", builder())); + public static final Block GRASS_BLOCK = register(new Block("grass_block", builder() + .booleanState(SNOWY))); + public static final Block DIRT = register(new Block("dirt", builder())); + public static final Block COARSE_DIRT = register(new Block("coarse_dirt", builder())); + public static final Block PODZOL = register(new Block("podzol", builder() + .booleanState(SNOWY))); + public static final Block COBBLESTONE = register(new Block("cobblestone", builder())); + public static final Block OAK_PLANKS = register(new Block("oak_planks", builder())); + public static final Block SPRUCE_PLANKS = register(new Block("spruce_planks", builder())); + public static final Block BIRCH_PLANKS = register(new Block("birch_planks", builder())); + public static final Block JUNGLE_PLANKS = register(new Block("jungle_planks", builder())); + public static final Block ACACIA_PLANKS = register(new Block("acacia_planks", builder())); + public static final Block CHERRY_PLANKS = register(new Block("cherry_planks", builder())); + public static final Block DARK_OAK_PLANKS = register(new Block("dark_oak_planks", builder())); + public static final Block MANGROVE_PLANKS = register(new Block("mangrove_planks", builder())); + public static final Block BAMBOO_PLANKS = register(new Block("bamboo_planks", builder())); + public static final Block BAMBOO_MOSAIC = register(new Block("bamboo_mosaic", builder())); + public static final Block OAK_SAPLING = register(new Block("oak_sapling", builder() + .intState(STAGE, 0, 1))); + public static final Block SPRUCE_SAPLING = register(new Block("spruce_sapling", builder() + .intState(STAGE, 0, 1))); + public static final Block BIRCH_SAPLING = register(new Block("birch_sapling", builder() + .intState(STAGE, 0, 1))); + public static final Block JUNGLE_SAPLING = register(new Block("jungle_sapling", builder() + .intState(STAGE, 0, 1))); + public static final Block ACACIA_SAPLING = register(new Block("acacia_sapling", builder() + .intState(STAGE, 0, 1))); + public static final Block CHERRY_SAPLING = register(new Block("cherry_sapling", builder() + .intState(STAGE, 0, 1))); + public static final Block DARK_OAK_SAPLING = register(new Block("dark_oak_sapling", builder() + .intState(STAGE, 0, 1))); + public static final Block MANGROVE_PROPAGULE = register(new Block("mangrove_propagule", builder() + .intState(AGE_4, 0, 4) + .booleanState(HANGING) + .intState(STAGE, 0, 1) + .booleanState(WATERLOGGED))); + public static final Block BEDROCK = register(new Block("bedrock", builder())); + public static final Block WATER = register(new Block("water", builder() + .intState(LEVEL, 0, 15))); + public static final Block LAVA = register(new Block("lava", builder() + .intState(LEVEL, 0, 15))); + public static final Block SAND = register(new Block("sand", builder())); + public static final Block SUSPICIOUS_SAND = register(new Block("suspicious_sand", builder() + .intState(DUSTED, 0, 3))); + public static final Block RED_SAND = register(new Block("red_sand", builder())); + public static final Block GRAVEL = register(new Block("gravel", builder())); + public static final Block SUSPICIOUS_GRAVEL = register(new Block("suspicious_gravel", builder() + .intState(DUSTED, 0, 3))); + public static final Block GOLD_ORE = register(new Block("gold_ore", builder())); + public static final Block DEEPSLATE_GOLD_ORE = register(new Block("deepslate_gold_ore", builder())); + public static final Block IRON_ORE = register(new Block("iron_ore", builder())); + public static final Block DEEPSLATE_IRON_ORE = register(new Block("deepslate_iron_ore", builder())); + public static final Block COAL_ORE = register(new Block("coal_ore", builder())); + public static final Block DEEPSLATE_COAL_ORE = register(new Block("deepslate_coal_ore", builder())); + public static final Block NETHER_GOLD_ORE = register(new Block("nether_gold_ore", builder())); + public static final Block OAK_LOG = register(new Block("oak_log", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block SPRUCE_LOG = register(new Block("spruce_log", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block BIRCH_LOG = register(new Block("birch_log", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block JUNGLE_LOG = register(new Block("jungle_log", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block ACACIA_LOG = register(new Block("acacia_log", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block CHERRY_LOG = register(new Block("cherry_log", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block DARK_OAK_LOG = register(new Block("dark_oak_log", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block MANGROVE_LOG = register(new Block("mangrove_log", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block MANGROVE_ROOTS = register(new Block("mangrove_roots", builder() + .booleanState(WATERLOGGED))); + public static final Block MUDDY_MANGROVE_ROOTS = register(new Block("muddy_mangrove_roots", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block BAMBOO_BLOCK = register(new Block("bamboo_block", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block STRIPPED_SPRUCE_LOG = register(new Block("stripped_spruce_log", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block STRIPPED_BIRCH_LOG = register(new Block("stripped_birch_log", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block STRIPPED_JUNGLE_LOG = register(new Block("stripped_jungle_log", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block STRIPPED_ACACIA_LOG = register(new Block("stripped_acacia_log", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block STRIPPED_CHERRY_LOG = register(new Block("stripped_cherry_log", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block STRIPPED_DARK_OAK_LOG = register(new Block("stripped_dark_oak_log", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block STRIPPED_OAK_LOG = register(new Block("stripped_oak_log", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block STRIPPED_MANGROVE_LOG = register(new Block("stripped_mangrove_log", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block STRIPPED_BAMBOO_BLOCK = register(new Block("stripped_bamboo_block", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block OAK_WOOD = register(new Block("oak_wood", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block SPRUCE_WOOD = register(new Block("spruce_wood", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block BIRCH_WOOD = register(new Block("birch_wood", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block JUNGLE_WOOD = register(new Block("jungle_wood", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block ACACIA_WOOD = register(new Block("acacia_wood", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block CHERRY_WOOD = register(new Block("cherry_wood", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block DARK_OAK_WOOD = register(new Block("dark_oak_wood", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block MANGROVE_WOOD = register(new Block("mangrove_wood", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block STRIPPED_OAK_WOOD = register(new Block("stripped_oak_wood", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block STRIPPED_SPRUCE_WOOD = register(new Block("stripped_spruce_wood", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block STRIPPED_BIRCH_WOOD = register(new Block("stripped_birch_wood", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block STRIPPED_JUNGLE_WOOD = register(new Block("stripped_jungle_wood", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block STRIPPED_ACACIA_WOOD = register(new Block("stripped_acacia_wood", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block STRIPPED_CHERRY_WOOD = register(new Block("stripped_cherry_wood", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block STRIPPED_DARK_OAK_WOOD = register(new Block("stripped_dark_oak_wood", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block STRIPPED_MANGROVE_WOOD = register(new Block("stripped_mangrove_wood", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block OAK_LEAVES = register(new Block("oak_leaves", builder() + .intState(DISTANCE, 1, 7) + .booleanState(PERSISTENT) + .booleanState(WATERLOGGED))); + public static final Block SPRUCE_LEAVES = register(new Block("spruce_leaves", builder() + .intState(DISTANCE, 1, 7) + .booleanState(PERSISTENT) + .booleanState(WATERLOGGED))); + public static final Block BIRCH_LEAVES = register(new Block("birch_leaves", builder() + .intState(DISTANCE, 1, 7) + .booleanState(PERSISTENT) + .booleanState(WATERLOGGED))); + public static final Block JUNGLE_LEAVES = register(new Block("jungle_leaves", builder() + .intState(DISTANCE, 1, 7) + .booleanState(PERSISTENT) + .booleanState(WATERLOGGED))); + public static final Block ACACIA_LEAVES = register(new Block("acacia_leaves", builder() + .intState(DISTANCE, 1, 7) + .booleanState(PERSISTENT) + .booleanState(WATERLOGGED))); + public static final Block CHERRY_LEAVES = register(new Block("cherry_leaves", builder() + .intState(DISTANCE, 1, 7) + .booleanState(PERSISTENT) + .booleanState(WATERLOGGED))); + public static final Block DARK_OAK_LEAVES = register(new Block("dark_oak_leaves", builder() + .intState(DISTANCE, 1, 7) + .booleanState(PERSISTENT) + .booleanState(WATERLOGGED))); + public static final Block MANGROVE_LEAVES = register(new Block("mangrove_leaves", builder() + .intState(DISTANCE, 1, 7) + .booleanState(PERSISTENT) + .booleanState(WATERLOGGED))); + public static final Block AZALEA_LEAVES = register(new Block("azalea_leaves", builder() + .intState(DISTANCE, 1, 7) + .booleanState(PERSISTENT) + .booleanState(WATERLOGGED))); + public static final Block FLOWERING_AZALEA_LEAVES = register(new Block("flowering_azalea_leaves", builder() + .intState(DISTANCE, 1, 7) + .booleanState(PERSISTENT) + .booleanState(WATERLOGGED))); + public static final Block SPONGE = register(new Block("sponge", builder())); + public static final Block WET_SPONGE = register(new Block("wet_sponge", builder())); + public static final Block GLASS = register(new Block("glass", builder())); + public static final Block LAPIS_ORE = register(new Block("lapis_ore", builder())); + public static final Block DEEPSLATE_LAPIS_ORE = register(new Block("deepslate_lapis_ore", builder())); + public static final Block LAPIS_BLOCK = register(new Block("lapis_block", builder())); + public static final Block DISPENSER = register(new Block("dispenser", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) + .booleanState(TRIGGERED))); + public static final Block SANDSTONE = register(new Block("sandstone", builder())); + public static final Block CHISELED_SANDSTONE = register(new Block("chiseled_sandstone", builder())); + public static final Block CUT_SANDSTONE = register(new Block("cut_sandstone", builder())); + public static final Block NOTE_BLOCK = register(new Block("note_block", builder() + .enumState(NOTEBLOCK_INSTRUMENT, "harp", "basedrum", "snare", "hat", "bass", "flute", "bell", "guitar", "chime", "xylophone", "iron_xylophone", "cow_bell", "didgeridoo", "bit", "banjo", "pling", "zombie", "skeleton", "creeper", "dragon", "wither_skeleton", "piglin", "custom_head") + .intState(NOTE, 0, 24) + .booleanState(POWERED))); + public static final Block WHITE_BED = register(new BedBlock("white_bed", 0, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(OCCUPIED) + .enumState(BED_PART, "head", "foot"))); + public static final Block ORANGE_BED = register(new BedBlock("orange_bed", 1, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(OCCUPIED) + .enumState(BED_PART, "head", "foot"))); + public static final Block MAGENTA_BED = register(new BedBlock("magenta_bed", 2, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(OCCUPIED) + .enumState(BED_PART, "head", "foot"))); + public static final Block LIGHT_BLUE_BED = register(new BedBlock("light_blue_bed", 3, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(OCCUPIED) + .enumState(BED_PART, "head", "foot"))); + public static final Block YELLOW_BED = register(new BedBlock("yellow_bed", 4, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(OCCUPIED) + .enumState(BED_PART, "head", "foot"))); + public static final Block LIME_BED = register(new BedBlock("lime_bed", 5, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(OCCUPIED) + .enumState(BED_PART, "head", "foot"))); + public static final Block PINK_BED = register(new BedBlock("pink_bed", 6, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(OCCUPIED) + .enumState(BED_PART, "head", "foot"))); + public static final Block GRAY_BED = register(new BedBlock("gray_bed", 7, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(OCCUPIED) + .enumState(BED_PART, "head", "foot"))); + public static final Block LIGHT_GRAY_BED = register(new BedBlock("light_gray_bed", 8, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(OCCUPIED) + .enumState(BED_PART, "head", "foot"))); + public static final Block CYAN_BED = register(new BedBlock("cyan_bed", 9, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(OCCUPIED) + .enumState(BED_PART, "head", "foot"))); + public static final Block PURPLE_BED = register(new BedBlock("purple_bed", 10, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(OCCUPIED) + .enumState(BED_PART, "head", "foot"))); + public static final Block BLUE_BED = register(new BedBlock("blue_bed", 11, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(OCCUPIED) + .enumState(BED_PART, "head", "foot"))); + public static final Block BROWN_BED = register(new BedBlock("brown_bed", 12, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(OCCUPIED) + .enumState(BED_PART, "head", "foot"))); + public static final Block GREEN_BED = register(new BedBlock("green_bed", 13, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(OCCUPIED) + .enumState(BED_PART, "head", "foot"))); + public static final Block RED_BED = register(new BedBlock("red_bed", 14, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(OCCUPIED) + .enumState(BED_PART, "head", "foot"))); + public static final Block BLACK_BED = register(new BedBlock("black_bed", 15, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(OCCUPIED) + .enumState(BED_PART, "head", "foot"))); + public static final Block POWERED_RAIL = register(new Block("powered_rail", builder() + .booleanState(POWERED) + .enumState(RAIL_SHAPE_STRAIGHT, "north_south", "east_west", "ascending_east", "ascending_west", "ascending_north", "ascending_south") + .booleanState(WATERLOGGED))); + public static final Block DETECTOR_RAIL = register(new Block("detector_rail", builder() + .booleanState(POWERED) + .enumState(RAIL_SHAPE_STRAIGHT, "north_south", "east_west", "ascending_east", "ascending_west", "ascending_north", "ascending_south") + .booleanState(WATERLOGGED))); + public static final Block STICKY_PISTON = register(new Block("sticky_piston", builder() + .booleanState(EXTENDED) + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); + public static final Block COBWEB = register(new Block("cobweb", builder())); + public static final Block SHORT_GRASS = register(new Block("short_grass", builder())); + public static final Block FERN = register(new Block("fern", builder())); + public static final Block DEAD_BUSH = register(new Block("dead_bush", builder())); + public static final Block SEAGRASS = register(new Block("seagrass", builder())); + public static final Block TALL_SEAGRASS = register(new Block("tall_seagrass", builder() + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); + public static final Block PISTON = register(new Block("piston", builder() + .booleanState(EXTENDED) + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); + public static final Block PISTON_HEAD = register(new Block("piston_head", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) + .booleanState(SHORT) + .enumState(PISTON_TYPE, "normal", "sticky"))); + public static final Block WHITE_WOOL = register(new Block("white_wool", builder())); + public static final Block ORANGE_WOOL = register(new Block("orange_wool", builder())); + public static final Block MAGENTA_WOOL = register(new Block("magenta_wool", builder())); + public static final Block LIGHT_BLUE_WOOL = register(new Block("light_blue_wool", builder())); + public static final Block YELLOW_WOOL = register(new Block("yellow_wool", builder())); + public static final Block LIME_WOOL = register(new Block("lime_wool", builder())); + public static final Block PINK_WOOL = register(new Block("pink_wool", builder())); + public static final Block GRAY_WOOL = register(new Block("gray_wool", builder())); + public static final Block LIGHT_GRAY_WOOL = register(new Block("light_gray_wool", builder())); + public static final Block CYAN_WOOL = register(new Block("cyan_wool", builder())); + public static final Block PURPLE_WOOL = register(new Block("purple_wool", builder())); + public static final Block BLUE_WOOL = register(new Block("blue_wool", builder())); + public static final Block BROWN_WOOL = register(new Block("brown_wool", builder())); + public static final Block GREEN_WOOL = register(new Block("green_wool", builder())); + public static final Block RED_WOOL = register(new Block("red_wool", builder())); + public static final Block BLACK_WOOL = register(new Block("black_wool", builder())); + public static final Block MOVING_PISTON = register(new Block("moving_piston", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) + .enumState(PISTON_TYPE, "normal", "sticky"))); + public static final Block DANDELION = register(new Block("dandelion", builder())); + public static final Block TORCHFLOWER = register(new Block("torchflower", builder())); + public static final Block POPPY = register(new Block("poppy", builder())); + public static final Block BLUE_ORCHID = register(new Block("blue_orchid", builder())); + public static final Block ALLIUM = register(new Block("allium", builder())); + public static final Block AZURE_BLUET = register(new Block("azure_bluet", builder())); + public static final Block RED_TULIP = register(new Block("red_tulip", builder())); + public static final Block ORANGE_TULIP = register(new Block("orange_tulip", builder())); + public static final Block WHITE_TULIP = register(new Block("white_tulip", builder())); + public static final Block PINK_TULIP = register(new Block("pink_tulip", builder())); + public static final Block OXEYE_DAISY = register(new Block("oxeye_daisy", builder())); + public static final Block CORNFLOWER = register(new Block("cornflower", builder())); + public static final Block WITHER_ROSE = register(new Block("wither_rose", builder())); + public static final Block LILY_OF_THE_VALLEY = register(new Block("lily_of_the_valley", builder())); + public static final Block BROWN_MUSHROOM = register(new Block("brown_mushroom", builder())); + public static final Block RED_MUSHROOM = register(new Block("red_mushroom", builder())); + public static final Block GOLD_BLOCK = register(new Block("gold_block", builder())); + public static final Block IRON_BLOCK = register(new Block("iron_block", builder())); + public static final Block BRICKS = register(new Block("bricks", builder())); + public static final Block TNT = register(new Block("tnt", builder() + .booleanState(UNSTABLE))); + public static final Block BOOKSHELF = register(new Block("bookshelf", builder())); + public static final Block CHISELED_BOOKSHELF = register(new Block("chiseled_bookshelf", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(CHISELED_BOOKSHELF_SLOT_0_OCCUPIED) + .booleanState(CHISELED_BOOKSHELF_SLOT_1_OCCUPIED) + .booleanState(CHISELED_BOOKSHELF_SLOT_2_OCCUPIED) + .booleanState(CHISELED_BOOKSHELF_SLOT_3_OCCUPIED) + .booleanState(CHISELED_BOOKSHELF_SLOT_4_OCCUPIED) + .booleanState(CHISELED_BOOKSHELF_SLOT_5_OCCUPIED))); + public static final Block MOSSY_COBBLESTONE = register(new Block("mossy_cobblestone", builder())); + public static final Block OBSIDIAN = register(new Block("obsidian", builder())); + public static final Block TORCH = register(new Block("torch", builder())); + public static final Block WALL_TORCH = register(new Block("wall_torch", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block FIRE = register(new Block("fire", builder() + .intState(AGE_15, 0, 15) + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(UP) + .booleanState(WEST))); + public static final Block SOUL_FIRE = register(new Block("soul_fire", builder())); + public static final Block SPAWNER = register(new Block("spawner", builder())); + public static final Block OAK_STAIRS = register(new Block("oak_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block CHEST = register(new Block("chest", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(CHEST_TYPE, "single", "left", "right") + .booleanState(WATERLOGGED))); + public static final Block REDSTONE_WIRE = register(new Block("redstone_wire", builder() + .enumState(EAST_REDSTONE, "up", "side", "none") + .enumState(NORTH_REDSTONE, "up", "side", "none") + .intState(POWER, 0, 15) + .enumState(SOUTH_REDSTONE, "up", "side", "none") + .enumState(WEST_REDSTONE, "up", "side", "none"))); + public static final Block DIAMOND_ORE = register(new Block("diamond_ore", builder())); + public static final Block DEEPSLATE_DIAMOND_ORE = register(new Block("deepslate_diamond_ore", builder())); + public static final Block DIAMOND_BLOCK = register(new Block("diamond_block", builder())); + public static final Block CRAFTING_TABLE = register(new Block("crafting_table", builder())); + public static final Block WHEAT = register(new Block("wheat", builder() + .intState(AGE_7, 0, 7))); + public static final Block FARMLAND = register(new Block("farmland", builder() + .intState(MOISTURE, 0, 7))); + public static final Block FURNACE = register(new Block("furnace", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(LIT))); + public static final Block OAK_SIGN = register(new Block("oak_sign", builder() + .intState(ROTATION_16, 0, 15) + .booleanState(WATERLOGGED))); + public static final Block SPRUCE_SIGN = register(new Block("spruce_sign", builder() + .intState(ROTATION_16, 0, 15) + .booleanState(WATERLOGGED))); + public static final Block BIRCH_SIGN = register(new Block("birch_sign", builder() + .intState(ROTATION_16, 0, 15) + .booleanState(WATERLOGGED))); + public static final Block ACACIA_SIGN = register(new Block("acacia_sign", builder() + .intState(ROTATION_16, 0, 15) + .booleanState(WATERLOGGED))); + public static final Block CHERRY_SIGN = register(new Block("cherry_sign", builder() + .intState(ROTATION_16, 0, 15) + .booleanState(WATERLOGGED))); + public static final Block JUNGLE_SIGN = register(new Block("jungle_sign", builder() + .intState(ROTATION_16, 0, 15) + .booleanState(WATERLOGGED))); + public static final Block DARK_OAK_SIGN = register(new Block("dark_oak_sign", builder() + .intState(ROTATION_16, 0, 15) + .booleanState(WATERLOGGED))); + public static final Block MANGROVE_SIGN = register(new Block("mangrove_sign", builder() + .intState(ROTATION_16, 0, 15) + .booleanState(WATERLOGGED))); + public static final Block BAMBOO_SIGN = register(new Block("bamboo_sign", builder() + .intState(ROTATION_16, 0, 15) + .booleanState(WATERLOGGED))); + public static final Block OAK_DOOR = register(new Block("oak_door", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") + .enumState(DOOR_HINGE, "left", "right") + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block LADDER = register(new Block("ladder", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block RAIL = register(new Block("rail", builder() + .enumState(RAIL_SHAPE, "north_south", "east_west", "ascending_east", "ascending_west", "ascending_north", "ascending_south", "south_east", "south_west", "north_west", "north_east") + .booleanState(WATERLOGGED))); + public static final Block COBBLESTONE_STAIRS = register(new Block("cobblestone_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block OAK_WALL_SIGN = register(new Block("oak_wall_sign", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block SPRUCE_WALL_SIGN = register(new Block("spruce_wall_sign", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block BIRCH_WALL_SIGN = register(new Block("birch_wall_sign", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block ACACIA_WALL_SIGN = register(new Block("acacia_wall_sign", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block CHERRY_WALL_SIGN = register(new Block("cherry_wall_sign", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block JUNGLE_WALL_SIGN = register(new Block("jungle_wall_sign", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block DARK_OAK_WALL_SIGN = register(new Block("dark_oak_wall_sign", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block MANGROVE_WALL_SIGN = register(new Block("mangrove_wall_sign", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block BAMBOO_WALL_SIGN = register(new Block("bamboo_wall_sign", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block OAK_HANGING_SIGN = register(new Block("oak_hanging_sign", builder() + .booleanState(ATTACHED) + .intState(ROTATION_16, 0, 15) + .booleanState(WATERLOGGED))); + public static final Block SPRUCE_HANGING_SIGN = register(new Block("spruce_hanging_sign", builder() + .booleanState(ATTACHED) + .intState(ROTATION_16, 0, 15) + .booleanState(WATERLOGGED))); + public static final Block BIRCH_HANGING_SIGN = register(new Block("birch_hanging_sign", builder() + .booleanState(ATTACHED) + .intState(ROTATION_16, 0, 15) + .booleanState(WATERLOGGED))); + public static final Block ACACIA_HANGING_SIGN = register(new Block("acacia_hanging_sign", builder() + .booleanState(ATTACHED) + .intState(ROTATION_16, 0, 15) + .booleanState(WATERLOGGED))); + public static final Block CHERRY_HANGING_SIGN = register(new Block("cherry_hanging_sign", builder() + .booleanState(ATTACHED) + .intState(ROTATION_16, 0, 15) + .booleanState(WATERLOGGED))); + public static final Block JUNGLE_HANGING_SIGN = register(new Block("jungle_hanging_sign", builder() + .booleanState(ATTACHED) + .intState(ROTATION_16, 0, 15) + .booleanState(WATERLOGGED))); + public static final Block DARK_OAK_HANGING_SIGN = register(new Block("dark_oak_hanging_sign", builder() + .booleanState(ATTACHED) + .intState(ROTATION_16, 0, 15) + .booleanState(WATERLOGGED))); + public static final Block CRIMSON_HANGING_SIGN = register(new Block("crimson_hanging_sign", builder() + .booleanState(ATTACHED) + .intState(ROTATION_16, 0, 15) + .booleanState(WATERLOGGED))); + public static final Block WARPED_HANGING_SIGN = register(new Block("warped_hanging_sign", builder() + .booleanState(ATTACHED) + .intState(ROTATION_16, 0, 15) + .booleanState(WATERLOGGED))); + public static final Block MANGROVE_HANGING_SIGN = register(new Block("mangrove_hanging_sign", builder() + .booleanState(ATTACHED) + .intState(ROTATION_16, 0, 15) + .booleanState(WATERLOGGED))); + public static final Block BAMBOO_HANGING_SIGN = register(new Block("bamboo_hanging_sign", builder() + .booleanState(ATTACHED) + .intState(ROTATION_16, 0, 15) + .booleanState(WATERLOGGED))); + public static final Block OAK_WALL_HANGING_SIGN = register(new Block("oak_wall_hanging_sign", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block SPRUCE_WALL_HANGING_SIGN = register(new Block("spruce_wall_hanging_sign", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block BIRCH_WALL_HANGING_SIGN = register(new Block("birch_wall_hanging_sign", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block ACACIA_WALL_HANGING_SIGN = register(new Block("acacia_wall_hanging_sign", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block CHERRY_WALL_HANGING_SIGN = register(new Block("cherry_wall_hanging_sign", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block JUNGLE_WALL_HANGING_SIGN = register(new Block("jungle_wall_hanging_sign", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block DARK_OAK_WALL_HANGING_SIGN = register(new Block("dark_oak_wall_hanging_sign", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block MANGROVE_WALL_HANGING_SIGN = register(new Block("mangrove_wall_hanging_sign", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block CRIMSON_WALL_HANGING_SIGN = register(new Block("crimson_wall_hanging_sign", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block WARPED_WALL_HANGING_SIGN = register(new Block("warped_wall_hanging_sign", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block BAMBOO_WALL_HANGING_SIGN = register(new Block("bamboo_wall_hanging_sign", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block LEVER = register(new Block("lever", builder() + .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(POWERED))); + public static final Block STONE_PRESSURE_PLATE = register(new Block("stone_pressure_plate", builder() + .booleanState(POWERED))); + public static final Block IRON_DOOR = register(new Block("iron_door", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") + .enumState(DOOR_HINGE, "left", "right") + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block OAK_PRESSURE_PLATE = register(new Block("oak_pressure_plate", builder() + .booleanState(POWERED))); + public static final Block SPRUCE_PRESSURE_PLATE = register(new Block("spruce_pressure_plate", builder() + .booleanState(POWERED))); + public static final Block BIRCH_PRESSURE_PLATE = register(new Block("birch_pressure_plate", builder() + .booleanState(POWERED))); + public static final Block JUNGLE_PRESSURE_PLATE = register(new Block("jungle_pressure_plate", builder() + .booleanState(POWERED))); + public static final Block ACACIA_PRESSURE_PLATE = register(new Block("acacia_pressure_plate", builder() + .booleanState(POWERED))); + public static final Block CHERRY_PRESSURE_PLATE = register(new Block("cherry_pressure_plate", builder() + .booleanState(POWERED))); + public static final Block DARK_OAK_PRESSURE_PLATE = register(new Block("dark_oak_pressure_plate", builder() + .booleanState(POWERED))); + public static final Block MANGROVE_PRESSURE_PLATE = register(new Block("mangrove_pressure_plate", builder() + .booleanState(POWERED))); + public static final Block BAMBOO_PRESSURE_PLATE = register(new Block("bamboo_pressure_plate", builder() + .booleanState(POWERED))); + public static final Block REDSTONE_ORE = register(new Block("redstone_ore", builder() + .booleanState(LIT))); + public static final Block DEEPSLATE_REDSTONE_ORE = register(new Block("deepslate_redstone_ore", builder() + .booleanState(LIT))); + public static final Block REDSTONE_TORCH = register(new Block("redstone_torch", builder() + .booleanState(LIT))); + public static final Block REDSTONE_WALL_TORCH = register(new Block("redstone_wall_torch", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(LIT))); + public static final Block STONE_BUTTON = register(new Block("stone_button", builder() + .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(POWERED))); + public static final Block SNOW = register(new Block("snow", builder() + .intState(LAYERS, 1, 8))); + public static final Block ICE = register(new Block("ice", builder())); + public static final Block SNOW_BLOCK = register(new Block("snow_block", builder())); + public static final Block CACTUS = register(new Block("cactus", builder() + .intState(AGE_15, 0, 15))); + public static final Block CLAY = register(new Block("clay", builder())); + public static final Block SUGAR_CANE = register(new Block("sugar_cane", builder() + .intState(AGE_15, 0, 15))); + public static final Block JUKEBOX = register(new Block("jukebox", builder() + .booleanState(HAS_RECORD))); + public static final Block OAK_FENCE = register(new Block("oak_fence", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block NETHERRACK = register(new Block("netherrack", builder())); + public static final Block SOUL_SAND = register(new Block("soul_sand", builder())); + public static final Block SOUL_SOIL = register(new Block("soul_soil", builder())); + public static final Block BASALT = register(new Block("basalt", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block POLISHED_BASALT = register(new Block("polished_basalt", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block SOUL_TORCH = register(new Block("soul_torch", builder())); + public static final Block SOUL_WALL_TORCH = register(new Block("soul_wall_torch", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block GLOWSTONE = register(new Block("glowstone", builder())); + public static final Block NETHER_PORTAL = register(new Block("nether_portal", builder() + .enumState(HORIZONTAL_AXIS, Axis.X, Axis.Z))); + public static final Block CARVED_PUMPKIN = register(new Block("carved_pumpkin", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block JACK_O_LANTERN = register(new Block("jack_o_lantern", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block CAKE = register(new Block("cake", builder() + .intState(BITES, 0, 6))); + public static final Block REPEATER = register(new Block("repeater", builder() + .intState(DELAY, 1, 4) + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(LOCKED) + .booleanState(POWERED))); + public static final Block WHITE_STAINED_GLASS = register(new Block("white_stained_glass", builder())); + public static final Block ORANGE_STAINED_GLASS = register(new Block("orange_stained_glass", builder())); + public static final Block MAGENTA_STAINED_GLASS = register(new Block("magenta_stained_glass", builder())); + public static final Block LIGHT_BLUE_STAINED_GLASS = register(new Block("light_blue_stained_glass", builder())); + public static final Block YELLOW_STAINED_GLASS = register(new Block("yellow_stained_glass", builder())); + public static final Block LIME_STAINED_GLASS = register(new Block("lime_stained_glass", builder())); + public static final Block PINK_STAINED_GLASS = register(new Block("pink_stained_glass", builder())); + public static final Block GRAY_STAINED_GLASS = register(new Block("gray_stained_glass", builder())); + public static final Block LIGHT_GRAY_STAINED_GLASS = register(new Block("light_gray_stained_glass", builder())); + public static final Block CYAN_STAINED_GLASS = register(new Block("cyan_stained_glass", builder())); + public static final Block PURPLE_STAINED_GLASS = register(new Block("purple_stained_glass", builder())); + public static final Block BLUE_STAINED_GLASS = register(new Block("blue_stained_glass", builder())); + public static final Block BROWN_STAINED_GLASS = register(new Block("brown_stained_glass", builder())); + public static final Block GREEN_STAINED_GLASS = register(new Block("green_stained_glass", builder())); + public static final Block RED_STAINED_GLASS = register(new Block("red_stained_glass", builder())); + public static final Block BLACK_STAINED_GLASS = register(new Block("black_stained_glass", builder())); + public static final Block OAK_TRAPDOOR = register(new Block("oak_trapdoor", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .booleanState(OPEN) + .booleanState(POWERED) + .booleanState(WATERLOGGED))); + public static final Block SPRUCE_TRAPDOOR = register(new Block("spruce_trapdoor", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .booleanState(OPEN) + .booleanState(POWERED) + .booleanState(WATERLOGGED))); + public static final Block BIRCH_TRAPDOOR = register(new Block("birch_trapdoor", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .booleanState(OPEN) + .booleanState(POWERED) + .booleanState(WATERLOGGED))); + public static final Block JUNGLE_TRAPDOOR = register(new Block("jungle_trapdoor", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .booleanState(OPEN) + .booleanState(POWERED) + .booleanState(WATERLOGGED))); + public static final Block ACACIA_TRAPDOOR = register(new Block("acacia_trapdoor", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .booleanState(OPEN) + .booleanState(POWERED) + .booleanState(WATERLOGGED))); + public static final Block CHERRY_TRAPDOOR = register(new Block("cherry_trapdoor", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .booleanState(OPEN) + .booleanState(POWERED) + .booleanState(WATERLOGGED))); + public static final Block DARK_OAK_TRAPDOOR = register(new Block("dark_oak_trapdoor", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .booleanState(OPEN) + .booleanState(POWERED) + .booleanState(WATERLOGGED))); + public static final Block MANGROVE_TRAPDOOR = register(new Block("mangrove_trapdoor", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .booleanState(OPEN) + .booleanState(POWERED) + .booleanState(WATERLOGGED))); + public static final Block BAMBOO_TRAPDOOR = register(new Block("bamboo_trapdoor", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .booleanState(OPEN) + .booleanState(POWERED) + .booleanState(WATERLOGGED))); + public static final Block STONE_BRICKS = register(new Block("stone_bricks", builder())); + public static final Block MOSSY_STONE_BRICKS = register(new Block("mossy_stone_bricks", builder())); + public static final Block CRACKED_STONE_BRICKS = register(new Block("cracked_stone_bricks", builder())); + public static final Block CHISELED_STONE_BRICKS = register(new Block("chiseled_stone_bricks", builder())); + public static final Block PACKED_MUD = register(new Block("packed_mud", builder())); + public static final Block MUD_BRICKS = register(new Block("mud_bricks", builder())); + public static final Block INFESTED_STONE = register(new Block("infested_stone", builder())); + public static final Block INFESTED_COBBLESTONE = register(new Block("infested_cobblestone", builder())); + public static final Block INFESTED_STONE_BRICKS = register(new Block("infested_stone_bricks", builder())); + public static final Block INFESTED_MOSSY_STONE_BRICKS = register(new Block("infested_mossy_stone_bricks", builder())); + public static final Block INFESTED_CRACKED_STONE_BRICKS = register(new Block("infested_cracked_stone_bricks", builder())); + public static final Block INFESTED_CHISELED_STONE_BRICKS = register(new Block("infested_chiseled_stone_bricks", builder())); + public static final Block BROWN_MUSHROOM_BLOCK = register(new Block("brown_mushroom_block", builder() + .booleanState(DOWN) + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(UP) + .booleanState(WEST))); + public static final Block RED_MUSHROOM_BLOCK = register(new Block("red_mushroom_block", builder() + .booleanState(DOWN) + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(UP) + .booleanState(WEST))); + public static final Block MUSHROOM_STEM = register(new Block("mushroom_stem", builder() + .booleanState(DOWN) + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(UP) + .booleanState(WEST))); + public static final Block IRON_BARS = register(new Block("iron_bars", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block CHAIN = register(new Block("chain", builder() + .enumState(AXIS, Axis.VALUES) + .booleanState(WATERLOGGED))); + public static final Block GLASS_PANE = register(new Block("glass_pane", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block PUMPKIN = register(new Block("pumpkin", builder())); + public static final Block MELON = register(new Block("melon", builder())); + public static final Block ATTACHED_PUMPKIN_STEM = register(new Block("attached_pumpkin_stem", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block ATTACHED_MELON_STEM = register(new Block("attached_melon_stem", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block PUMPKIN_STEM = register(new Block("pumpkin_stem", builder() + .intState(AGE_7, 0, 7))); + public static final Block MELON_STEM = register(new Block("melon_stem", builder() + .intState(AGE_7, 0, 7))); + public static final Block VINE = register(new Block("vine", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(UP) + .booleanState(WEST))); + public static final Block GLOW_LICHEN = register(new Block("glow_lichen", builder() + .booleanState(DOWN) + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(UP) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block OAK_FENCE_GATE = register(new Block("oak_fence_gate", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(IN_WALL) + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block BRICK_STAIRS = register(new Block("brick_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block STONE_BRICK_STAIRS = register(new Block("stone_brick_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block MUD_BRICK_STAIRS = register(new Block("mud_brick_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block MYCELIUM = register(new Block("mycelium", builder() + .booleanState(SNOWY))); + public static final Block LILY_PAD = register(new Block("lily_pad", builder())); + public static final Block NETHER_BRICKS = register(new Block("nether_bricks", builder())); + public static final Block NETHER_BRICK_FENCE = register(new Block("nether_brick_fence", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block NETHER_BRICK_STAIRS = register(new Block("nether_brick_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block NETHER_WART = register(new Block("nether_wart", builder() + .intState(AGE_3, 0, 3))); + public static final Block ENCHANTING_TABLE = register(new Block("enchanting_table", builder())); + public static final Block BREWING_STAND = register(new Block("brewing_stand", builder() + .booleanState(HAS_BOTTLE_0) + .booleanState(HAS_BOTTLE_1) + .booleanState(HAS_BOTTLE_2))); + public static final Block CAULDRON = register(new Block("cauldron", builder())); + public static final Block WATER_CAULDRON = register(new Block("water_cauldron", builder() + .intState(LEVEL_CAULDRON, 1, 3))); + public static final Block LAVA_CAULDRON = register(new Block("lava_cauldron", builder())); + public static final Block POWDER_SNOW_CAULDRON = register(new Block("powder_snow_cauldron", builder() + .intState(LEVEL_CAULDRON, 1, 3))); + public static final Block END_PORTAL = register(new Block("end_portal", builder())); + public static final Block END_PORTAL_FRAME = register(new Block("end_portal_frame", builder() + .booleanState(EYE) + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block END_STONE = register(new Block("end_stone", builder())); + public static final Block DRAGON_EGG = register(new Block("dragon_egg", builder())); + public static final Block REDSTONE_LAMP = register(new Block("redstone_lamp", builder() + .booleanState(LIT))); + public static final Block COCOA = register(new Block("cocoa", builder() + .intState(AGE_2, 0, 2) + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block SANDSTONE_STAIRS = register(new Block("sandstone_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block EMERALD_ORE = register(new Block("emerald_ore", builder())); + public static final Block DEEPSLATE_EMERALD_ORE = register(new Block("deepslate_emerald_ore", builder())); + public static final Block ENDER_CHEST = register(new Block("ender_chest", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block TRIPWIRE_HOOK = register(new Block("tripwire_hook", builder() + .booleanState(ATTACHED) + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(POWERED))); + public static final Block TRIPWIRE = register(new Block("tripwire", builder() + .booleanState(ATTACHED) + .booleanState(DISARMED) + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(POWERED) + .booleanState(SOUTH) + .booleanState(WEST))); + public static final Block EMERALD_BLOCK = register(new Block("emerald_block", builder())); + public static final Block SPRUCE_STAIRS = register(new Block("spruce_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block BIRCH_STAIRS = register(new Block("birch_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block JUNGLE_STAIRS = register(new Block("jungle_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block COMMAND_BLOCK = register(new Block("command_block", builder() + .booleanState(CONDITIONAL) + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); + public static final Block BEACON = register(new Block("beacon", builder())); + public static final Block COBBLESTONE_WALL = register(new Block("cobblestone_wall", builder() + .enumState(EAST_WALL, "none", "low", "tall") + .enumState(NORTH_WALL, "none", "low", "tall") + .enumState(SOUTH_WALL, "none", "low", "tall") + .booleanState(UP) + .booleanState(WATERLOGGED) + .enumState(WEST_WALL, "none", "low", "tall"))); + public static final Block MOSSY_COBBLESTONE_WALL = register(new Block("mossy_cobblestone_wall", builder() + .enumState(EAST_WALL, "none", "low", "tall") + .enumState(NORTH_WALL, "none", "low", "tall") + .enumState(SOUTH_WALL, "none", "low", "tall") + .booleanState(UP) + .booleanState(WATERLOGGED) + .enumState(WEST_WALL, "none", "low", "tall"))); + public static final Block FLOWER_POT = register(new Block("flower_pot", builder())); + public static final Block POTTED_TORCHFLOWER = register(new Block("potted_torchflower", builder())); + public static final Block POTTED_OAK_SAPLING = register(new Block("potted_oak_sapling", builder())); + public static final Block POTTED_SPRUCE_SAPLING = register(new Block("potted_spruce_sapling", builder())); + public static final Block POTTED_BIRCH_SAPLING = register(new Block("potted_birch_sapling", builder())); + public static final Block POTTED_JUNGLE_SAPLING = register(new Block("potted_jungle_sapling", builder())); + public static final Block POTTED_ACACIA_SAPLING = register(new Block("potted_acacia_sapling", builder())); + public static final Block POTTED_CHERRY_SAPLING = register(new Block("potted_cherry_sapling", builder())); + public static final Block POTTED_DARK_OAK_SAPLING = register(new Block("potted_dark_oak_sapling", builder())); + public static final Block POTTED_MANGROVE_PROPAGULE = register(new Block("potted_mangrove_propagule", builder())); + public static final Block POTTED_FERN = register(new Block("potted_fern", builder())); + public static final Block POTTED_DANDELION = register(new Block("potted_dandelion", builder())); + public static final Block POTTED_POPPY = register(new Block("potted_poppy", builder())); + public static final Block POTTED_BLUE_ORCHID = register(new Block("potted_blue_orchid", builder())); + public static final Block POTTED_ALLIUM = register(new Block("potted_allium", builder())); + public static final Block POTTED_AZURE_BLUET = register(new Block("potted_azure_bluet", builder())); + public static final Block POTTED_RED_TULIP = register(new Block("potted_red_tulip", builder())); + public static final Block POTTED_ORANGE_TULIP = register(new Block("potted_orange_tulip", builder())); + public static final Block POTTED_WHITE_TULIP = register(new Block("potted_white_tulip", builder())); + public static final Block POTTED_PINK_TULIP = register(new Block("potted_pink_tulip", builder())); + public static final Block POTTED_OXEYE_DAISY = register(new Block("potted_oxeye_daisy", builder())); + public static final Block POTTED_CORNFLOWER = register(new Block("potted_cornflower", builder())); + public static final Block POTTED_LILY_OF_THE_VALLEY = register(new Block("potted_lily_of_the_valley", builder())); + public static final Block POTTED_WITHER_ROSE = register(new Block("potted_wither_rose", builder())); + public static final Block POTTED_RED_MUSHROOM = register(new Block("potted_red_mushroom", builder())); + public static final Block POTTED_BROWN_MUSHROOM = register(new Block("potted_brown_mushroom", builder())); + public static final Block POTTED_DEAD_BUSH = register(new Block("potted_dead_bush", builder())); + public static final Block POTTED_CACTUS = register(new Block("potted_cactus", builder())); + public static final Block CARROTS = register(new Block("carrots", builder() + .intState(AGE_7, 0, 7))); + public static final Block POTATOES = register(new Block("potatoes", builder() + .intState(AGE_7, 0, 7))); + public static final Block OAK_BUTTON = register(new Block("oak_button", builder() + .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(POWERED))); + public static final Block SPRUCE_BUTTON = register(new Block("spruce_button", builder() + .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(POWERED))); + public static final Block BIRCH_BUTTON = register(new Block("birch_button", builder() + .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(POWERED))); + public static final Block JUNGLE_BUTTON = register(new Block("jungle_button", builder() + .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(POWERED))); + public static final Block ACACIA_BUTTON = register(new Block("acacia_button", builder() + .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(POWERED))); + public static final Block CHERRY_BUTTON = register(new Block("cherry_button", builder() + .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(POWERED))); + public static final Block DARK_OAK_BUTTON = register(new Block("dark_oak_button", builder() + .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(POWERED))); + public static final Block MANGROVE_BUTTON = register(new Block("mangrove_button", builder() + .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(POWERED))); + public static final Block BAMBOO_BUTTON = register(new Block("bamboo_button", builder() + .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(POWERED))); + public static final Block SKELETON_SKULL = register(new Block("skeleton_skull", builder() + .booleanState(POWERED) + .intState(ROTATION_16, 0, 15))); + public static final Block SKELETON_WALL_SKULL = register(new Block("skeleton_wall_skull", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(POWERED))); + public static final Block WITHER_SKELETON_SKULL = register(new Block("wither_skeleton_skull", builder() + .booleanState(POWERED) + .intState(ROTATION_16, 0, 15))); + public static final Block WITHER_SKELETON_WALL_SKULL = register(new Block("wither_skeleton_wall_skull", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(POWERED))); + public static final Block ZOMBIE_HEAD = register(new Block("zombie_head", builder() + .booleanState(POWERED) + .intState(ROTATION_16, 0, 15))); + public static final Block ZOMBIE_WALL_HEAD = register(new Block("zombie_wall_head", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(POWERED))); + public static final Block PLAYER_HEAD = register(new Block("player_head", builder() + .booleanState(POWERED) + .intState(ROTATION_16, 0, 15))); + public static final Block PLAYER_WALL_HEAD = register(new Block("player_wall_head", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(POWERED))); + public static final Block CREEPER_HEAD = register(new Block("creeper_head", builder() + .booleanState(POWERED) + .intState(ROTATION_16, 0, 15))); + public static final Block CREEPER_WALL_HEAD = register(new Block("creeper_wall_head", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(POWERED))); + public static final Block DRAGON_HEAD = register(new Block("dragon_head", builder() + .booleanState(POWERED) + .intState(ROTATION_16, 0, 15))); + public static final Block DRAGON_WALL_HEAD = register(new Block("dragon_wall_head", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(POWERED))); + public static final Block PIGLIN_HEAD = register(new Block("piglin_head", builder() + .booleanState(POWERED) + .intState(ROTATION_16, 0, 15))); + public static final Block PIGLIN_WALL_HEAD = register(new Block("piglin_wall_head", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(POWERED))); + public static final Block ANVIL = register(new Block("anvil", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block CHIPPED_ANVIL = register(new Block("chipped_anvil", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block DAMAGED_ANVIL = register(new Block("damaged_anvil", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block TRAPPED_CHEST = register(new Block("trapped_chest", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(CHEST_TYPE, "single", "left", "right") + .booleanState(WATERLOGGED))); + public static final Block LIGHT_WEIGHTED_PRESSURE_PLATE = register(new Block("light_weighted_pressure_plate", builder() + .intState(POWER, 0, 15))); + public static final Block HEAVY_WEIGHTED_PRESSURE_PLATE = register(new Block("heavy_weighted_pressure_plate", builder() + .intState(POWER, 0, 15))); + public static final Block COMPARATOR = register(new Block("comparator", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(MODE_COMPARATOR, "compare", "subtract") + .booleanState(POWERED))); + public static final Block DAYLIGHT_DETECTOR = register(new Block("daylight_detector", builder() + .booleanState(INVERTED) + .intState(POWER, 0, 15))); + public static final Block REDSTONE_BLOCK = register(new Block("redstone_block", builder())); + public static final Block NETHER_QUARTZ_ORE = register(new Block("nether_quartz_ore", builder())); + public static final Block HOPPER = register(new Block("hopper", builder() + .booleanState(ENABLED) + .enumState(FACING_HOPPER, Direction.DOWN, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block QUARTZ_BLOCK = register(new Block("quartz_block", builder())); + public static final Block CHISELED_QUARTZ_BLOCK = register(new Block("chiseled_quartz_block", builder())); + public static final Block QUARTZ_PILLAR = register(new Block("quartz_pillar", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block QUARTZ_STAIRS = register(new Block("quartz_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block ACTIVATOR_RAIL = register(new Block("activator_rail", builder() + .booleanState(POWERED) + .enumState(RAIL_SHAPE_STRAIGHT, "north_south", "east_west", "ascending_east", "ascending_west", "ascending_north", "ascending_south") + .booleanState(WATERLOGGED))); + public static final Block DROPPER = register(new Block("dropper", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) + .booleanState(TRIGGERED))); + public static final Block WHITE_TERRACOTTA = register(new Block("white_terracotta", builder())); + public static final Block ORANGE_TERRACOTTA = register(new Block("orange_terracotta", builder())); + public static final Block MAGENTA_TERRACOTTA = register(new Block("magenta_terracotta", builder())); + public static final Block LIGHT_BLUE_TERRACOTTA = register(new Block("light_blue_terracotta", builder())); + public static final Block YELLOW_TERRACOTTA = register(new Block("yellow_terracotta", builder())); + public static final Block LIME_TERRACOTTA = register(new Block("lime_terracotta", builder())); + public static final Block PINK_TERRACOTTA = register(new Block("pink_terracotta", builder())); + public static final Block GRAY_TERRACOTTA = register(new Block("gray_terracotta", builder())); + public static final Block LIGHT_GRAY_TERRACOTTA = register(new Block("light_gray_terracotta", builder())); + public static final Block CYAN_TERRACOTTA = register(new Block("cyan_terracotta", builder())); + public static final Block PURPLE_TERRACOTTA = register(new Block("purple_terracotta", builder())); + public static final Block BLUE_TERRACOTTA = register(new Block("blue_terracotta", builder())); + public static final Block BROWN_TERRACOTTA = register(new Block("brown_terracotta", builder())); + public static final Block GREEN_TERRACOTTA = register(new Block("green_terracotta", builder())); + public static final Block RED_TERRACOTTA = register(new Block("red_terracotta", builder())); + public static final Block BLACK_TERRACOTTA = register(new Block("black_terracotta", builder())); + public static final Block WHITE_STAINED_GLASS_PANE = register(new Block("white_stained_glass_pane", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block ORANGE_STAINED_GLASS_PANE = register(new Block("orange_stained_glass_pane", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block MAGENTA_STAINED_GLASS_PANE = register(new Block("magenta_stained_glass_pane", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block LIGHT_BLUE_STAINED_GLASS_PANE = register(new Block("light_blue_stained_glass_pane", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block YELLOW_STAINED_GLASS_PANE = register(new Block("yellow_stained_glass_pane", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block LIME_STAINED_GLASS_PANE = register(new Block("lime_stained_glass_pane", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block PINK_STAINED_GLASS_PANE = register(new Block("pink_stained_glass_pane", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block GRAY_STAINED_GLASS_PANE = register(new Block("gray_stained_glass_pane", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block LIGHT_GRAY_STAINED_GLASS_PANE = register(new Block("light_gray_stained_glass_pane", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block CYAN_STAINED_GLASS_PANE = register(new Block("cyan_stained_glass_pane", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block PURPLE_STAINED_GLASS_PANE = register(new Block("purple_stained_glass_pane", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block BLUE_STAINED_GLASS_PANE = register(new Block("blue_stained_glass_pane", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block BROWN_STAINED_GLASS_PANE = register(new Block("brown_stained_glass_pane", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block GREEN_STAINED_GLASS_PANE = register(new Block("green_stained_glass_pane", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block RED_STAINED_GLASS_PANE = register(new Block("red_stained_glass_pane", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block BLACK_STAINED_GLASS_PANE = register(new Block("black_stained_glass_pane", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block ACACIA_STAIRS = register(new Block("acacia_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block CHERRY_STAIRS = register(new Block("cherry_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block DARK_OAK_STAIRS = register(new Block("dark_oak_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block MANGROVE_STAIRS = register(new Block("mangrove_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block BAMBOO_STAIRS = register(new Block("bamboo_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block BAMBOO_MOSAIC_STAIRS = register(new Block("bamboo_mosaic_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block SLIME_BLOCK = register(new Block("slime_block", builder())); + public static final Block BARRIER = register(new Block("barrier", builder() + .booleanState(WATERLOGGED))); + public static final Block LIGHT = register(new Block("light", builder() + .intState(LEVEL, 0, 15) + .booleanState(WATERLOGGED))); + public static final Block IRON_TRAPDOOR = register(new Block("iron_trapdoor", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .booleanState(OPEN) + .booleanState(POWERED) + .booleanState(WATERLOGGED))); + public static final Block PRISMARINE = register(new Block("prismarine", builder())); + public static final Block PRISMARINE_BRICKS = register(new Block("prismarine_bricks", builder())); + public static final Block DARK_PRISMARINE = register(new Block("dark_prismarine", builder())); + public static final Block PRISMARINE_STAIRS = register(new Block("prismarine_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block PRISMARINE_BRICK_STAIRS = register(new Block("prismarine_brick_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block DARK_PRISMARINE_STAIRS = register(new Block("dark_prismarine_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block PRISMARINE_SLAB = register(new Block("prismarine_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block PRISMARINE_BRICK_SLAB = register(new Block("prismarine_brick_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block DARK_PRISMARINE_SLAB = register(new Block("dark_prismarine_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block SEA_LANTERN = register(new Block("sea_lantern", builder())); + public static final Block HAY_BLOCK = register(new Block("hay_block", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block WHITE_CARPET = register(new Block("white_carpet", builder())); + public static final Block ORANGE_CARPET = register(new Block("orange_carpet", builder())); + public static final Block MAGENTA_CARPET = register(new Block("magenta_carpet", builder())); + public static final Block LIGHT_BLUE_CARPET = register(new Block("light_blue_carpet", builder())); + public static final Block YELLOW_CARPET = register(new Block("yellow_carpet", builder())); + public static final Block LIME_CARPET = register(new Block("lime_carpet", builder())); + public static final Block PINK_CARPET = register(new Block("pink_carpet", builder())); + public static final Block GRAY_CARPET = register(new Block("gray_carpet", builder())); + public static final Block LIGHT_GRAY_CARPET = register(new Block("light_gray_carpet", builder())); + public static final Block CYAN_CARPET = register(new Block("cyan_carpet", builder())); + public static final Block PURPLE_CARPET = register(new Block("purple_carpet", builder())); + public static final Block BLUE_CARPET = register(new Block("blue_carpet", builder())); + public static final Block BROWN_CARPET = register(new Block("brown_carpet", builder())); + public static final Block GREEN_CARPET = register(new Block("green_carpet", builder())); + public static final Block RED_CARPET = register(new Block("red_carpet", builder())); + public static final Block BLACK_CARPET = register(new Block("black_carpet", builder())); + public static final Block TERRACOTTA = register(new Block("terracotta", builder())); + public static final Block COAL_BLOCK = register(new Block("coal_block", builder())); + public static final Block PACKED_ICE = register(new Block("packed_ice", builder())); + public static final Block SUNFLOWER = register(new Block("sunflower", builder() + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); + public static final Block LILAC = register(new Block("lilac", builder() + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); + public static final Block ROSE_BUSH = register(new Block("rose_bush", builder() + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); + public static final Block PEONY = register(new Block("peony", builder() + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); + public static final Block TALL_GRASS = register(new Block("tall_grass", builder() + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); + public static final Block LARGE_FERN = register(new Block("large_fern", builder() + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); + public static final Block WHITE_BANNER = register(new BannerBlock("white_banner", 0, builder() + .intState(ROTATION_16, 0, 15))); + public static final Block ORANGE_BANNER = register(new BannerBlock("orange_banner", 1, builder() + .intState(ROTATION_16, 0, 15))); + public static final Block MAGENTA_BANNER = register(new BannerBlock("magenta_banner", 2, builder() + .intState(ROTATION_16, 0, 15))); + public static final Block LIGHT_BLUE_BANNER = register(new BannerBlock("light_blue_banner", 3, builder() + .intState(ROTATION_16, 0, 15))); + public static final Block YELLOW_BANNER = register(new BannerBlock("yellow_banner", 4, builder() + .intState(ROTATION_16, 0, 15))); + public static final Block LIME_BANNER = register(new BannerBlock("lime_banner", 5, builder() + .intState(ROTATION_16, 0, 15))); + public static final Block PINK_BANNER = register(new BannerBlock("pink_banner", 6, builder() + .intState(ROTATION_16, 0, 15))); + public static final Block GRAY_BANNER = register(new BannerBlock("gray_banner", 7, builder() + .intState(ROTATION_16, 0, 15))); + public static final Block LIGHT_GRAY_BANNER = register(new BannerBlock("light_gray_banner", 8, builder() + .intState(ROTATION_16, 0, 15))); + public static final Block CYAN_BANNER = register(new BannerBlock("cyan_banner", 9, builder() + .intState(ROTATION_16, 0, 15))); + public static final Block PURPLE_BANNER = register(new BannerBlock("purple_banner", 10, builder() + .intState(ROTATION_16, 0, 15))); + public static final Block BLUE_BANNER = register(new BannerBlock("blue_banner", 11, builder() + .intState(ROTATION_16, 0, 15))); + public static final Block BROWN_BANNER = register(new BannerBlock("brown_banner", 12, builder() + .intState(ROTATION_16, 0, 15))); + public static final Block GREEN_BANNER = register(new BannerBlock("green_banner", 13, builder() + .intState(ROTATION_16, 0, 15))); + public static final Block RED_BANNER = register(new BannerBlock("red_banner", 14, builder() + .intState(ROTATION_16, 0, 15))); + public static final Block BLACK_BANNER = register(new BannerBlock("black_banner", 15, builder() + .intState(ROTATION_16, 0, 15))); + public static final Block WHITE_WALL_BANNER = register(new BannerBlock("white_wall_banner", 0, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block ORANGE_WALL_BANNER = register(new BannerBlock("orange_wall_banner", 1, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block MAGENTA_WALL_BANNER = register(new BannerBlock("magenta_wall_banner", 2, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block LIGHT_BLUE_WALL_BANNER = register(new BannerBlock("light_blue_wall_banner", 3, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block YELLOW_WALL_BANNER = register(new BannerBlock("yellow_wall_banner", 4, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block LIME_WALL_BANNER = register(new BannerBlock("lime_wall_banner", 5, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block PINK_WALL_BANNER = register(new BannerBlock("pink_wall_banner", 6, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block GRAY_WALL_BANNER = register(new BannerBlock("gray_wall_banner", 7, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block LIGHT_GRAY_WALL_BANNER = register(new BannerBlock("light_gray_wall_banner", 8, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block CYAN_WALL_BANNER = register(new BannerBlock("cyan_wall_banner", 9, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block PURPLE_WALL_BANNER = register(new BannerBlock("purple_wall_banner", 10, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block BLUE_WALL_BANNER = register(new BannerBlock("blue_wall_banner", 11, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block BROWN_WALL_BANNER = register(new BannerBlock("brown_wall_banner", 12, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block GREEN_WALL_BANNER = register(new BannerBlock("green_wall_banner", 13, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block RED_WALL_BANNER = register(new BannerBlock("red_wall_banner", 14, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block BLACK_WALL_BANNER = register(new BannerBlock("black_wall_banner", 15, builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block RED_SANDSTONE = register(new Block("red_sandstone", builder())); + public static final Block CHISELED_RED_SANDSTONE = register(new Block("chiseled_red_sandstone", builder())); + public static final Block CUT_RED_SANDSTONE = register(new Block("cut_red_sandstone", builder())); + public static final Block RED_SANDSTONE_STAIRS = register(new Block("red_sandstone_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block OAK_SLAB = register(new Block("oak_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block SPRUCE_SLAB = register(new Block("spruce_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block BIRCH_SLAB = register(new Block("birch_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block JUNGLE_SLAB = register(new Block("jungle_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block ACACIA_SLAB = register(new Block("acacia_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block CHERRY_SLAB = register(new Block("cherry_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block DARK_OAK_SLAB = register(new Block("dark_oak_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block MANGROVE_SLAB = register(new Block("mangrove_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block BAMBOO_SLAB = register(new Block("bamboo_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block BAMBOO_MOSAIC_SLAB = register(new Block("bamboo_mosaic_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block STONE_SLAB = register(new Block("stone_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block SMOOTH_STONE_SLAB = register(new Block("smooth_stone_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block SANDSTONE_SLAB = register(new Block("sandstone_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block CUT_SANDSTONE_SLAB = register(new Block("cut_sandstone_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block PETRIFIED_OAK_SLAB = register(new Block("petrified_oak_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block COBBLESTONE_SLAB = register(new Block("cobblestone_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block BRICK_SLAB = register(new Block("brick_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block STONE_BRICK_SLAB = register(new Block("stone_brick_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block MUD_BRICK_SLAB = register(new Block("mud_brick_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block NETHER_BRICK_SLAB = register(new Block("nether_brick_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block QUARTZ_SLAB = register(new Block("quartz_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block RED_SANDSTONE_SLAB = register(new Block("red_sandstone_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block CUT_RED_SANDSTONE_SLAB = register(new Block("cut_red_sandstone_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block PURPUR_SLAB = register(new Block("purpur_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block SMOOTH_STONE = register(new Block("smooth_stone", builder())); + public static final Block SMOOTH_SANDSTONE = register(new Block("smooth_sandstone", builder())); + public static final Block SMOOTH_QUARTZ = register(new Block("smooth_quartz", builder())); + public static final Block SMOOTH_RED_SANDSTONE = register(new Block("smooth_red_sandstone", builder())); + public static final Block SPRUCE_FENCE_GATE = register(new Block("spruce_fence_gate", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(IN_WALL) + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block BIRCH_FENCE_GATE = register(new Block("birch_fence_gate", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(IN_WALL) + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block JUNGLE_FENCE_GATE = register(new Block("jungle_fence_gate", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(IN_WALL) + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block ACACIA_FENCE_GATE = register(new Block("acacia_fence_gate", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(IN_WALL) + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block CHERRY_FENCE_GATE = register(new Block("cherry_fence_gate", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(IN_WALL) + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block DARK_OAK_FENCE_GATE = register(new Block("dark_oak_fence_gate", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(IN_WALL) + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block MANGROVE_FENCE_GATE = register(new Block("mangrove_fence_gate", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(IN_WALL) + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block BAMBOO_FENCE_GATE = register(new Block("bamboo_fence_gate", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(IN_WALL) + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block SPRUCE_FENCE = register(new Block("spruce_fence", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block BIRCH_FENCE = register(new Block("birch_fence", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block JUNGLE_FENCE = register(new Block("jungle_fence", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block ACACIA_FENCE = register(new Block("acacia_fence", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block CHERRY_FENCE = register(new Block("cherry_fence", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block DARK_OAK_FENCE = register(new Block("dark_oak_fence", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block MANGROVE_FENCE = register(new Block("mangrove_fence", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block BAMBOO_FENCE = register(new Block("bamboo_fence", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block SPRUCE_DOOR = register(new Block("spruce_door", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") + .enumState(DOOR_HINGE, "left", "right") + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block BIRCH_DOOR = register(new Block("birch_door", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") + .enumState(DOOR_HINGE, "left", "right") + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block JUNGLE_DOOR = register(new Block("jungle_door", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") + .enumState(DOOR_HINGE, "left", "right") + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block ACACIA_DOOR = register(new Block("acacia_door", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") + .enumState(DOOR_HINGE, "left", "right") + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block CHERRY_DOOR = register(new Block("cherry_door", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") + .enumState(DOOR_HINGE, "left", "right") + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block DARK_OAK_DOOR = register(new Block("dark_oak_door", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") + .enumState(DOOR_HINGE, "left", "right") + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block MANGROVE_DOOR = register(new Block("mangrove_door", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") + .enumState(DOOR_HINGE, "left", "right") + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block BAMBOO_DOOR = register(new Block("bamboo_door", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") + .enumState(DOOR_HINGE, "left", "right") + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block END_ROD = register(new Block("end_rod", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); + public static final Block CHORUS_PLANT = register(new Block("chorus_plant", builder() + .booleanState(DOWN) + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(UP) + .booleanState(WEST))); + public static final Block CHORUS_FLOWER = register(new Block("chorus_flower", builder() + .intState(AGE_5, 0, 5))); + public static final Block PURPUR_BLOCK = register(new Block("purpur_block", builder())); + public static final Block PURPUR_PILLAR = register(new Block("purpur_pillar", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block PURPUR_STAIRS = register(new Block("purpur_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block END_STONE_BRICKS = register(new Block("end_stone_bricks", builder())); + public static final Block TORCHFLOWER_CROP = register(new Block("torchflower_crop", builder() + .intState(AGE_1, 0, 1))); + public static final Block PITCHER_CROP = register(new Block("pitcher_crop", builder() + .intState(AGE_4, 0, 4) + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); + public static final Block PITCHER_PLANT = register(new Block("pitcher_plant", builder() + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); + public static final Block BEETROOTS = register(new Block("beetroots", builder() + .intState(AGE_3, 0, 3))); + public static final Block DIRT_PATH = register(new Block("dirt_path", builder())); + public static final Block END_GATEWAY = register(new Block("end_gateway", builder())); + public static final Block REPEATING_COMMAND_BLOCK = register(new Block("repeating_command_block", builder() + .booleanState(CONDITIONAL) + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); + public static final Block CHAIN_COMMAND_BLOCK = register(new Block("chain_command_block", builder() + .booleanState(CONDITIONAL) + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); + public static final Block FROSTED_ICE = register(new Block("frosted_ice", builder() + .intState(AGE_3, 0, 3))); + public static final Block MAGMA_BLOCK = register(new Block("magma_block", builder())); + public static final Block NETHER_WART_BLOCK = register(new Block("nether_wart_block", builder())); + public static final Block RED_NETHER_BRICKS = register(new Block("red_nether_bricks", builder())); + public static final Block BONE_BLOCK = register(new Block("bone_block", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block STRUCTURE_VOID = register(new Block("structure_void", builder())); + public static final Block OBSERVER = register(new Block("observer", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) + .booleanState(POWERED))); + public static final Block SHULKER_BOX = register(new Block("shulker_box", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); + public static final Block WHITE_SHULKER_BOX = register(new Block("white_shulker_box", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); + public static final Block ORANGE_SHULKER_BOX = register(new Block("orange_shulker_box", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); + public static final Block MAGENTA_SHULKER_BOX = register(new Block("magenta_shulker_box", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); + public static final Block LIGHT_BLUE_SHULKER_BOX = register(new Block("light_blue_shulker_box", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); + public static final Block YELLOW_SHULKER_BOX = register(new Block("yellow_shulker_box", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); + public static final Block LIME_SHULKER_BOX = register(new Block("lime_shulker_box", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); + public static final Block PINK_SHULKER_BOX = register(new Block("pink_shulker_box", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); + public static final Block GRAY_SHULKER_BOX = register(new Block("gray_shulker_box", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); + public static final Block LIGHT_GRAY_SHULKER_BOX = register(new Block("light_gray_shulker_box", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); + public static final Block CYAN_SHULKER_BOX = register(new Block("cyan_shulker_box", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); + public static final Block PURPLE_SHULKER_BOX = register(new Block("purple_shulker_box", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); + public static final Block BLUE_SHULKER_BOX = register(new Block("blue_shulker_box", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); + public static final Block BROWN_SHULKER_BOX = register(new Block("brown_shulker_box", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); + public static final Block GREEN_SHULKER_BOX = register(new Block("green_shulker_box", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); + public static final Block RED_SHULKER_BOX = register(new Block("red_shulker_box", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); + public static final Block BLACK_SHULKER_BOX = register(new Block("black_shulker_box", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); + public static final Block WHITE_GLAZED_TERRACOTTA = register(new Block("white_glazed_terracotta", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block ORANGE_GLAZED_TERRACOTTA = register(new Block("orange_glazed_terracotta", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block MAGENTA_GLAZED_TERRACOTTA = register(new Block("magenta_glazed_terracotta", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block LIGHT_BLUE_GLAZED_TERRACOTTA = register(new Block("light_blue_glazed_terracotta", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block YELLOW_GLAZED_TERRACOTTA = register(new Block("yellow_glazed_terracotta", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block LIME_GLAZED_TERRACOTTA = register(new Block("lime_glazed_terracotta", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block PINK_GLAZED_TERRACOTTA = register(new Block("pink_glazed_terracotta", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block GRAY_GLAZED_TERRACOTTA = register(new Block("gray_glazed_terracotta", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block LIGHT_GRAY_GLAZED_TERRACOTTA = register(new Block("light_gray_glazed_terracotta", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block CYAN_GLAZED_TERRACOTTA = register(new Block("cyan_glazed_terracotta", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block PURPLE_GLAZED_TERRACOTTA = register(new Block("purple_glazed_terracotta", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block BLUE_GLAZED_TERRACOTTA = register(new Block("blue_glazed_terracotta", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block BROWN_GLAZED_TERRACOTTA = register(new Block("brown_glazed_terracotta", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block GREEN_GLAZED_TERRACOTTA = register(new Block("green_glazed_terracotta", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block RED_GLAZED_TERRACOTTA = register(new Block("red_glazed_terracotta", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block BLACK_GLAZED_TERRACOTTA = register(new Block("black_glazed_terracotta", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block WHITE_CONCRETE = register(new Block("white_concrete", builder())); + public static final Block ORANGE_CONCRETE = register(new Block("orange_concrete", builder())); + public static final Block MAGENTA_CONCRETE = register(new Block("magenta_concrete", builder())); + public static final Block LIGHT_BLUE_CONCRETE = register(new Block("light_blue_concrete", builder())); + public static final Block YELLOW_CONCRETE = register(new Block("yellow_concrete", builder())); + public static final Block LIME_CONCRETE = register(new Block("lime_concrete", builder())); + public static final Block PINK_CONCRETE = register(new Block("pink_concrete", builder())); + public static final Block GRAY_CONCRETE = register(new Block("gray_concrete", builder())); + public static final Block LIGHT_GRAY_CONCRETE = register(new Block("light_gray_concrete", builder())); + public static final Block CYAN_CONCRETE = register(new Block("cyan_concrete", builder())); + public static final Block PURPLE_CONCRETE = register(new Block("purple_concrete", builder())); + public static final Block BLUE_CONCRETE = register(new Block("blue_concrete", builder())); + public static final Block BROWN_CONCRETE = register(new Block("brown_concrete", builder())); + public static final Block GREEN_CONCRETE = register(new Block("green_concrete", builder())); + public static final Block RED_CONCRETE = register(new Block("red_concrete", builder())); + public static final Block BLACK_CONCRETE = register(new Block("black_concrete", builder())); + public static final Block WHITE_CONCRETE_POWDER = register(new Block("white_concrete_powder", builder())); + public static final Block ORANGE_CONCRETE_POWDER = register(new Block("orange_concrete_powder", builder())); + public static final Block MAGENTA_CONCRETE_POWDER = register(new Block("magenta_concrete_powder", builder())); + public static final Block LIGHT_BLUE_CONCRETE_POWDER = register(new Block("light_blue_concrete_powder", builder())); + public static final Block YELLOW_CONCRETE_POWDER = register(new Block("yellow_concrete_powder", builder())); + public static final Block LIME_CONCRETE_POWDER = register(new Block("lime_concrete_powder", builder())); + public static final Block PINK_CONCRETE_POWDER = register(new Block("pink_concrete_powder", builder())); + public static final Block GRAY_CONCRETE_POWDER = register(new Block("gray_concrete_powder", builder())); + public static final Block LIGHT_GRAY_CONCRETE_POWDER = register(new Block("light_gray_concrete_powder", builder())); + public static final Block CYAN_CONCRETE_POWDER = register(new Block("cyan_concrete_powder", builder())); + public static final Block PURPLE_CONCRETE_POWDER = register(new Block("purple_concrete_powder", builder())); + public static final Block BLUE_CONCRETE_POWDER = register(new Block("blue_concrete_powder", builder())); + public static final Block BROWN_CONCRETE_POWDER = register(new Block("brown_concrete_powder", builder())); + public static final Block GREEN_CONCRETE_POWDER = register(new Block("green_concrete_powder", builder())); + public static final Block RED_CONCRETE_POWDER = register(new Block("red_concrete_powder", builder())); + public static final Block BLACK_CONCRETE_POWDER = register(new Block("black_concrete_powder", builder())); + public static final Block KELP = register(new Block("kelp", builder() + .intState(AGE_25, 0, 25))); + public static final Block KELP_PLANT = register(new Block("kelp_plant", builder())); + public static final Block DRIED_KELP_BLOCK = register(new Block("dried_kelp_block", builder())); + public static final Block TURTLE_EGG = register(new Block("turtle_egg", builder() + .intState(EGGS, 1, 4) + .intState(HATCH, 0, 2))); + public static final Block SNIFFER_EGG = register(new Block("sniffer_egg", builder() + .intState(HATCH, 0, 2))); + public static final Block DEAD_TUBE_CORAL_BLOCK = register(new Block("dead_tube_coral_block", builder())); + public static final Block DEAD_BRAIN_CORAL_BLOCK = register(new Block("dead_brain_coral_block", builder())); + public static final Block DEAD_BUBBLE_CORAL_BLOCK = register(new Block("dead_bubble_coral_block", builder())); + public static final Block DEAD_FIRE_CORAL_BLOCK = register(new Block("dead_fire_coral_block", builder())); + public static final Block DEAD_HORN_CORAL_BLOCK = register(new Block("dead_horn_coral_block", builder())); + public static final Block TUBE_CORAL_BLOCK = register(new Block("tube_coral_block", builder())); + public static final Block BRAIN_CORAL_BLOCK = register(new Block("brain_coral_block", builder())); + public static final Block BUBBLE_CORAL_BLOCK = register(new Block("bubble_coral_block", builder())); + public static final Block FIRE_CORAL_BLOCK = register(new Block("fire_coral_block", builder())); + public static final Block HORN_CORAL_BLOCK = register(new Block("horn_coral_block", builder())); + public static final Block DEAD_TUBE_CORAL = register(new Block("dead_tube_coral", builder() + .booleanState(WATERLOGGED))); + public static final Block DEAD_BRAIN_CORAL = register(new Block("dead_brain_coral", builder() + .booleanState(WATERLOGGED))); + public static final Block DEAD_BUBBLE_CORAL = register(new Block("dead_bubble_coral", builder() + .booleanState(WATERLOGGED))); + public static final Block DEAD_FIRE_CORAL = register(new Block("dead_fire_coral", builder() + .booleanState(WATERLOGGED))); + public static final Block DEAD_HORN_CORAL = register(new Block("dead_horn_coral", builder() + .booleanState(WATERLOGGED))); + public static final Block TUBE_CORAL = register(new Block("tube_coral", builder() + .booleanState(WATERLOGGED))); + public static final Block BRAIN_CORAL = register(new Block("brain_coral", builder() + .booleanState(WATERLOGGED))); + public static final Block BUBBLE_CORAL = register(new Block("bubble_coral", builder() + .booleanState(WATERLOGGED))); + public static final Block FIRE_CORAL = register(new Block("fire_coral", builder() + .booleanState(WATERLOGGED))); + public static final Block HORN_CORAL = register(new Block("horn_coral", builder() + .booleanState(WATERLOGGED))); + public static final Block DEAD_TUBE_CORAL_FAN = register(new Block("dead_tube_coral_fan", builder() + .booleanState(WATERLOGGED))); + public static final Block DEAD_BRAIN_CORAL_FAN = register(new Block("dead_brain_coral_fan", builder() + .booleanState(WATERLOGGED))); + public static final Block DEAD_BUBBLE_CORAL_FAN = register(new Block("dead_bubble_coral_fan", builder() + .booleanState(WATERLOGGED))); + public static final Block DEAD_FIRE_CORAL_FAN = register(new Block("dead_fire_coral_fan", builder() + .booleanState(WATERLOGGED))); + public static final Block DEAD_HORN_CORAL_FAN = register(new Block("dead_horn_coral_fan", builder() + .booleanState(WATERLOGGED))); + public static final Block TUBE_CORAL_FAN = register(new Block("tube_coral_fan", builder() + .booleanState(WATERLOGGED))); + public static final Block BRAIN_CORAL_FAN = register(new Block("brain_coral_fan", builder() + .booleanState(WATERLOGGED))); + public static final Block BUBBLE_CORAL_FAN = register(new Block("bubble_coral_fan", builder() + .booleanState(WATERLOGGED))); + public static final Block FIRE_CORAL_FAN = register(new Block("fire_coral_fan", builder() + .booleanState(WATERLOGGED))); + public static final Block HORN_CORAL_FAN = register(new Block("horn_coral_fan", builder() + .booleanState(WATERLOGGED))); + public static final Block DEAD_TUBE_CORAL_WALL_FAN = register(new Block("dead_tube_coral_wall_fan", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block DEAD_BRAIN_CORAL_WALL_FAN = register(new Block("dead_brain_coral_wall_fan", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block DEAD_BUBBLE_CORAL_WALL_FAN = register(new Block("dead_bubble_coral_wall_fan", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block DEAD_FIRE_CORAL_WALL_FAN = register(new Block("dead_fire_coral_wall_fan", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block DEAD_HORN_CORAL_WALL_FAN = register(new Block("dead_horn_coral_wall_fan", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block TUBE_CORAL_WALL_FAN = register(new Block("tube_coral_wall_fan", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block BRAIN_CORAL_WALL_FAN = register(new Block("brain_coral_wall_fan", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block BUBBLE_CORAL_WALL_FAN = register(new Block("bubble_coral_wall_fan", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block FIRE_CORAL_WALL_FAN = register(new Block("fire_coral_wall_fan", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block HORN_CORAL_WALL_FAN = register(new Block("horn_coral_wall_fan", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block SEA_PICKLE = register(new Block("sea_pickle", builder() + .intState(PICKLES, 1, 4) + .booleanState(WATERLOGGED))); + public static final Block BLUE_ICE = register(new Block("blue_ice", builder())); + public static final Block CONDUIT = register(new Block("conduit", builder() + .booleanState(WATERLOGGED))); + public static final Block BAMBOO_SAPLING = register(new Block("bamboo_sapling", builder())); + public static final Block BAMBOO = register(new Block("bamboo", builder() + .intState(AGE_1, 0, 1) + .enumState(BAMBOO_LEAVES, "none", "small", "large") + .intState(STAGE, 0, 1))); + public static final Block POTTED_BAMBOO = register(new Block("potted_bamboo", builder())); + public static final Block VOID_AIR = register(new Block("void_air", builder())); + public static final Block CAVE_AIR = register(new Block("cave_air", builder())); + public static final Block BUBBLE_COLUMN = register(new Block("bubble_column", builder() + .booleanState(DRAG))); + public static final Block POLISHED_GRANITE_STAIRS = register(new Block("polished_granite_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block SMOOTH_RED_SANDSTONE_STAIRS = register(new Block("smooth_red_sandstone_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block MOSSY_STONE_BRICK_STAIRS = register(new Block("mossy_stone_brick_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block POLISHED_DIORITE_STAIRS = register(new Block("polished_diorite_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block MOSSY_COBBLESTONE_STAIRS = register(new Block("mossy_cobblestone_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block END_STONE_BRICK_STAIRS = register(new Block("end_stone_brick_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block STONE_STAIRS = register(new Block("stone_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block SMOOTH_SANDSTONE_STAIRS = register(new Block("smooth_sandstone_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block SMOOTH_QUARTZ_STAIRS = register(new Block("smooth_quartz_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block GRANITE_STAIRS = register(new Block("granite_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block ANDESITE_STAIRS = register(new Block("andesite_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block RED_NETHER_BRICK_STAIRS = register(new Block("red_nether_brick_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block POLISHED_ANDESITE_STAIRS = register(new Block("polished_andesite_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block DIORITE_STAIRS = register(new Block("diorite_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block POLISHED_GRANITE_SLAB = register(new Block("polished_granite_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block SMOOTH_RED_SANDSTONE_SLAB = register(new Block("smooth_red_sandstone_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block MOSSY_STONE_BRICK_SLAB = register(new Block("mossy_stone_brick_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block POLISHED_DIORITE_SLAB = register(new Block("polished_diorite_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block MOSSY_COBBLESTONE_SLAB = register(new Block("mossy_cobblestone_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block END_STONE_BRICK_SLAB = register(new Block("end_stone_brick_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block SMOOTH_SANDSTONE_SLAB = register(new Block("smooth_sandstone_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block SMOOTH_QUARTZ_SLAB = register(new Block("smooth_quartz_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block GRANITE_SLAB = register(new Block("granite_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block ANDESITE_SLAB = register(new Block("andesite_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block RED_NETHER_BRICK_SLAB = register(new Block("red_nether_brick_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block POLISHED_ANDESITE_SLAB = register(new Block("polished_andesite_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block DIORITE_SLAB = register(new Block("diorite_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block BRICK_WALL = register(new Block("brick_wall", builder() + .enumState(EAST_WALL, "none", "low", "tall") + .enumState(NORTH_WALL, "none", "low", "tall") + .enumState(SOUTH_WALL, "none", "low", "tall") + .booleanState(UP) + .booleanState(WATERLOGGED) + .enumState(WEST_WALL, "none", "low", "tall"))); + public static final Block PRISMARINE_WALL = register(new Block("prismarine_wall", builder() + .enumState(EAST_WALL, "none", "low", "tall") + .enumState(NORTH_WALL, "none", "low", "tall") + .enumState(SOUTH_WALL, "none", "low", "tall") + .booleanState(UP) + .booleanState(WATERLOGGED) + .enumState(WEST_WALL, "none", "low", "tall"))); + public static final Block RED_SANDSTONE_WALL = register(new Block("red_sandstone_wall", builder() + .enumState(EAST_WALL, "none", "low", "tall") + .enumState(NORTH_WALL, "none", "low", "tall") + .enumState(SOUTH_WALL, "none", "low", "tall") + .booleanState(UP) + .booleanState(WATERLOGGED) + .enumState(WEST_WALL, "none", "low", "tall"))); + public static final Block MOSSY_STONE_BRICK_WALL = register(new Block("mossy_stone_brick_wall", builder() + .enumState(EAST_WALL, "none", "low", "tall") + .enumState(NORTH_WALL, "none", "low", "tall") + .enumState(SOUTH_WALL, "none", "low", "tall") + .booleanState(UP) + .booleanState(WATERLOGGED) + .enumState(WEST_WALL, "none", "low", "tall"))); + public static final Block GRANITE_WALL = register(new Block("granite_wall", builder() + .enumState(EAST_WALL, "none", "low", "tall") + .enumState(NORTH_WALL, "none", "low", "tall") + .enumState(SOUTH_WALL, "none", "low", "tall") + .booleanState(UP) + .booleanState(WATERLOGGED) + .enumState(WEST_WALL, "none", "low", "tall"))); + public static final Block STONE_BRICK_WALL = register(new Block("stone_brick_wall", builder() + .enumState(EAST_WALL, "none", "low", "tall") + .enumState(NORTH_WALL, "none", "low", "tall") + .enumState(SOUTH_WALL, "none", "low", "tall") + .booleanState(UP) + .booleanState(WATERLOGGED) + .enumState(WEST_WALL, "none", "low", "tall"))); + public static final Block MUD_BRICK_WALL = register(new Block("mud_brick_wall", builder() + .enumState(EAST_WALL, "none", "low", "tall") + .enumState(NORTH_WALL, "none", "low", "tall") + .enumState(SOUTH_WALL, "none", "low", "tall") + .booleanState(UP) + .booleanState(WATERLOGGED) + .enumState(WEST_WALL, "none", "low", "tall"))); + public static final Block NETHER_BRICK_WALL = register(new Block("nether_brick_wall", builder() + .enumState(EAST_WALL, "none", "low", "tall") + .enumState(NORTH_WALL, "none", "low", "tall") + .enumState(SOUTH_WALL, "none", "low", "tall") + .booleanState(UP) + .booleanState(WATERLOGGED) + .enumState(WEST_WALL, "none", "low", "tall"))); + public static final Block ANDESITE_WALL = register(new Block("andesite_wall", builder() + .enumState(EAST_WALL, "none", "low", "tall") + .enumState(NORTH_WALL, "none", "low", "tall") + .enumState(SOUTH_WALL, "none", "low", "tall") + .booleanState(UP) + .booleanState(WATERLOGGED) + .enumState(WEST_WALL, "none", "low", "tall"))); + public static final Block RED_NETHER_BRICK_WALL = register(new Block("red_nether_brick_wall", builder() + .enumState(EAST_WALL, "none", "low", "tall") + .enumState(NORTH_WALL, "none", "low", "tall") + .enumState(SOUTH_WALL, "none", "low", "tall") + .booleanState(UP) + .booleanState(WATERLOGGED) + .enumState(WEST_WALL, "none", "low", "tall"))); + public static final Block SANDSTONE_WALL = register(new Block("sandstone_wall", builder() + .enumState(EAST_WALL, "none", "low", "tall") + .enumState(NORTH_WALL, "none", "low", "tall") + .enumState(SOUTH_WALL, "none", "low", "tall") + .booleanState(UP) + .booleanState(WATERLOGGED) + .enumState(WEST_WALL, "none", "low", "tall"))); + public static final Block END_STONE_BRICK_WALL = register(new Block("end_stone_brick_wall", builder() + .enumState(EAST_WALL, "none", "low", "tall") + .enumState(NORTH_WALL, "none", "low", "tall") + .enumState(SOUTH_WALL, "none", "low", "tall") + .booleanState(UP) + .booleanState(WATERLOGGED) + .enumState(WEST_WALL, "none", "low", "tall"))); + public static final Block DIORITE_WALL = register(new Block("diorite_wall", builder() + .enumState(EAST_WALL, "none", "low", "tall") + .enumState(NORTH_WALL, "none", "low", "tall") + .enumState(SOUTH_WALL, "none", "low", "tall") + .booleanState(UP) + .booleanState(WATERLOGGED) + .enumState(WEST_WALL, "none", "low", "tall"))); + public static final Block SCAFFOLDING = register(new Block("scaffolding", builder() + .booleanState(BOTTOM) + .intState(STABILITY_DISTANCE, 0, 7) + .booleanState(WATERLOGGED))); + public static final Block LOOM = register(new Block("loom", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block BARREL = register(new Block("barrel", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) + .booleanState(OPEN))); + public static final Block SMOKER = register(new Block("smoker", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(LIT))); + public static final Block BLAST_FURNACE = register(new Block("blast_furnace", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(LIT))); + public static final Block CARTOGRAPHY_TABLE = register(new Block("cartography_table", builder())); + public static final Block FLETCHING_TABLE = register(new Block("fletching_table", builder())); + public static final Block GRINDSTONE = register(new Block("grindstone", builder() + .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block LECTERN = register(new Block("lectern", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(HAS_BOOK) + .booleanState(POWERED))); + public static final Block SMITHING_TABLE = register(new Block("smithing_table", builder())); + public static final Block STONECUTTER = register(new Block("stonecutter", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); + public static final Block BELL = register(new Block("bell", builder() + .enumState(BELL_ATTACHMENT, "floor", "ceiling", "single_wall", "double_wall") + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(POWERED))); + public static final Block LANTERN = register(new Block("lantern", builder() + .booleanState(HANGING) + .booleanState(WATERLOGGED))); + public static final Block SOUL_LANTERN = register(new Block("soul_lantern", builder() + .booleanState(HANGING) + .booleanState(WATERLOGGED))); + public static final Block CAMPFIRE = register(new Block("campfire", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(LIT) + .booleanState(SIGNAL_FIRE) + .booleanState(WATERLOGGED))); + public static final Block SOUL_CAMPFIRE = register(new Block("soul_campfire", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(LIT) + .booleanState(SIGNAL_FIRE) + .booleanState(WATERLOGGED))); + public static final Block SWEET_BERRY_BUSH = register(new Block("sweet_berry_bush", builder() + .intState(AGE_3, 0, 3))); + public static final Block WARPED_STEM = register(new Block("warped_stem", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block STRIPPED_WARPED_STEM = register(new Block("stripped_warped_stem", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block WARPED_HYPHAE = register(new Block("warped_hyphae", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block STRIPPED_WARPED_HYPHAE = register(new Block("stripped_warped_hyphae", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block WARPED_NYLIUM = register(new Block("warped_nylium", builder())); + public static final Block WARPED_FUNGUS = register(new Block("warped_fungus", builder())); + public static final Block WARPED_WART_BLOCK = register(new Block("warped_wart_block", builder())); + public static final Block WARPED_ROOTS = register(new Block("warped_roots", builder())); + public static final Block NETHER_SPROUTS = register(new Block("nether_sprouts", builder())); + public static final Block CRIMSON_STEM = register(new Block("crimson_stem", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block STRIPPED_CRIMSON_STEM = register(new Block("stripped_crimson_stem", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block CRIMSON_HYPHAE = register(new Block("crimson_hyphae", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block STRIPPED_CRIMSON_HYPHAE = register(new Block("stripped_crimson_hyphae", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block CRIMSON_NYLIUM = register(new Block("crimson_nylium", builder())); + public static final Block CRIMSON_FUNGUS = register(new Block("crimson_fungus", builder())); + public static final Block SHROOMLIGHT = register(new Block("shroomlight", builder())); + public static final Block WEEPING_VINES = register(new Block("weeping_vines", builder() + .intState(AGE_25, 0, 25))); + public static final Block WEEPING_VINES_PLANT = register(new Block("weeping_vines_plant", builder())); + public static final Block TWISTING_VINES = register(new Block("twisting_vines", builder() + .intState(AGE_25, 0, 25))); + public static final Block TWISTING_VINES_PLANT = register(new Block("twisting_vines_plant", builder())); + public static final Block CRIMSON_ROOTS = register(new Block("crimson_roots", builder())); + public static final Block CRIMSON_PLANKS = register(new Block("crimson_planks", builder())); + public static final Block WARPED_PLANKS = register(new Block("warped_planks", builder())); + public static final Block CRIMSON_SLAB = register(new Block("crimson_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block WARPED_SLAB = register(new Block("warped_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block CRIMSON_PRESSURE_PLATE = register(new Block("crimson_pressure_plate", builder() + .booleanState(POWERED))); + public static final Block WARPED_PRESSURE_PLATE = register(new Block("warped_pressure_plate", builder() + .booleanState(POWERED))); + public static final Block CRIMSON_FENCE = register(new Block("crimson_fence", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block WARPED_FENCE = register(new Block("warped_fence", builder() + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block CRIMSON_TRAPDOOR = register(new Block("crimson_trapdoor", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .booleanState(OPEN) + .booleanState(POWERED) + .booleanState(WATERLOGGED))); + public static final Block WARPED_TRAPDOOR = register(new Block("warped_trapdoor", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .booleanState(OPEN) + .booleanState(POWERED) + .booleanState(WATERLOGGED))); + public static final Block CRIMSON_FENCE_GATE = register(new Block("crimson_fence_gate", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(IN_WALL) + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block WARPED_FENCE_GATE = register(new Block("warped_fence_gate", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(IN_WALL) + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block CRIMSON_STAIRS = register(new Block("crimson_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block WARPED_STAIRS = register(new Block("warped_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block CRIMSON_BUTTON = register(new Block("crimson_button", builder() + .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(POWERED))); + public static final Block WARPED_BUTTON = register(new Block("warped_button", builder() + .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(POWERED))); + public static final Block CRIMSON_DOOR = register(new Block("crimson_door", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") + .enumState(DOOR_HINGE, "left", "right") + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block WARPED_DOOR = register(new Block("warped_door", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") + .enumState(DOOR_HINGE, "left", "right") + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block CRIMSON_SIGN = register(new Block("crimson_sign", builder() + .intState(ROTATION_16, 0, 15) + .booleanState(WATERLOGGED))); + public static final Block WARPED_SIGN = register(new Block("warped_sign", builder() + .intState(ROTATION_16, 0, 15) + .booleanState(WATERLOGGED))); + public static final Block CRIMSON_WALL_SIGN = register(new Block("crimson_wall_sign", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block WARPED_WALL_SIGN = register(new Block("warped_wall_sign", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block STRUCTURE_BLOCK = register(new Block("structure_block", builder() + .enumState(STRUCTUREBLOCK_MODE, "save", "load", "corner", "data"))); + public static final Block JIGSAW = register(new Block("jigsaw", builder() + .enumState(ORIENTATION, "down_east", "down_north", "down_south", "down_west", "up_east", "up_north", "up_south", "up_west", "west_up", "east_up", "north_up", "south_up"))); + public static final Block COMPOSTER = register(new Block("composter", builder() + .intState(LEVEL_COMPOSTER, 0, 8))); + public static final Block TARGET = register(new Block("target", builder() + .intState(POWER, 0, 15))); + public static final Block BEE_NEST = register(new Block("bee_nest", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .intState(LEVEL_HONEY, 0, 5))); + public static final Block BEEHIVE = register(new Block("beehive", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .intState(LEVEL_HONEY, 0, 5))); + public static final Block HONEY_BLOCK = register(new Block("honey_block", builder())); + public static final Block HONEYCOMB_BLOCK = register(new Block("honeycomb_block", builder())); + public static final Block NETHERITE_BLOCK = register(new Block("netherite_block", builder())); + public static final Block ANCIENT_DEBRIS = register(new Block("ancient_debris", builder())); + public static final Block CRYING_OBSIDIAN = register(new Block("crying_obsidian", builder())); + public static final Block RESPAWN_ANCHOR = register(new Block("respawn_anchor", builder() + .intState(RESPAWN_ANCHOR_CHARGES, 0, 4))); + public static final Block POTTED_CRIMSON_FUNGUS = register(new Block("potted_crimson_fungus", builder())); + public static final Block POTTED_WARPED_FUNGUS = register(new Block("potted_warped_fungus", builder())); + public static final Block POTTED_CRIMSON_ROOTS = register(new Block("potted_crimson_roots", builder())); + public static final Block POTTED_WARPED_ROOTS = register(new Block("potted_warped_roots", builder())); + public static final Block LODESTONE = register(new Block("lodestone", builder())); + public static final Block BLACKSTONE = register(new Block("blackstone", builder())); + public static final Block BLACKSTONE_STAIRS = register(new Block("blackstone_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block BLACKSTONE_WALL = register(new Block("blackstone_wall", builder() + .enumState(EAST_WALL, "none", "low", "tall") + .enumState(NORTH_WALL, "none", "low", "tall") + .enumState(SOUTH_WALL, "none", "low", "tall") + .booleanState(UP) + .booleanState(WATERLOGGED) + .enumState(WEST_WALL, "none", "low", "tall"))); + public static final Block BLACKSTONE_SLAB = register(new Block("blackstone_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block POLISHED_BLACKSTONE = register(new Block("polished_blackstone", builder())); + public static final Block POLISHED_BLACKSTONE_BRICKS = register(new Block("polished_blackstone_bricks", builder())); + public static final Block CRACKED_POLISHED_BLACKSTONE_BRICKS = register(new Block("cracked_polished_blackstone_bricks", builder())); + public static final Block CHISELED_POLISHED_BLACKSTONE = register(new Block("chiseled_polished_blackstone", builder())); + public static final Block POLISHED_BLACKSTONE_BRICK_SLAB = register(new Block("polished_blackstone_brick_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block POLISHED_BLACKSTONE_BRICK_STAIRS = register(new Block("polished_blackstone_brick_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block POLISHED_BLACKSTONE_BRICK_WALL = register(new Block("polished_blackstone_brick_wall", builder() + .enumState(EAST_WALL, "none", "low", "tall") + .enumState(NORTH_WALL, "none", "low", "tall") + .enumState(SOUTH_WALL, "none", "low", "tall") + .booleanState(UP) + .booleanState(WATERLOGGED) + .enumState(WEST_WALL, "none", "low", "tall"))); + public static final Block GILDED_BLACKSTONE = register(new Block("gilded_blackstone", builder())); + public static final Block POLISHED_BLACKSTONE_STAIRS = register(new Block("polished_blackstone_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block POLISHED_BLACKSTONE_SLAB = register(new Block("polished_blackstone_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block POLISHED_BLACKSTONE_PRESSURE_PLATE = register(new Block("polished_blackstone_pressure_plate", builder() + .booleanState(POWERED))); + public static final Block POLISHED_BLACKSTONE_BUTTON = register(new Block("polished_blackstone_button", builder() + .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(POWERED))); + public static final Block POLISHED_BLACKSTONE_WALL = register(new Block("polished_blackstone_wall", builder() + .enumState(EAST_WALL, "none", "low", "tall") + .enumState(NORTH_WALL, "none", "low", "tall") + .enumState(SOUTH_WALL, "none", "low", "tall") + .booleanState(UP) + .booleanState(WATERLOGGED) + .enumState(WEST_WALL, "none", "low", "tall"))); + public static final Block CHISELED_NETHER_BRICKS = register(new Block("chiseled_nether_bricks", builder())); + public static final Block CRACKED_NETHER_BRICKS = register(new Block("cracked_nether_bricks", builder())); + public static final Block QUARTZ_BRICKS = register(new Block("quartz_bricks", builder())); + public static final Block CANDLE = register(new Block("candle", builder() + .intState(CANDLES, 1, 4) + .booleanState(LIT) + .booleanState(WATERLOGGED))); + public static final Block WHITE_CANDLE = register(new Block("white_candle", builder() + .intState(CANDLES, 1, 4) + .booleanState(LIT) + .booleanState(WATERLOGGED))); + public static final Block ORANGE_CANDLE = register(new Block("orange_candle", builder() + .intState(CANDLES, 1, 4) + .booleanState(LIT) + .booleanState(WATERLOGGED))); + public static final Block MAGENTA_CANDLE = register(new Block("magenta_candle", builder() + .intState(CANDLES, 1, 4) + .booleanState(LIT) + .booleanState(WATERLOGGED))); + public static final Block LIGHT_BLUE_CANDLE = register(new Block("light_blue_candle", builder() + .intState(CANDLES, 1, 4) + .booleanState(LIT) + .booleanState(WATERLOGGED))); + public static final Block YELLOW_CANDLE = register(new Block("yellow_candle", builder() + .intState(CANDLES, 1, 4) + .booleanState(LIT) + .booleanState(WATERLOGGED))); + public static final Block LIME_CANDLE = register(new Block("lime_candle", builder() + .intState(CANDLES, 1, 4) + .booleanState(LIT) + .booleanState(WATERLOGGED))); + public static final Block PINK_CANDLE = register(new Block("pink_candle", builder() + .intState(CANDLES, 1, 4) + .booleanState(LIT) + .booleanState(WATERLOGGED))); + public static final Block GRAY_CANDLE = register(new Block("gray_candle", builder() + .intState(CANDLES, 1, 4) + .booleanState(LIT) + .booleanState(WATERLOGGED))); + public static final Block LIGHT_GRAY_CANDLE = register(new Block("light_gray_candle", builder() + .intState(CANDLES, 1, 4) + .booleanState(LIT) + .booleanState(WATERLOGGED))); + public static final Block CYAN_CANDLE = register(new Block("cyan_candle", builder() + .intState(CANDLES, 1, 4) + .booleanState(LIT) + .booleanState(WATERLOGGED))); + public static final Block PURPLE_CANDLE = register(new Block("purple_candle", builder() + .intState(CANDLES, 1, 4) + .booleanState(LIT) + .booleanState(WATERLOGGED))); + public static final Block BLUE_CANDLE = register(new Block("blue_candle", builder() + .intState(CANDLES, 1, 4) + .booleanState(LIT) + .booleanState(WATERLOGGED))); + public static final Block BROWN_CANDLE = register(new Block("brown_candle", builder() + .intState(CANDLES, 1, 4) + .booleanState(LIT) + .booleanState(WATERLOGGED))); + public static final Block GREEN_CANDLE = register(new Block("green_candle", builder() + .intState(CANDLES, 1, 4) + .booleanState(LIT) + .booleanState(WATERLOGGED))); + public static final Block RED_CANDLE = register(new Block("red_candle", builder() + .intState(CANDLES, 1, 4) + .booleanState(LIT) + .booleanState(WATERLOGGED))); + public static final Block BLACK_CANDLE = register(new Block("black_candle", builder() + .intState(CANDLES, 1, 4) + .booleanState(LIT) + .booleanState(WATERLOGGED))); + public static final Block CANDLE_CAKE = register(new Block("candle_cake", builder() + .booleanState(LIT))); + public static final Block WHITE_CANDLE_CAKE = register(new Block("white_candle_cake", builder() + .booleanState(LIT))); + public static final Block ORANGE_CANDLE_CAKE = register(new Block("orange_candle_cake", builder() + .booleanState(LIT))); + public static final Block MAGENTA_CANDLE_CAKE = register(new Block("magenta_candle_cake", builder() + .booleanState(LIT))); + public static final Block LIGHT_BLUE_CANDLE_CAKE = register(new Block("light_blue_candle_cake", builder() + .booleanState(LIT))); + public static final Block YELLOW_CANDLE_CAKE = register(new Block("yellow_candle_cake", builder() + .booleanState(LIT))); + public static final Block LIME_CANDLE_CAKE = register(new Block("lime_candle_cake", builder() + .booleanState(LIT))); + public static final Block PINK_CANDLE_CAKE = register(new Block("pink_candle_cake", builder() + .booleanState(LIT))); + public static final Block GRAY_CANDLE_CAKE = register(new Block("gray_candle_cake", builder() + .booleanState(LIT))); + public static final Block LIGHT_GRAY_CANDLE_CAKE = register(new Block("light_gray_candle_cake", builder() + .booleanState(LIT))); + public static final Block CYAN_CANDLE_CAKE = register(new Block("cyan_candle_cake", builder() + .booleanState(LIT))); + public static final Block PURPLE_CANDLE_CAKE = register(new Block("purple_candle_cake", builder() + .booleanState(LIT))); + public static final Block BLUE_CANDLE_CAKE = register(new Block("blue_candle_cake", builder() + .booleanState(LIT))); + public static final Block BROWN_CANDLE_CAKE = register(new Block("brown_candle_cake", builder() + .booleanState(LIT))); + public static final Block GREEN_CANDLE_CAKE = register(new Block("green_candle_cake", builder() + .booleanState(LIT))); + public static final Block RED_CANDLE_CAKE = register(new Block("red_candle_cake", builder() + .booleanState(LIT))); + public static final Block BLACK_CANDLE_CAKE = register(new Block("black_candle_cake", builder() + .booleanState(LIT))); + public static final Block AMETHYST_BLOCK = register(new Block("amethyst_block", builder())); + public static final Block BUDDING_AMETHYST = register(new Block("budding_amethyst", builder())); + public static final Block AMETHYST_CLUSTER = register(new Block("amethyst_cluster", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) + .booleanState(WATERLOGGED))); + public static final Block LARGE_AMETHYST_BUD = register(new Block("large_amethyst_bud", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) + .booleanState(WATERLOGGED))); + public static final Block MEDIUM_AMETHYST_BUD = register(new Block("medium_amethyst_bud", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) + .booleanState(WATERLOGGED))); + public static final Block SMALL_AMETHYST_BUD = register(new Block("small_amethyst_bud", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) + .booleanState(WATERLOGGED))); + public static final Block TUFF = register(new Block("tuff", builder())); + public static final Block TUFF_SLAB = register(new Block("tuff_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block TUFF_STAIRS = register(new Block("tuff_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block TUFF_WALL = register(new Block("tuff_wall", builder() + .enumState(EAST_WALL, "none", "low", "tall") + .enumState(NORTH_WALL, "none", "low", "tall") + .enumState(SOUTH_WALL, "none", "low", "tall") + .booleanState(UP) + .booleanState(WATERLOGGED) + .enumState(WEST_WALL, "none", "low", "tall"))); + public static final Block POLISHED_TUFF = register(new Block("polished_tuff", builder())); + public static final Block POLISHED_TUFF_SLAB = register(new Block("polished_tuff_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block POLISHED_TUFF_STAIRS = register(new Block("polished_tuff_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block POLISHED_TUFF_WALL = register(new Block("polished_tuff_wall", builder() + .enumState(EAST_WALL, "none", "low", "tall") + .enumState(NORTH_WALL, "none", "low", "tall") + .enumState(SOUTH_WALL, "none", "low", "tall") + .booleanState(UP) + .booleanState(WATERLOGGED) + .enumState(WEST_WALL, "none", "low", "tall"))); + public static final Block CHISELED_TUFF = register(new Block("chiseled_tuff", builder())); + public static final Block TUFF_BRICKS = register(new Block("tuff_bricks", builder())); + public static final Block TUFF_BRICK_SLAB = register(new Block("tuff_brick_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block TUFF_BRICK_STAIRS = register(new Block("tuff_brick_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block TUFF_BRICK_WALL = register(new Block("tuff_brick_wall", builder() + .enumState(EAST_WALL, "none", "low", "tall") + .enumState(NORTH_WALL, "none", "low", "tall") + .enumState(SOUTH_WALL, "none", "low", "tall") + .booleanState(UP) + .booleanState(WATERLOGGED) + .enumState(WEST_WALL, "none", "low", "tall"))); + public static final Block CHISELED_TUFF_BRICKS = register(new Block("chiseled_tuff_bricks", builder())); + public static final Block CALCITE = register(new Block("calcite", builder())); + public static final Block TINTED_GLASS = register(new Block("tinted_glass", builder())); + public static final Block POWDER_SNOW = register(new Block("powder_snow", builder())); + public static final Block SCULK_SENSOR = register(new Block("sculk_sensor", builder() + .intState(POWER, 0, 15) + .enumState(SCULK_SENSOR_PHASE, "inactive", "active", "cooldown") + .booleanState(WATERLOGGED))); + public static final Block CALIBRATED_SCULK_SENSOR = register(new Block("calibrated_sculk_sensor", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .intState(POWER, 0, 15) + .enumState(SCULK_SENSOR_PHASE, "inactive", "active", "cooldown") + .booleanState(WATERLOGGED))); + public static final Block SCULK = register(new Block("sculk", builder())); + public static final Block SCULK_VEIN = register(new Block("sculk_vein", builder() + .booleanState(DOWN) + .booleanState(EAST) + .booleanState(NORTH) + .booleanState(SOUTH) + .booleanState(UP) + .booleanState(WATERLOGGED) + .booleanState(WEST))); + public static final Block SCULK_CATALYST = register(new Block("sculk_catalyst", builder() + .booleanState(BLOOM))); + public static final Block SCULK_SHRIEKER = register(new Block("sculk_shrieker", builder() + .booleanState(CAN_SUMMON) + .booleanState(SHRIEKING) + .booleanState(WATERLOGGED))); + public static final Block COPPER_BLOCK = register(new Block("copper_block", builder())); + public static final Block EXPOSED_COPPER = register(new Block("exposed_copper", builder())); + public static final Block WEATHERED_COPPER = register(new Block("weathered_copper", builder())); + public static final Block OXIDIZED_COPPER = register(new Block("oxidized_copper", builder())); + public static final Block COPPER_ORE = register(new Block("copper_ore", builder())); + public static final Block DEEPSLATE_COPPER_ORE = register(new Block("deepslate_copper_ore", builder())); + public static final Block OXIDIZED_CUT_COPPER = register(new Block("oxidized_cut_copper", builder())); + public static final Block WEATHERED_CUT_COPPER = register(new Block("weathered_cut_copper", builder())); + public static final Block EXPOSED_CUT_COPPER = register(new Block("exposed_cut_copper", builder())); + public static final Block CUT_COPPER = register(new Block("cut_copper", builder())); + public static final Block OXIDIZED_CHISELED_COPPER = register(new Block("oxidized_chiseled_copper", builder())); + public static final Block WEATHERED_CHISELED_COPPER = register(new Block("weathered_chiseled_copper", builder())); + public static final Block EXPOSED_CHISELED_COPPER = register(new Block("exposed_chiseled_copper", builder())); + public static final Block CHISELED_COPPER = register(new Block("chiseled_copper", builder())); + public static final Block WAXED_OXIDIZED_CHISELED_COPPER = register(new Block("waxed_oxidized_chiseled_copper", builder())); + public static final Block WAXED_WEATHERED_CHISELED_COPPER = register(new Block("waxed_weathered_chiseled_copper", builder())); + public static final Block WAXED_EXPOSED_CHISELED_COPPER = register(new Block("waxed_exposed_chiseled_copper", builder())); + public static final Block WAXED_CHISELED_COPPER = register(new Block("waxed_chiseled_copper", builder())); + public static final Block OXIDIZED_CUT_COPPER_STAIRS = register(new Block("oxidized_cut_copper_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block WEATHERED_CUT_COPPER_STAIRS = register(new Block("weathered_cut_copper_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block EXPOSED_CUT_COPPER_STAIRS = register(new Block("exposed_cut_copper_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block CUT_COPPER_STAIRS = register(new Block("cut_copper_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block OXIDIZED_CUT_COPPER_SLAB = register(new Block("oxidized_cut_copper_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block WEATHERED_CUT_COPPER_SLAB = register(new Block("weathered_cut_copper_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block EXPOSED_CUT_COPPER_SLAB = register(new Block("exposed_cut_copper_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block CUT_COPPER_SLAB = register(new Block("cut_copper_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block WAXED_COPPER_BLOCK = register(new Block("waxed_copper_block", builder())); + public static final Block WAXED_WEATHERED_COPPER = register(new Block("waxed_weathered_copper", builder())); + public static final Block WAXED_EXPOSED_COPPER = register(new Block("waxed_exposed_copper", builder())); + public static final Block WAXED_OXIDIZED_COPPER = register(new Block("waxed_oxidized_copper", builder())); + public static final Block WAXED_OXIDIZED_CUT_COPPER = register(new Block("waxed_oxidized_cut_copper", builder())); + public static final Block WAXED_WEATHERED_CUT_COPPER = register(new Block("waxed_weathered_cut_copper", builder())); + public static final Block WAXED_EXPOSED_CUT_COPPER = register(new Block("waxed_exposed_cut_copper", builder())); + public static final Block WAXED_CUT_COPPER = register(new Block("waxed_cut_copper", builder())); + public static final Block WAXED_OXIDIZED_CUT_COPPER_STAIRS = register(new Block("waxed_oxidized_cut_copper_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block WAXED_WEATHERED_CUT_COPPER_STAIRS = register(new Block("waxed_weathered_cut_copper_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block WAXED_EXPOSED_CUT_COPPER_STAIRS = register(new Block("waxed_exposed_cut_copper_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block WAXED_CUT_COPPER_STAIRS = register(new Block("waxed_cut_copper_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block WAXED_OXIDIZED_CUT_COPPER_SLAB = register(new Block("waxed_oxidized_cut_copper_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block WAXED_WEATHERED_CUT_COPPER_SLAB = register(new Block("waxed_weathered_cut_copper_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block WAXED_EXPOSED_CUT_COPPER_SLAB = register(new Block("waxed_exposed_cut_copper_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block WAXED_CUT_COPPER_SLAB = register(new Block("waxed_cut_copper_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block COPPER_DOOR = register(new Block("copper_door", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") + .enumState(DOOR_HINGE, "left", "right") + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block EXPOSED_COPPER_DOOR = register(new Block("exposed_copper_door", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") + .enumState(DOOR_HINGE, "left", "right") + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block OXIDIZED_COPPER_DOOR = register(new Block("oxidized_copper_door", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") + .enumState(DOOR_HINGE, "left", "right") + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block WEATHERED_COPPER_DOOR = register(new Block("weathered_copper_door", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") + .enumState(DOOR_HINGE, "left", "right") + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block WAXED_COPPER_DOOR = register(new Block("waxed_copper_door", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") + .enumState(DOOR_HINGE, "left", "right") + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block WAXED_EXPOSED_COPPER_DOOR = register(new Block("waxed_exposed_copper_door", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") + .enumState(DOOR_HINGE, "left", "right") + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block WAXED_OXIDIZED_COPPER_DOOR = register(new Block("waxed_oxidized_copper_door", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") + .enumState(DOOR_HINGE, "left", "right") + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block WAXED_WEATHERED_COPPER_DOOR = register(new Block("waxed_weathered_copper_door", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") + .enumState(DOOR_HINGE, "left", "right") + .booleanState(OPEN) + .booleanState(POWERED))); + public static final Block COPPER_TRAPDOOR = register(new Block("copper_trapdoor", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .booleanState(OPEN) + .booleanState(POWERED) + .booleanState(WATERLOGGED))); + public static final Block EXPOSED_COPPER_TRAPDOOR = register(new Block("exposed_copper_trapdoor", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .booleanState(OPEN) + .booleanState(POWERED) + .booleanState(WATERLOGGED))); + public static final Block OXIDIZED_COPPER_TRAPDOOR = register(new Block("oxidized_copper_trapdoor", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .booleanState(OPEN) + .booleanState(POWERED) + .booleanState(WATERLOGGED))); + public static final Block WEATHERED_COPPER_TRAPDOOR = register(new Block("weathered_copper_trapdoor", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .booleanState(OPEN) + .booleanState(POWERED) + .booleanState(WATERLOGGED))); + public static final Block WAXED_COPPER_TRAPDOOR = register(new Block("waxed_copper_trapdoor", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .booleanState(OPEN) + .booleanState(POWERED) + .booleanState(WATERLOGGED))); + public static final Block WAXED_EXPOSED_COPPER_TRAPDOOR = register(new Block("waxed_exposed_copper_trapdoor", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .booleanState(OPEN) + .booleanState(POWERED) + .booleanState(WATERLOGGED))); + public static final Block WAXED_OXIDIZED_COPPER_TRAPDOOR = register(new Block("waxed_oxidized_copper_trapdoor", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .booleanState(OPEN) + .booleanState(POWERED) + .booleanState(WATERLOGGED))); + public static final Block WAXED_WEATHERED_COPPER_TRAPDOOR = register(new Block("waxed_weathered_copper_trapdoor", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .booleanState(OPEN) + .booleanState(POWERED) + .booleanState(WATERLOGGED))); + public static final Block COPPER_GRATE = register(new Block("copper_grate", builder() + .booleanState(WATERLOGGED))); + public static final Block EXPOSED_COPPER_GRATE = register(new Block("exposed_copper_grate", builder() + .booleanState(WATERLOGGED))); + public static final Block WEATHERED_COPPER_GRATE = register(new Block("weathered_copper_grate", builder() + .booleanState(WATERLOGGED))); + public static final Block OXIDIZED_COPPER_GRATE = register(new Block("oxidized_copper_grate", builder() + .booleanState(WATERLOGGED))); + public static final Block WAXED_COPPER_GRATE = register(new Block("waxed_copper_grate", builder() + .booleanState(WATERLOGGED))); + public static final Block WAXED_EXPOSED_COPPER_GRATE = register(new Block("waxed_exposed_copper_grate", builder() + .booleanState(WATERLOGGED))); + public static final Block WAXED_WEATHERED_COPPER_GRATE = register(new Block("waxed_weathered_copper_grate", builder() + .booleanState(WATERLOGGED))); + public static final Block WAXED_OXIDIZED_COPPER_GRATE = register(new Block("waxed_oxidized_copper_grate", builder() + .booleanState(WATERLOGGED))); + public static final Block COPPER_BULB = register(new Block("copper_bulb", builder() + .booleanState(LIT) + .booleanState(POWERED))); + public static final Block EXPOSED_COPPER_BULB = register(new Block("exposed_copper_bulb", builder() + .booleanState(LIT) + .booleanState(POWERED))); + public static final Block WEATHERED_COPPER_BULB = register(new Block("weathered_copper_bulb", builder() + .booleanState(LIT) + .booleanState(POWERED))); + public static final Block OXIDIZED_COPPER_BULB = register(new Block("oxidized_copper_bulb", builder() + .booleanState(LIT) + .booleanState(POWERED))); + public static final Block WAXED_COPPER_BULB = register(new Block("waxed_copper_bulb", builder() + .booleanState(LIT) + .booleanState(POWERED))); + public static final Block WAXED_EXPOSED_COPPER_BULB = register(new Block("waxed_exposed_copper_bulb", builder() + .booleanState(LIT) + .booleanState(POWERED))); + public static final Block WAXED_WEATHERED_COPPER_BULB = register(new Block("waxed_weathered_copper_bulb", builder() + .booleanState(LIT) + .booleanState(POWERED))); + public static final Block WAXED_OXIDIZED_COPPER_BULB = register(new Block("waxed_oxidized_copper_bulb", builder() + .booleanState(LIT) + .booleanState(POWERED))); + public static final Block LIGHTNING_ROD = register(new Block("lightning_rod", builder() + .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) + .booleanState(POWERED) + .booleanState(WATERLOGGED))); + public static final Block POINTED_DRIPSTONE = register(new Block("pointed_dripstone", builder() + .enumState(DRIPSTONE_THICKNESS, "tip_merge", "tip", "frustum", "middle", "base") + .enumState(VERTICAL_DIRECTION, Direction.UP, Direction.DOWN) + .booleanState(WATERLOGGED))); + public static final Block DRIPSTONE_BLOCK = register(new Block("dripstone_block", builder())); + public static final Block CAVE_VINES = register(new Block("cave_vines", builder() + .intState(AGE_25, 0, 25) + .booleanState(BERRIES))); + public static final Block CAVE_VINES_PLANT = register(new Block("cave_vines_plant", builder() + .booleanState(BERRIES))); + public static final Block SPORE_BLOSSOM = register(new Block("spore_blossom", builder())); + public static final Block AZALEA = register(new Block("azalea", builder())); + public static final Block FLOWERING_AZALEA = register(new Block("flowering_azalea", builder())); + public static final Block MOSS_CARPET = register(new Block("moss_carpet", builder())); + public static final Block PINK_PETALS = register(new Block("pink_petals", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .intState(FLOWER_AMOUNT, 1, 4))); + public static final Block MOSS_BLOCK = register(new Block("moss_block", builder())); + public static final Block BIG_DRIPLEAF = register(new Block("big_dripleaf", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(TILT, "none", "unstable", "partial", "full") + .booleanState(WATERLOGGED))); + public static final Block BIG_DRIPLEAF_STEM = register(new Block("big_dripleaf_stem", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block SMALL_DRIPLEAF = register(new Block("small_dripleaf", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") + .booleanState(WATERLOGGED))); + public static final Block HANGING_ROOTS = register(new Block("hanging_roots", builder() + .booleanState(WATERLOGGED))); + public static final Block ROOTED_DIRT = register(new Block("rooted_dirt", builder())); + public static final Block MUD = register(new Block("mud", builder())); + public static final Block DEEPSLATE = register(new Block("deepslate", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block COBBLED_DEEPSLATE = register(new Block("cobbled_deepslate", builder())); + public static final Block COBBLED_DEEPSLATE_STAIRS = register(new Block("cobbled_deepslate_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block COBBLED_DEEPSLATE_SLAB = register(new Block("cobbled_deepslate_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block COBBLED_DEEPSLATE_WALL = register(new Block("cobbled_deepslate_wall", builder() + .enumState(EAST_WALL, "none", "low", "tall") + .enumState(NORTH_WALL, "none", "low", "tall") + .enumState(SOUTH_WALL, "none", "low", "tall") + .booleanState(UP) + .booleanState(WATERLOGGED) + .enumState(WEST_WALL, "none", "low", "tall"))); + public static final Block POLISHED_DEEPSLATE = register(new Block("polished_deepslate", builder())); + public static final Block POLISHED_DEEPSLATE_STAIRS = register(new Block("polished_deepslate_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block POLISHED_DEEPSLATE_SLAB = register(new Block("polished_deepslate_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block POLISHED_DEEPSLATE_WALL = register(new Block("polished_deepslate_wall", builder() + .enumState(EAST_WALL, "none", "low", "tall") + .enumState(NORTH_WALL, "none", "low", "tall") + .enumState(SOUTH_WALL, "none", "low", "tall") + .booleanState(UP) + .booleanState(WATERLOGGED) + .enumState(WEST_WALL, "none", "low", "tall"))); + public static final Block DEEPSLATE_TILES = register(new Block("deepslate_tiles", builder())); + public static final Block DEEPSLATE_TILE_STAIRS = register(new Block("deepslate_tile_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block DEEPSLATE_TILE_SLAB = register(new Block("deepslate_tile_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block DEEPSLATE_TILE_WALL = register(new Block("deepslate_tile_wall", builder() + .enumState(EAST_WALL, "none", "low", "tall") + .enumState(NORTH_WALL, "none", "low", "tall") + .enumState(SOUTH_WALL, "none", "low", "tall") + .booleanState(UP) + .booleanState(WATERLOGGED) + .enumState(WEST_WALL, "none", "low", "tall"))); + public static final Block DEEPSLATE_BRICKS = register(new Block("deepslate_bricks", builder())); + public static final Block DEEPSLATE_BRICK_STAIRS = register(new Block("deepslate_brick_stairs", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .enumState(HALF, "top", "bottom") + .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .booleanState(WATERLOGGED))); + public static final Block DEEPSLATE_BRICK_SLAB = register(new Block("deepslate_brick_slab", builder() + .enumState(SLAB_TYPE, "top", "bottom", "double") + .booleanState(WATERLOGGED))); + public static final Block DEEPSLATE_BRICK_WALL = register(new Block("deepslate_brick_wall", builder() + .enumState(EAST_WALL, "none", "low", "tall") + .enumState(NORTH_WALL, "none", "low", "tall") + .enumState(SOUTH_WALL, "none", "low", "tall") + .booleanState(UP) + .booleanState(WATERLOGGED) + .enumState(WEST_WALL, "none", "low", "tall"))); + public static final Block CHISELED_DEEPSLATE = register(new Block("chiseled_deepslate", builder())); + public static final Block CRACKED_DEEPSLATE_BRICKS = register(new Block("cracked_deepslate_bricks", builder())); + public static final Block CRACKED_DEEPSLATE_TILES = register(new Block("cracked_deepslate_tiles", builder())); + public static final Block INFESTED_DEEPSLATE = register(new Block("infested_deepslate", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block SMOOTH_BASALT = register(new Block("smooth_basalt", builder())); + public static final Block RAW_IRON_BLOCK = register(new Block("raw_iron_block", builder())); + public static final Block RAW_COPPER_BLOCK = register(new Block("raw_copper_block", builder())); + public static final Block RAW_GOLD_BLOCK = register(new Block("raw_gold_block", builder())); + public static final Block POTTED_AZALEA_BUSH = register(new Block("potted_azalea_bush", builder())); + public static final Block POTTED_FLOWERING_AZALEA_BUSH = register(new Block("potted_flowering_azalea_bush", builder())); + public static final Block OCHRE_FROGLIGHT = register(new Block("ochre_froglight", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block VERDANT_FROGLIGHT = register(new Block("verdant_froglight", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block PEARLESCENT_FROGLIGHT = register(new Block("pearlescent_froglight", builder() + .enumState(AXIS, Axis.VALUES))); + public static final Block FROGSPAWN = register(new Block("frogspawn", builder())); + public static final Block REINFORCED_DEEPSLATE = register(new Block("reinforced_deepslate", builder())); + public static final Block DECORATED_POT = register(new Block("decorated_pot", builder() + .booleanState(CRACKED) + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(WATERLOGGED))); + public static final Block CRAFTER = register(new Block("crafter", builder() + .booleanState(CRAFTING) + .enumState(ORIENTATION, "down_east", "down_north", "down_south", "down_west", "up_east", "up_north", "up_south", "up_west", "west_up", "east_up", "north_up", "south_up") + .booleanState(TRIGGERED))); + public static final Block TRIAL_SPAWNER = register(new Block("trial_spawner", builder() + .booleanState(OMINOUS) + .enumState(TRIAL_SPAWNER_STATE, "inactive", "waiting_for_players", "active", "waiting_for_reward_ejection", "ejecting_reward", "cooldown"))); + public static final Block VAULT = register(new Block("vault", builder() + .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) + .booleanState(OMINOUS) + .enumState(VAULT_STATE, "inactive", "active", "unlocking", "ejecting"))); + public static final Block HEAVY_CORE = register(new Block("heavy_core", builder() + .booleanState(WATERLOGGED))); + + private static T register(T block) { + BlockRegistries.JAVA_BLOCKS_TO_RENAME.get().add(block); + return block; + } + + private Blocks() { + } +} diff --git a/core/src/main/java/org/geysermc/geyser/level/block/property/ChestType.java b/core/src/main/java/org/geysermc/geyser/level/block/property/ChestType.java new file mode 100644 index 000000000..c206f127c --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/property/ChestType.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.property; + +public enum ChestType { + SINGLE, + LEFT, + RIGHT; + + public static final ChestType[] VALUES = values(); +} diff --git a/core/src/main/java/org/geysermc/geyser/level/block/property/Properties.java b/core/src/main/java/org/geysermc/geyser/level/block/property/Properties.java new file mode 100644 index 000000000..bbb6f8fe3 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/property/Properties.java @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.property; + +import org.geysermc.geyser.level.physics.Axis; +import org.geysermc.geyser.level.physics.Direction; + +public final class Properties { + public static final Property ATTACHED = Property.create("attached"); + public static final Property BOTTOM = Property.create("bottom"); + public static final Property CONDITIONAL = Property.create("conditional"); + public static final Property DISARMED = Property.create("disarmed"); + public static final Property DRAG = Property.create("drag"); + public static final Property ENABLED = Property.create("enabled"); + public static final Property EXTENDED = Property.create("extended"); + public static final Property EYE = Property.create("eye"); + public static final Property FALLING = Property.create("falling"); + public static final Property HANGING = Property.create("hanging"); + public static final Property HAS_BOTTLE_0 = Property.create("has_bottle_0"); + public static final Property HAS_BOTTLE_1 = Property.create("has_bottle_1"); + public static final Property HAS_BOTTLE_2 = Property.create("has_bottle_2"); + public static final Property HAS_RECORD = Property.create("has_record"); + public static final Property HAS_BOOK = Property.create("has_book"); + public static final Property INVERTED = Property.create("inverted"); + public static final Property IN_WALL = Property.create("in_wall"); + public static final Property LIT = Property.create("lit"); + public static final Property LOCKED = Property.create("locked"); + public static final Property OCCUPIED = Property.create("occupied"); + public static final Property OPEN = Property.create("open"); + public static final Property PERSISTENT = Property.create("persistent"); + public static final Property POWERED = Property.create("powered"); + public static final Property SHORT = Property.create("short"); + public static final Property SIGNAL_FIRE = Property.create("signal_fire"); + public static final Property SNOWY = Property.create("snowy"); + public static final Property TRIGGERED = Property.create("triggered"); + public static final Property UNSTABLE = Property.create("unstable"); + public static final Property WATERLOGGED = Property.create("waterlogged"); + public static final Property BERRIES = Property.create("berries"); + public static final Property BLOOM = Property.create("bloom"); + public static final Property SHRIEKING = Property.create("shrieking"); + public static final Property CAN_SUMMON = Property.create("can_summon"); + public static final Property HORIZONTAL_AXIS = Property.create("axis"); + public static final Property AXIS = Property.create("axis"); + public static final Property UP = Property.create("up"); + public static final Property DOWN = Property.create("down"); + public static final Property NORTH = Property.create("north"); + public static final Property EAST = Property.create("east"); + public static final Property SOUTH = Property.create("south"); + public static final Property WEST = Property.create("west"); + public static final Property FACING = Property.create("facing"); + public static final Property FACING_HOPPER = Property.create("facing"); + public static final Property HORIZONTAL_FACING = Property.create("facing"); + public static final Property FLOWER_AMOUNT = Property.create("flower_amount"); + public static final Property ORIENTATION = Property.create("orientation"); + public static final Property ATTACH_FACE = Property.create("face"); + public static final Property BELL_ATTACHMENT = Property.create("attachment"); + public static final Property EAST_WALL = Property.create("east"); + public static final Property NORTH_WALL = Property.create("north"); + public static final Property SOUTH_WALL = Property.create("south"); + public static final Property WEST_WALL = Property.create("west"); + public static final Property EAST_REDSTONE = Property.create("east"); + public static final Property NORTH_REDSTONE = Property.create("north"); + public static final Property SOUTH_REDSTONE = Property.create("south"); + public static final Property WEST_REDSTONE = Property.create("west"); + public static final Property DOUBLE_BLOCK_HALF = Property.create("half"); + public static final Property HALF = Property.create("half"); + public static final Property RAIL_SHAPE = Property.create("shape"); + public static final Property RAIL_SHAPE_STRAIGHT = Property.create("shape"); + public static final Property AGE_1 = Property.create("age"); + public static final Property AGE_2 = Property.create("age"); + public static final Property AGE_3 = Property.create("age"); + public static final Property AGE_4 = Property.create("age"); + public static final Property AGE_5 = Property.create("age"); + public static final Property AGE_7 = Property.create("age"); + public static final Property AGE_15 = Property.create("age"); + public static final Property AGE_25 = Property.create("age"); + public static final Property BITES = Property.create("bites"); + public static final Property CANDLES = Property.create("candles"); + public static final Property DELAY = Property.create("delay"); + public static final Property DISTANCE = Property.create("distance"); + public static final Property EGGS = Property.create("eggs"); + public static final Property HATCH = Property.create("hatch"); + public static final Property LAYERS = Property.create("layers"); + public static final Property LEVEL_CAULDRON = Property.create("level"); + public static final Property LEVEL_COMPOSTER = Property.create("level"); + public static final Property LEVEL_FLOWING = Property.create("level"); + public static final Property LEVEL_HONEY = Property.create("honey_level"); + public static final Property LEVEL = Property.create("level"); + public static final Property MOISTURE = Property.create("moisture"); + public static final Property NOTE = Property.create("note"); + public static final Property PICKLES = Property.create("pickles"); + public static final Property POWER = Property.create("power"); + public static final Property STAGE = Property.create("stage"); + public static final Property STABILITY_DISTANCE = Property.create("distance"); + public static final Property RESPAWN_ANCHOR_CHARGES = Property.create("charges"); + public static final Property ROTATION_16 = Property.create("rotation"); + public static final Property BED_PART = Property.create("part"); + public static final Property CHEST_TYPE = Property.create("type"); + public static final Property MODE_COMPARATOR = Property.create("mode"); + public static final Property DOOR_HINGE = Property.create("hinge"); + public static final Property NOTEBLOCK_INSTRUMENT = Property.create("instrument"); + public static final Property PISTON_TYPE = Property.create("type"); + public static final Property SLAB_TYPE = Property.create("type"); + public static final Property STAIRS_SHAPE = Property.create("shape"); + public static final Property STRUCTUREBLOCK_MODE = Property.create("mode"); + public static final Property BAMBOO_LEAVES = Property.create("leaves"); + public static final Property TILT = Property.create("tilt"); + public static final Property VERTICAL_DIRECTION = Property.create("vertical_direction"); + public static final Property DRIPSTONE_THICKNESS = Property.create("thickness"); + public static final Property SCULK_SENSOR_PHASE = Property.create("sculk_sensor_phase"); + public static final Property CHISELED_BOOKSHELF_SLOT_0_OCCUPIED = Property.create("slot_0_occupied"); + public static final Property CHISELED_BOOKSHELF_SLOT_1_OCCUPIED = Property.create("slot_1_occupied"); + public static final Property CHISELED_BOOKSHELF_SLOT_2_OCCUPIED = Property.create("slot_2_occupied"); + public static final Property CHISELED_BOOKSHELF_SLOT_3_OCCUPIED = Property.create("slot_3_occupied"); + public static final Property CHISELED_BOOKSHELF_SLOT_4_OCCUPIED = Property.create("slot_4_occupied"); + public static final Property CHISELED_BOOKSHELF_SLOT_5_OCCUPIED = Property.create("slot_5_occupied"); + public static final Property DUSTED = Property.create("dusted"); + public static final Property CRACKED = Property.create("cracked"); + public static final Property CRAFTING = Property.create("crafting"); + public static final Property TRIAL_SPAWNER_STATE = Property.create("trial_spawner_state"); + public static final Property VAULT_STATE = Property.create("vault_state"); + public static final Property OMINOUS = Property.create("ominous"); +} diff --git a/core/src/main/java/org/geysermc/geyser/level/block/property/Property.java b/core/src/main/java/org/geysermc/geyser/level/block/property/Property.java new file mode 100644 index 000000000..da68c54e4 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/property/Property.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.property; + +public class Property> { + private final String name; + + public Property(String name) { + this.name = name; + } + + @Override + public String toString() { + return getClass().getSimpleName() + "[" + name + "]"; + } + + public static > Property create(String name) { + return new Property<>(name); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/BannerBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/BannerBlock.java new file mode 100644 index 000000000..481004baa --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/BannerBlock.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.type; + +public class BannerBlock extends Block { + private final int dyeColor; + + public BannerBlock(String javaIdentifier, int dyeColor, Builder builder) { + super(javaIdentifier, builder); + this.dyeColor = dyeColor; + } + + public int dyeColor() { + return dyeColor; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/BedBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/BedBlock.java new file mode 100644 index 000000000..e72dbdafa --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/BedBlock.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.type; + +public class BedBlock extends Block { + private final int dyeColor; + + public BedBlock(String javaIdentifier, int dyeColor, Builder builder) { + super(javaIdentifier, builder); + this.dyeColor = dyeColor; + } + + public int dyeColor() { + return dyeColor; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java b/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java new file mode 100644 index 000000000..459f4a5af --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.type; + +import it.unimi.dsi.fastutil.Pair; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; +import it.unimi.dsi.fastutil.objects.Reference2ObjectArrayMap; +import it.unimi.dsi.fastutil.objects.Reference2ObjectMap; +import org.geysermc.geyser.level.block.property.Property; +import org.geysermc.geyser.registry.BlockRegistries; +import org.geysermc.mcprotocollib.protocol.data.game.Identifier; + +import java.util.*; +import java.util.stream.Stream; + +public class Block { + public static final int JAVA_AIR_ID = 0; + + private final String javaIdentifier; + private int javaId = -1; + + public Block(String javaIdentifier, Builder builder) { + this.javaIdentifier = Identifier.formalize(javaIdentifier).intern(); + builder.build(this); + } + + public String javaIdentifier() { + return javaIdentifier; + } + + public int javaId() { + return javaId; + } + + public void setJavaId(int javaId) { + if (this.javaId != -1) { + throw new RuntimeException("Block ID has already been set!"); + } + this.javaId = javaId; + } + + @Override + public String toString() { + return "Item{" + + "javaIdentifier='" + javaIdentifier + '\'' + + ", javaId=" + javaId + + '}'; + } + + public static Builder builder() { + return new Builder(); + } + + public static final class Builder { + private final Map, List>> states = new LinkedHashMap<>(); + + /** + * For states that we're just tracking for mirroring Java states. + */ + public Builder enumState(Property property, String... values) { + states.put(property, List.of(values)); + return this; + } + + @SafeVarargs + public final > Builder enumState(Property property, T... enums) { + states.put(property, List.of(enums)); + return this; + } + + public Builder booleanState(Property property) { + states.put(property, List.of(Boolean.TRUE, Boolean.FALSE)); // Make this list a static constant if it'll survive past initialization + return this; + } + + public Builder intState(Property property, int low, int high) { + IntList list = new IntArrayList(); + // There is a state for every number between the low and high. + for (int i = low; i <= high; i++) { + list.add(i); + } + states.put(property, List.copyOf(list)); // Boxing reasons for that copy I guess. + return this; + } + + private void build(Block block) { + if (states.isEmpty()) { + BlockRegistries.BLOCK_STATES.get().add(new BlockState(block, BlockRegistries.BLOCK_STATES.get().size())); + } else { + // Think of this stream as another list containing, at the start, one empty list. + // It's two collections. Not a stream from the empty list. + Stream, Comparable>>> stream = Stream.of(Collections.emptyList()); + for (var state : this.states.entrySet()) { + // OK, so here's how I understand this works. Because this was staring at vanilla Java code trying + // to figure out exactly how it works so we don't have any discrepencies. + // For each existing pair in the list, a new list is created, adding one of the new values. + // Property up [true/false] would exist as true and false + // Both entries will get duplicated, adding down, true and false. + stream = stream.flatMap(aPreviousPropertiesList -> + // So the above is a list. It may be empty if this is the first property, + // or it may be populated if this is not the first property. + // We're about to create a new stream, each with a new list, + // for every previous property + state.getValue().stream().map(value -> { + var newProperties = new ArrayList<>(aPreviousPropertiesList); + newProperties.add(Pair.of(state.getKey(), value)); + return newProperties; + })); + } + + // Now we have a list of Pairs. Each list is a block state! + // If we have two boolean properties: up [true/false] and down [true/false], + // We'll see [up=true,down=true], [up=false,down=true], [up=true,down=false], [up=false,down=false] + stream.forEach(properties -> { + Reference2ObjectMap, Comparable> propertyMap = new Reference2ObjectArrayMap<>(properties.size()); + for (int i = 0; i < properties.size(); i++) { + Pair, Comparable> property = properties.get(i); + propertyMap.put(property.key(), property.value()); + } + BlockRegistries.BLOCK_STATES.get().add(new BlockState(block, BlockRegistries.BLOCK_STATES.get().size(), propertyMap)); + }); + } + } + + private Builder() { + } + } +} diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java b/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java new file mode 100644 index 000000000..936b711e4 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.type; + +import it.unimi.dsi.fastutil.objects.Reference2ObjectMap; +import it.unimi.dsi.fastutil.objects.Reference2ObjectMaps; +import org.geysermc.geyser.level.block.property.Property; +import org.geysermc.geyser.registry.BlockRegistries; + +public final class BlockState { + private final Block block; + private final int javaId; + private final Reference2ObjectMap, Comparable> states; + + BlockState(Block block, int javaId) { + this(block, javaId, Reference2ObjectMaps.emptyMap()); + } + + BlockState(Block block, int javaId, Reference2ObjectMap, Comparable> states) { + this.block = block; + this.javaId = javaId; + this.states = states; + } + + public > T getValue(Property property) { + //noinspection unchecked + return (T) states.get(property); + } + + public Block block() { + return block; + } + + public int javaId() { + return javaId; + } + + public static BlockState of(int javaId) { + return BlockRegistries.BLOCK_STATES.get(javaId); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java b/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java index aa9d6fc36..54a36dc12 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java +++ b/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java @@ -34,6 +34,8 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import org.geysermc.geyser.api.block.custom.CustomBlockData; import org.geysermc.geyser.api.block.custom.CustomBlockState; import org.geysermc.geyser.api.block.custom.nonvanilla.JavaBlockState; +import org.geysermc.geyser.level.block.type.Block; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.registry.loader.CollisionRegistryLoader; import org.geysermc.geyser.registry.loader.RegistryLoaders; import org.geysermc.geyser.registry.populator.BlockRegistryPopulator; @@ -44,8 +46,8 @@ import org.geysermc.geyser.registry.type.BlockMappings; import org.geysermc.geyser.registry.type.CustomSkull; import org.geysermc.geyser.translator.collision.BlockCollision; +import java.util.ArrayList; import java.util.BitSet; - import java.util.Set; /** @@ -58,6 +60,14 @@ public class BlockRegistries { */ public static final VersionedRegistry BLOCKS = VersionedRegistry.create(RegistryLoaders.empty(Int2ObjectOpenHashMap::new)); + /** + * A registry which stores Java IDs to Java {@link BlockState}s, each with their specific state differences and a link + * to the overarching block. + */ + public static final ListRegistry BLOCK_STATES = ListRegistry.create(RegistryLoaders.empty(ArrayList::new)); + + public static final ListRegistry JAVA_BLOCKS_TO_RENAME = ListRegistry.create(RegistryLoaders.empty(ArrayList::new)); + /** * A mapped registry which stores Java to Bedrock block identifiers. */ diff --git a/core/src/main/java/org/geysermc/geyser/registry/ListRegistry.java b/core/src/main/java/org/geysermc/geyser/registry/ListRegistry.java new file mode 100644 index 000000000..bb5d2538c --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/registry/ListRegistry.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.registry; + +import org.checkerframework.checker.nullness.qual.Nullable; +import org.geysermc.geyser.registry.loader.RegistryLoader; + +import java.util.List; + +public class ListRegistry extends Registry> { + /** + * Creates a new instance of this class with the given input and + * {@link RegistryLoader}. The input specified is what the registry + * loader needs to take in. + * + * @param input the input + * @param registryLoader the registry loader + */ + protected ListRegistry(I input, RegistryLoader> registryLoader) { + super(input, registryLoader); + } + + /** + * Returns the value registered by the given index. + * + * @param index the index + * @return the value registered by the given index. + */ + @Nullable + public M get(int index) { + if (index >= this.mappings.size()) { + return null; + } + + return this.mappings.get(index); + } + + /** + * Returns the value registered by the given index or the default value + * specified if null. + * + * @param index the index + * @param defaultValue the default value + * @return the value registered by the given key or the default value + * specified if null. + */ + public M getOrDefault(int index, M defaultValue) { + M value = this.get(index); + if (value == null) { + return defaultValue; + } + + return value; + } + + /** + * Registers a new value into this registry with the given index. + * + * @param index the index + * @param value the value + * @return a new value into this registry with the given index. + */ + public M register(int index, M value) { + return this.mappings.set(index, value); + } + + /** + * Creates a new array registry with the given {@link RegistryLoader}. The + * input type is not specified here, meaning the loader return type is either + * predefined, or the registry is populated at a later point. + * + * @param registryLoader the registry loader + * @param the input type + * @param the returned mappings type + * @return a new registry with the given RegistryLoader supplier + */ + public static ListRegistry create(RegistryLoader> registryLoader) { + return new ListRegistry(null, registryLoader); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java index e76edc059..ace110f78 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java @@ -582,8 +582,6 @@ public final class BlockRegistryPopulator { } } - BlockRegistries.CLEAN_JAVA_IDENTIFIERS.set(cleanIdentifiers.toArray(new String[0])); - BLOCKS_JSON = blocksJson; JsonNode blockInteractionsJson; diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index c0ff1fb71..144cd9f27 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -1592,9 +1592,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { startGamePacket.setRewindHistorySize(0); startGamePacket.setServerAuthoritativeBlockBreaking(false); - // Entity properties for older versions - startGamePacket.getExperiments().add(new ExperimentData("upcoming_creator_features", true)); - upstream.sendPacket(startGamePacket); } diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/ChunkCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/ChunkCache.java index e3a9cba89..7b279857a 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/ChunkCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/ChunkCache.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.session.cache; +import org.geysermc.geyser.level.block.type.Block; import org.geysermc.mcprotocollib.protocol.data.game.chunk.DataPalette; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; @@ -92,11 +93,11 @@ public class ChunkCache { DataPalette palette = chunk.sections()[(y - minY) >> 4]; if (palette == null) { - if (block != BlockStateValues.JAVA_AIR_ID) { + if (block != Block.JAVA_AIR_ID) { // A previously empty chunk, which is no longer empty as a block has been added to it palette = DataPalette.createForChunk(); // Fixes the chunk assuming that all blocks is the `block` variable we are updating. /shrug - palette.getPalette().stateToId(BlockStateValues.JAVA_AIR_ID); + palette.getPalette().stateToId(Block.JAVA_AIR_ID); chunk.sections()[(y - minY) >> 4] = palette; } else { // Nothing to update @@ -109,17 +110,17 @@ public class ChunkCache { public int getBlockAt(int x, int y, int z) { if (!cache) { - return BlockStateValues.JAVA_AIR_ID; + return Block.JAVA_AIR_ID; } GeyserChunk column = this.getChunk(x >> 4, z >> 4); if (column == null) { - return BlockStateValues.JAVA_AIR_ID; + return Block.JAVA_AIR_ID; } if (y < minY || ((y - minY) >> 4) > column.sections().length - 1) { // Y likely goes above or below the height limit of this world - return BlockStateValues.JAVA_AIR_ID; + return Block.JAVA_AIR_ID; } DataPalette chunk = column.sections()[(y - minY) >> 4]; @@ -127,7 +128,7 @@ public class ChunkCache { return chunk.get(x & 0xF, y & 0xF, z & 0xF); } - return BlockStateValues.JAVA_AIR_ID; + return Block.JAVA_AIR_ID; } public void removeChunk(int chunkX, int chunkZ) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java index f9879499a..795eba101 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java @@ -35,6 +35,7 @@ import org.geysermc.geyser.inventory.BedrockContainerSlot; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.holder.BlockInventoryHolder; import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator; @@ -58,7 +59,7 @@ public class ShulkerInventoryTranslator extends AbstractBlockInventoryTranslator .putInt("z", position.getZ()) .putString("CustomName", inventory.getTitle()); // Don't reset facing property - shulkerBoxTranslator.translateTag(session, tag, null, javaBlockState); + shulkerBoxTranslator.translateTag(session, tag, null, BlockState.of(javaBlockState)); BlockEntityDataPacket dataPacket = new BlockEntityDataPacket(); dataPacket.setData(tag.build()); diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java index 498bd418b..cb973fa18 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java @@ -36,8 +36,7 @@ import org.cloudburstmc.protocol.bedrock.packet.ContainerOpenPacket; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; import org.geysermc.geyser.inventory.Container; import org.geysermc.geyser.inventory.Inventory; -import org.geysermc.geyser.level.block.BlockStateValues; -import org.geysermc.geyser.level.block.DoubleChestValue; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.type.BlockMapping; import org.geysermc.geyser.session.GeyserSession; @@ -72,8 +71,8 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator { .putString("CustomName", inventory.getTitle()) .putString("id", "Chest"); - DoubleChestValue chestValue = BlockStateValues.getDoubleChestValues().get(javaBlockId); - DoubleChestBlockEntityTranslator.translateChestValue(tag, chestValue, + BlockState blockState = BlockState.of(javaBlockId); + DoubleChestBlockEntityTranslator.translateChestValue(tag, blockState, session.getLastInteractionBlockPosition().getX(), session.getLastInteractionBlockPosition().getZ()); BlockEntityDataPacket dataPacket = new BlockEntityDataPacket(); diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java index 81f58214c..8b6f627e1 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BannerBlockEntityTranslator.java @@ -30,7 +30,8 @@ import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.item.type.BannerItem; -import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.type.BannerBlock; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @@ -39,10 +40,9 @@ import java.util.List; @BlockEntity(type = BlockEntityType.BANNER) public class BannerBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override - public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, @Nullable NbtMap javaNbt, int blockState) { - int bannerColor = BlockStateValues.getBannerColor(blockState); - if (bannerColor != -1) { - bedrockNbt.putInt("Base", 15 - bannerColor); + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, @Nullable NbtMap javaNbt, BlockState blockState) { + if (blockState.block() instanceof BannerBlock banner) { + bedrockNbt.putInt("Base", 15 - banner.dyeColor()); } if (javaNbt == null) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BeaconBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BeaconBlockEntityTranslator.java index f7dee2864..9b5248785 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BeaconBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BeaconBlockEntityTranslator.java @@ -27,13 +27,14 @@ package org.geysermc.geyser.translator.level.block.entity; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.BEACON) public class BeaconBlockEntityTranslator extends BlockEntityTranslator { @Override - public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) { int primary = javaNbt.getInt("primary"); // The effects here generally map one-to-one Java <-> Bedrock. Only the newer ones get more complicated bedrockNbt.putInt("primary", primary == -1 ? 0 : primary); diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedBlockEntityTranslator.java index 720ffea3c..7622e6d28 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedBlockEntityTranslator.java @@ -27,19 +27,15 @@ package org.geysermc.geyser.translator.level.block.entity; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; -import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.type.BedBlock; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.BED) public class BedBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override - public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { - byte bedcolor = BlockStateValues.getBedColor(blockState); - // Just in case... - if (bedcolor == -1) { - bedcolor = 0; - } - bedrockNbt.putByte("color", bedcolor); + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) { + bedrockNbt.putByte("color", (byte) (blockState.block() instanceof BedBlock bed ? bed.dyeColor() : 0)); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedrockOnlyBlockEntity.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedrockOnlyBlockEntity.java index 051986473..01e2d3e74 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedrockOnlyBlockEntity.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedrockOnlyBlockEntity.java @@ -31,6 +31,7 @@ import org.cloudburstmc.nbt.NbtList; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; /** @@ -50,7 +51,7 @@ public interface BedrockOnlyBlockEntity extends RequiresBlockState { * @param blockState The Java block state. * @param position The Bedrock block position. */ - void updateBlock(GeyserSession session, int blockState, Vector3i position); + void updateBlock(GeyserSession session, BlockState blockState, Vector3i position); /** * Get the tag of the Bedrock-only block entity diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java index 6df7781be..5def51e01 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java @@ -28,6 +28,7 @@ package org.geysermc.geyser.translator.level.block.entity; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.BlockEntityUtils; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @@ -39,9 +40,9 @@ public abstract class BlockEntityTranslator { protected BlockEntityTranslator() { } - public abstract void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState); + public abstract void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState); - public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, @Nullable NbtMap javaNbt, int blockState) { + public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, @Nullable NbtMap javaNbt, BlockState blockState) { NbtMapBuilder tagBuilder = getConstantBedrockTag(type, x, y, z); if (javaNbt != null || this instanceof RequiresBlockState) { // Always process tags if the block state is part of the tag. diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java index b4012236b..f0d632041 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BrushableBlockEntityTranslator.java @@ -29,7 +29,8 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @@ -38,7 +39,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType public class BrushableBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override - public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, @Nullable NbtMap javaNbt, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, @Nullable NbtMap javaNbt, BlockState blockState) { if (javaNbt == null) { return; } @@ -70,6 +71,6 @@ public class BrushableBlockEntityTranslator extends BlockEntityTranslator implem // controls which side the item protrudes from bedrockNbt.putByte("brush_direction", hitDirection); // controls how much the item protrudes - bedrockNbt.putInt("brush_count", BlockStateValues.getBrushProgress(blockState)); + bedrockNbt.putInt("brush_count", blockState.getValue(Properties.DUSTED)); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CampfireBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CampfireBlockEntityTranslator.java index 699319bb6..fb71a84cc 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CampfireBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CampfireBlockEntityTranslator.java @@ -28,6 +28,7 @@ package org.geysermc.geyser.translator.level.block.entity; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; @@ -38,7 +39,7 @@ import java.util.List; @BlockEntity(type = BlockEntityType.CAMPFIRE) public class CampfireBlockEntityTranslator extends BlockEntityTranslator { @Override - public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) { List items = javaNbt.getList("Items", NbtType.COMPOUND); if (items != null) { int i = 1; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CommandBlockBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CommandBlockBlockEntityTranslator.java index 0e00a19a8..b363de530 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CommandBlockBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CommandBlockBlockEntityTranslator.java @@ -27,7 +27,8 @@ package org.geysermc.geyser.translator.level.block.entity; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; -import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @@ -35,12 +36,12 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType @BlockEntity(type = BlockEntityType.COMMAND_BLOCK) public class CommandBlockBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override - public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) { if (javaNbt == null || javaNbt.size() < 5) { return; // These values aren't here } // Java infers from the block state, but Bedrock needs it in the tag - bedrockNbt.putByte("conditionalMode", BlockStateValues.getCommandBlockValues().getOrDefault(blockState, (byte) 0)); + bedrockNbt.putBoolean("conditionalMode", blockState.getValue(Properties.CONDITIONAL)); // Java and Bedrock values bedrockNbt.putByte("conditionMet", javaNbt.getByte("conditionMet")); bedrockNbt.putByte("auto", javaNbt.getByte("auto")); diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java index b24558b45..33c884c55 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DecoratedPotBlockEntityTranslator.java @@ -28,6 +28,7 @@ package org.geysermc.geyser.translator.level.block.entity; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @@ -35,7 +36,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType public class DecoratedPotBlockEntityTranslator extends BlockEntityTranslator { @Override - public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) { if (javaNbt == null) { return; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java index dcb39d22c..63c5f71f3 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java @@ -29,7 +29,9 @@ import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.block.BlockStateValues; -import org.geysermc.geyser.level.block.DoubleChestValue; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.level.block.type.BlockState; +import org.geysermc.geyser.level.physics.Direction; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.BlockEntityUtils; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @@ -45,52 +47,40 @@ public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator impl } @Override - public void updateBlock(GeyserSession session, int blockState, Vector3i position) { + public void updateBlock(GeyserSession session, BlockState blockState, Vector3i position) { NbtMapBuilder tagBuilder = getConstantBedrockTag(BlockEntityUtils.getBedrockBlockEntityId(BlockEntityType.CHEST), position.getX(), position.getY(), position.getZ()); translateTag(session, tagBuilder, null, blockState); BlockEntityUtils.updateBlockEntity(session, tagBuilder.build(), position); } @Override - public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { - DoubleChestValue chestValues = BlockStateValues.getDoubleChestValues().get(blockState); - if (chestValues != null) { - int x = (int) bedrockNbt.get("x"); - int z = (int) bedrockNbt.get("z"); - translateChestValue(bedrockNbt, chestValues, x, z); - } + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) { + int x = (int) bedrockNbt.get("x"); + int z = (int) bedrockNbt.get("z"); + translateChestValue(bedrockNbt, blockState, x, z); } /** * Add Bedrock block entity tags to a NbtMap based on Java properties * * @param builder the NbtMapBuilder to apply properties to - * @param chestValues the position properties of this double chest + * @param state the BlockState of this double chest * @param x the x position of this chest pair * @param z the z position of this chest pair */ - public static void translateChestValue(NbtMapBuilder builder, DoubleChestValue chestValues, int x, int z) { + public static void translateChestValue(NbtMapBuilder builder, BlockState state, int x, int z) { // Calculate the position of the other chest based on the Java block state - if (chestValues.isFacingEast()) { - if (chestValues.isDirectionPositive()) { - // East - z = z + (chestValues.isLeft() ? 1 : -1); - } else { - // West - z = z + (chestValues.isLeft() ? -1 : 1); - } - } else { - if (chestValues.isDirectionPositive()) { - // South - x = x + (chestValues.isLeft() ? -1 : 1); - } else { - // North - x = x + (chestValues.isLeft() ? 1 : -1); - } + Direction facing = state.getValue(Properties.HORIZONTAL_FACING); + boolean isLeft = state.getValue(Properties.CHEST_TYPE).equals("left"); //TODO enum + switch (facing) { + case EAST -> z = z + (isLeft ? 1 : -1); + case WEST -> z = z + (isLeft ? -1 : 1); + case SOUTH -> x = x + (isLeft ? -1 : 1); + case NORTH -> x = x + (isLeft ? 1 : -1); } builder.putInt("pairx", x); builder.putInt("pairz", z); - if (!chestValues.isLeft()) { + if (!isLeft) { builder.putInt("pairlead", (byte) 1); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EmptyBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EmptyBlockEntityTranslator.java index 9ce0aff0a..88029dc2d 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EmptyBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EmptyBlockEntityTranslator.java @@ -27,10 +27,11 @@ package org.geysermc.geyser.translator.level.block.entity; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; public class EmptyBlockEntityTranslator extends BlockEntityTranslator { @Override - public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) { } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EndGatewayBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EndGatewayBlockEntityTranslator.java index 97428eec1..36731bdff 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EndGatewayBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/EndGatewayBlockEntityTranslator.java @@ -31,13 +31,14 @@ import org.cloudburstmc.nbt.NbtList; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.END_GATEWAY) public class EndGatewayBlockEntityTranslator extends BlockEntityTranslator { @Override - public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) { bedrockNbt.putInt("Age", (int) javaNbt.getLong("Age")); // Java sometimes does not provide this tag, but Bedrock crashes if it doesn't exist // Linked coordinates diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/FlowerPotBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/FlowerPotBlockEntityTranslator.java index 074fff6ef..0a60b0f32 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/FlowerPotBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/FlowerPotBlockEntityTranslator.java @@ -30,6 +30,7 @@ import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.BlockEntityUtils; @@ -75,12 +76,12 @@ public class FlowerPotBlockEntityTranslator implements BedrockOnlyBlockEntity { } @Override - public void updateBlock(GeyserSession session, int blockState, Vector3i position) { - NbtMap tag = getTag(session, blockState, position); + public void updateBlock(GeyserSession session, BlockState blockState, Vector3i position) { + NbtMap tag = getTag(session, blockState.javaId(), position); BlockEntityUtils.updateBlockEntity(session, tag, position); UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); updateBlockPacket.setDataLayer(0); - updateBlockPacket.setDefinition(session.getBlockMappings().getBedrockBlock(blockState)); + updateBlockPacket.setDefinition(session.getBlockMappings().getBedrockBlock(blockState.javaId())); updateBlockPacket.setBlockPosition(position); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK); diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java index 53f32682c..51f5565b7 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java @@ -29,13 +29,14 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @BlockEntity(type = BlockEntityType.JIGSAW) public class JigsawBlockBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override - public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, @Nullable NbtMap javaNbt, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, @Nullable NbtMap javaNbt, BlockState blockState) { if (javaNbt == null) { return; } @@ -46,7 +47,7 @@ public class JigsawBlockBlockEntityTranslator extends BlockEntityTranslator impl } else { // Tag is not present in at least 1.14.4 Paper // Minecraft 1.18.1 deliberately has a fallback here, but not for any other value - bedrockNbt.putString("joint", BlockStateValues.getHorizontalFacingJigsaws().contains(blockState) ? "aligned" : "rollable"); + bedrockNbt.putString("joint", BlockStateValues.getHorizontalFacingJigsaws().contains(blockState.javaId()) ? "aligned" : "rollable"); // TODO } bedrockNbt.putString("name", javaNbt.getString("name")); bedrockNbt.putString("target_pool", javaNbt.getString("target_pool")); diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java index 78e71000a..e09f6ae42 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; +import org.geysermc.geyser.level.block.type.Block; import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.PistonValueType; import org.cloudburstmc.math.vector.Vector3d; import org.cloudburstmc.math.vector.Vector3f; @@ -222,10 +223,10 @@ public class PistonBlockEntity { Vector3i blockInFront = position.add(orientation.getUnitVector()); int blockId = session.getGeyser().getWorldManager().getBlockAt(session, blockInFront); if (BlockStateValues.isPistonHead(blockId)) { - ChunkUtils.updateBlock(session, BlockStateValues.JAVA_AIR_ID, blockInFront); - } else if ((session.getGeyser().getPlatformType() == PlatformType.SPIGOT || session.getErosionHandler().isActive()) && blockId == BlockStateValues.JAVA_AIR_ID) { + ChunkUtils.updateBlock(session, Block.JAVA_AIR_ID, blockInFront); + } else if ((session.getGeyser().getPlatformType() == PlatformType.SPIGOT || session.getErosionHandler().isActive()) && blockId == Block.JAVA_AIR_ID) { // Spigot removes the piston head from the cache, but we need to send the block update ourselves - ChunkUtils.updateBlock(session, BlockStateValues.JAVA_AIR_ID, blockInFront); + ChunkUtils.updateBlock(session, Block.JAVA_AIR_ID, blockInFront); } } @@ -255,7 +256,7 @@ public class PistonBlockEntity { continue; } int blockId = session.getGeyser().getWorldManager().getBlockAt(session, blockPos); - if (blockId == BlockStateValues.JAVA_AIR_ID) { + if (blockId == Block.JAVA_AIR_ID) { continue; } if (BlockStateValues.canPistonMoveBlock(blockId, action == PistonValueType.PUSHING)) { @@ -278,7 +279,7 @@ public class PistonBlockEntity { continue; } int adjacentBlockId = session.getGeyser().getWorldManager().getBlockAt(session, adjacentPos); - if (adjacentBlockId != BlockStateValues.JAVA_AIR_ID && BlockStateValues.isBlockAttached(blockId, adjacentBlockId) && BlockStateValues.canPistonMoveBlock(adjacentBlockId, false)) { + if (adjacentBlockId != Block.JAVA_AIR_ID && BlockStateValues.isBlockAttached(blockId, adjacentBlockId) && BlockStateValues.canPistonMoveBlock(adjacentBlockId, false)) { // If it is another slime/honey block we need to check its adjacent blocks if (BlockStateValues.isBlockSticky(adjacentBlockId)) { blocksToCheck.add(adjacentPos); @@ -322,7 +323,7 @@ public class PistonBlockEntity { */ private void removeBlocks() { for (Vector3i blockPos : attachedBlocks.keySet()) { - ChunkUtils.updateBlock(session, BlockStateValues.JAVA_AIR_ID, blockPos); + ChunkUtils.updateBlock(session, Block.JAVA_AIR_ID, blockPos); } if (action != PistonValueType.PUSHING) { removePistonHead(); @@ -560,7 +561,7 @@ public class PistonBlockEntity { if (blockPos.equals(getPistonHeadPos())) { return BlockStateValues.getPistonHead(orientation); } else { - return attachedBlocks.getOrDefault(blockPos, BlockStateValues.JAVA_AIR_ID); + return attachedBlocks.getOrDefault(blockPos, Block.JAVA_AIR_ID); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/ShulkerBoxBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/ShulkerBoxBlockEntityTranslator.java index ba2ddd815..e6d19e492 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/ShulkerBoxBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/ShulkerBoxBlockEntityTranslator.java @@ -28,7 +28,8 @@ package org.geysermc.geyser.translator.level.block.entity; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; -import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.inventory.ShulkerInventoryTranslator; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @@ -40,12 +41,7 @@ public class ShulkerBoxBlockEntityTranslator extends BlockEntityTranslator imple * where {@code tag} is passed as null. */ @Override - public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, @Nullable NbtMap javaNbt, int blockState) { - byte direction = BlockStateValues.getShulkerBoxDirection(blockState); - // Just in case... - if (direction == -1) { - direction = 1; - } - bedrockNbt.putByte("facing", direction); + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, @Nullable NbtMap javaNbt, BlockState blockState) { + bedrockNbt.putByte("facing", (byte) blockState.getValue(Properties.FACING).ordinal()); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SignBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SignBlockEntityTranslator.java index bbf0dbcb3..2a1ccb639 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SignBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SignBlockEntityTranslator.java @@ -28,6 +28,7 @@ package org.geysermc.geyser.translator.level.block.entity; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.translator.text.MessageTranslator; @@ -73,7 +74,7 @@ public class SignBlockEntityTranslator extends BlockEntityTranslator { } @Override - public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) { bedrockNbt.putCompound("FrontText", translateSide(javaNbt.getCompound("front_text"))); bedrockNbt.putCompound("BackText", translateSide(javaNbt.getCompound("back_text"))); bedrockNbt.putBoolean("IsWaxed", javaNbt.getBoolean("is_waxed")); diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java index b1ab017e8..c03ae8ef0 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java @@ -34,6 +34,8 @@ import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.SkullCache; import org.geysermc.geyser.skin.SkinProvider; @@ -50,16 +52,19 @@ import java.util.concurrent.ExecutionException; public class SkullBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override - public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { - byte skullVariant = BlockStateValues.getSkullVariant(blockState); - float rotation = BlockStateValues.getSkullRotation(blockState) * 22.5f; + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) { + byte skullVariant = BlockStateValues.getSkullVariant(blockState.javaId()); // TODO // Just in case... if (skullVariant == -1) { skullVariant = 0; } - bedrockNbt.putFloat("Rotation", rotation); + Integer rotation = blockState.getValue(Properties.ROTATION_16); + if (rotation != null) { + // Could be a wall skull block + bedrockNbt.putFloat("Rotation", rotation * 22.5f); + } bedrockNbt.putByte("SkullType", skullVariant); - if (BlockStateValues.isSkullPowered(blockState)) { + if (blockState.getValue(Properties.POWERED)) { bedrockNbt.putBoolean("MouthMoving", true); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java index edf71d384..4b6a630ba 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java @@ -32,6 +32,7 @@ import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; import org.geysermc.geyser.entity.EntityDefinition; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @@ -40,7 +41,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType public class SpawnerBlockEntityTranslator extends BlockEntityTranslator { @Override - public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, @Nullable NbtMap javaNbt, int blockState) { + public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, @Nullable NbtMap javaNbt, BlockState blockState) { if (javaNbt == null) { return super.getBlockEntityTag(session, type, x, y, z, javaNbt, blockState); } @@ -70,7 +71,7 @@ public class SpawnerBlockEntityTranslator extends BlockEntityTranslator { } @Override - public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) { Object current; // TODO use primitive get and put methods diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java index 4bb9c5676..79fb3da6b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java @@ -32,6 +32,7 @@ import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.data.structure.StructureMirror; import org.cloudburstmc.protocol.bedrock.data.structure.StructureRotation; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.StructureBlockUtils; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @@ -40,7 +41,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType public class StructureBlockBlockEntityTranslator extends BlockEntityTranslator { @Override - public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, @Nullable NbtMap javaNbt, int blockState) { + public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, @Nullable NbtMap javaNbt, BlockState blockState) { if (javaNbt == null) { return super.getBlockEntityTag(session, type, x, y, z, javaNbt, blockState); } @@ -73,7 +74,7 @@ public class StructureBlockBlockEntityTranslator extends BlockEntityTranslator { } @Override - public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) { if (javaNbt.size() < 5) { return; // These values aren't here } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/TrialSpawnerBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/TrialSpawnerBlockEntityTranslator.java index ff3f89f3f..a4c158a15 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/TrialSpawnerBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/TrialSpawnerBlockEntityTranslator.java @@ -27,6 +27,7 @@ package org.geysermc.geyser.translator.level.block.entity; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @@ -34,7 +35,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType public class TrialSpawnerBlockEntityTranslator extends BlockEntityTranslator { @Override - public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) { + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) { if (javaNbt == null) { return; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java index 35c46ffd2..9cb3fb455 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.translator.protocol.bedrock; +import org.geysermc.geyser.level.block.type.Block; import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.packet.BlockPickRequestPacket; @@ -48,7 +49,7 @@ public class BedrockBlockPickRequestTranslator extends PacketTranslator> 4) - yOffset]; - int blockState = section.get(x, y & 0xF, z); + BlockState blockState = BlockRegistries.BLOCK_STATES.get(section.get(x, y & 0xF, z)); - if (type == BlockEntityType.LECTERN && BlockStateValues.getLecternBookStates().get(blockState)) { + if (type == BlockEntityType.LECTERN && blockState.getValue(Properties.HAS_BOOK)) { // If getLecternBookStates is false, let's just treat it like a normal block entity // Fill in tag with a default value NbtMapBuilder lecternTag = LecternUtils.getBaseLecternTag(x + chunkBlockX, y, z + chunkBlockZ, 1); @@ -419,7 +422,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator> 4) - (bedrockDimension.minY() >> 4); int subChunkIndex = (y >> 4) + (bedrockDimension.minY() >> 4); diff --git a/core/src/main/java/org/geysermc/geyser/util/ChunkUtils.java b/core/src/main/java/org/geysermc/geyser/util/ChunkUtils.java index 379162540..a1e956ace 100644 --- a/core/src/main/java/org/geysermc/geyser/util/ChunkUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/ChunkUtils.java @@ -41,6 +41,8 @@ import org.geysermc.geyser.entity.type.ItemFrameEntity; import org.geysermc.geyser.level.BedrockDimension; import org.geysermc.geyser.level.JavaDimension; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.type.Block; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.level.chunk.BlockStorage; import org.geysermc.geyser.level.chunk.GeyserChunkSection; import org.geysermc.geyser.level.chunk.bitarray.SingletonBitArray; @@ -50,8 +52,6 @@ import org.geysermc.geyser.session.cache.SkullCache; import org.geysermc.geyser.text.GeyserLocale; import org.geysermc.geyser.translator.level.block.entity.BedrockOnlyBlockEntity; -import static org.geysermc.geyser.level.block.BlockStateValues.JAVA_AIR_ID; - @UtilityClass public class ChunkUtils { @@ -130,7 +130,7 @@ public class ChunkUtils { // Checks for item frames so they aren't tripped up and removed ItemFrameEntity itemFrameEntity = ItemFrameEntity.getItemFrameEntity(session, position); if (itemFrameEntity != null) { - if (blockState == JAVA_AIR_ID) { // Item frame is still present and no block overrides that; refresh it + if (blockState == Block.JAVA_AIR_ID) { // Item frame is still present and no block overrides that; refresh it itemFrameEntity.updateBlock(true); // Still update the chunk cache with the new block if updateBlock is called return; @@ -180,21 +180,21 @@ public class ChunkUtils { BlockDefinition aboveBedrockExtendedCollisionDefinition = session.getBlockMappings().getExtendedCollisionBoxes().get(blockState); int belowBlock = session.getGeyser().getWorldManager().getBlockAt(session, position.getX(), position.getY() - 1, position.getZ()); BlockDefinition belowBedrockExtendedCollisionDefinition = session.getBlockMappings().getExtendedCollisionBoxes().get(belowBlock); - if (belowBedrockExtendedCollisionDefinition != null && blockState == BlockStateValues.JAVA_AIR_ID) { + if (belowBedrockExtendedCollisionDefinition != null && blockState == Block.JAVA_AIR_ID) { UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); updateBlockPacket.setDataLayer(0); updateBlockPacket.setBlockPosition(position); updateBlockPacket.setDefinition(belowBedrockExtendedCollisionDefinition); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK); session.sendUpstreamPacket(updateBlockPacket); - } else if (aboveBedrockExtendedCollisionDefinition != null && aboveBlock == BlockStateValues.JAVA_AIR_ID) { + } else if (aboveBedrockExtendedCollisionDefinition != null && aboveBlock == Block.JAVA_AIR_ID) { UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); updateBlockPacket.setDataLayer(0); updateBlockPacket.setBlockPosition(position.add(0, 1, 0)); updateBlockPacket.setDefinition(aboveBedrockExtendedCollisionDefinition); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK); session.sendUpstreamPacket(updateBlockPacket); - } else if (aboveBlock == BlockStateValues.JAVA_AIR_ID) { + } else if (aboveBlock == Block.JAVA_AIR_ID) { UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); updateBlockPacket.setDataLayer(0); updateBlockPacket.setBlockPosition(position.add(0, 1, 0)); @@ -211,7 +211,7 @@ public class ChunkUtils { for (BedrockOnlyBlockEntity bedrockOnlyBlockEntity : BlockEntityUtils.BEDROCK_ONLY_BLOCK_ENTITIES) { if (bedrockOnlyBlockEntity.isBlock(blockState)) { // Flower pots are block entities only in Bedrock and are not updated anywhere else like note blocks - bedrockOnlyBlockEntity.updateBlock(session, blockState, position); + bedrockOnlyBlockEntity.updateBlock(session, BlockState.of(blockState), position); //TODO blockState break; //No block will be a part of two classes } } diff --git a/core/src/main/java/org/geysermc/geyser/util/SoundUtils.java b/core/src/main/java/org/geysermc/geyser/util/SoundUtils.java index 85f8fc704..7559347e9 100644 --- a/core/src/main/java/org/geysermc/geyser/util/SoundUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/SoundUtils.java @@ -34,6 +34,7 @@ import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket; import org.cloudburstmc.protocol.bedrock.packet.PlaySoundPacket; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.SoundMapping; @@ -147,7 +148,7 @@ public final class SoundUtils { soundPacket.setExtraData(soundMapping.getExtraData() + (int)(Math.round((Math.log10(pitch) / Math.log10(2)) * 12)) + 12); } else if (sound == SoundEvent.PLACE && soundMapping.getExtraData() == -1) { if (!soundMapping.getIdentifier().equals(":")) { - int javaId = BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getOrDefault(soundMapping.getIdentifier(), BlockStateValues.JAVA_AIR_ID); + int javaId = BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getOrDefault(soundMapping.getIdentifier(), Block.JAVA_AIR_ID); soundPacket.setExtraData(session.getBlockMappings().getBedrockBlockId(javaId)); } else { session.getGeyser().getLogger().debug("PLACE sound mapping identifier was invalid! Please report: " + soundMapping); diff --git a/core/src/main/java/org/geysermc/geyser/util/StatisticsUtils.java b/core/src/main/java/org/geysermc/geyser/util/StatisticsUtils.java index 96328bcdd..8f9be0b98 100644 --- a/core/src/main/java/org/geysermc/geyser/util/StatisticsUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/StatisticsUtils.java @@ -29,6 +29,7 @@ import it.unimi.dsi.fastutil.objects.Object2IntMap; import org.geysermc.cumulus.form.SimpleForm; import org.geysermc.cumulus.util.FormImage; import org.geysermc.geyser.item.type.Item; +import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; @@ -93,10 +94,10 @@ public class StatisticsUtils { for (Object2IntMap.Entry entry : session.getStatistics().object2IntEntrySet()) { if (entry.getKey() instanceof BreakBlockStatistic statistic) { - String identifier = BlockRegistries.CLEAN_JAVA_IDENTIFIERS.get(statistic.getId()); - if (identifier != null) { - String block = identifier.replace("minecraft:", "block.minecraft."); - content.add(block + ": " + entry.getIntValue()); + Block block = BlockRegistries.JAVA_BLOCKS_TO_RENAME.get(statistic.getId()); + if (block != null) { + String identifier = block.javaIdentifier().replace("minecraft:", "block.minecraft."); + content.add(identifier + ": " + entry.getIntValue()); } } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0500a31be..0f0845137 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -65,6 +65,7 @@ fastutil-int-byte-maps = { group = "com.nukkitx.fastutil", name = "fastutil-int- fastutil-int-boolean-maps = { group = "com.nukkitx.fastutil", name = "fastutil-int-boolean-maps", version.ref = "fastutil" } fastutil-object-int-maps = { group = "com.nukkitx.fastutil", name = "fastutil-object-int-maps", version.ref = "fastutil" } fastutil-object-object-maps = { group = "com.nukkitx.fastutil", name = "fastutil-object-object-maps", version.ref = "fastutil" } +fastutil-reference-object-maps = { group = "com.nukkitx.fastutil", name = "fastutil-reference-object-maps", version.ref = "fastutil" } adventure-text-serializer-gson = { group = "net.kyori", name = "adventure-text-serializer-gson", version.ref = "adventure" } # Remove when we remove our Adventure bump adventure-text-serializer-legacy = { group = "net.kyori", name = "adventure-text-serializer-legacy", version.ref = "adventure" } @@ -142,7 +143,7 @@ blossom = { id = "net.kyori.blossom", version.ref = "blossom" } [bundles] jackson = [ "jackson-annotations", "jackson-core", "jackson-dataformat-yaml" ] -fastutil = [ "fastutil-int-int-maps", "fastutil-int-long-maps", "fastutil-int-byte-maps", "fastutil-int-boolean-maps", "fastutil-object-int-maps", "fastutil-object-object-maps" ] +fastutil = [ "fastutil-int-int-maps", "fastutil-int-long-maps", "fastutil-int-byte-maps", "fastutil-int-boolean-maps", "fastutil-object-int-maps", "fastutil-object-object-maps", "fastutil-reference-object-maps" ] adventure = [ "adventure-text-serializer-gson", "adventure-text-serializer-legacy", "adventure-text-serializer-plain" ] log4j = [ "log4j-api", "log4j-core", "log4j-slf4j2-impl" ] jline = [ "jline-terminal", "jline-terminal-jna", "jline-reader" ] From a46332ace19aadf2d09f258f7c9ef456cf0af965 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Fri, 17 May 2024 14:50:21 -0400 Subject: [PATCH 167/272] Move block breaking to new system --- .../geysermc/geyser/level/block/Blocks.java | 1834 ++++++++--------- .../geyser/level/block/type/Block.java | 36 + .../populator/BlockRegistryPopulator.java | 10 + .../geyser/session/cache/TagCache.java | 14 +- .../player/BedrockActionTranslator.java | 5 +- .../level/JavaBlockDestructionTranslator.java | 7 +- .../org/geysermc/geyser/util/BlockUtils.java | 44 +- 7 files changed, 1005 insertions(+), 945 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java b/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java index 426895269..1f9c9c162 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java @@ -38,30 +38,30 @@ import static org.geysermc.geyser.level.block.type.Block.builder; @SuppressWarnings("unused") public final class Blocks { public static final Block AIR = register(new Block("air", builder())); - public static final Block STONE = register(new Block("stone", builder())); - public static final Block GRANITE = register(new Block("granite", builder())); - public static final Block POLISHED_GRANITE = register(new Block("polished_granite", builder())); - public static final Block DIORITE = register(new Block("diorite", builder())); - public static final Block POLISHED_DIORITE = register(new Block("polished_diorite", builder())); - public static final Block ANDESITE = register(new Block("andesite", builder())); - public static final Block POLISHED_ANDESITE = register(new Block("polished_andesite", builder())); - public static final Block GRASS_BLOCK = register(new Block("grass_block", builder() + public static final Block STONE = register(new Block("stone", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block GRANITE = register(new Block("granite", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block POLISHED_GRANITE = register(new Block("polished_granite", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block DIORITE = register(new Block("diorite", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block POLISHED_DIORITE = register(new Block("polished_diorite", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block ANDESITE = register(new Block("andesite", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block POLISHED_ANDESITE = register(new Block("polished_andesite", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block GRASS_BLOCK = register(new Block("grass_block", builder().destroyTime(0.6f) .booleanState(SNOWY))); - public static final Block DIRT = register(new Block("dirt", builder())); - public static final Block COARSE_DIRT = register(new Block("coarse_dirt", builder())); - public static final Block PODZOL = register(new Block("podzol", builder() + public static final Block DIRT = register(new Block("dirt", builder().destroyTime(0.5f))); + public static final Block COARSE_DIRT = register(new Block("coarse_dirt", builder().destroyTime(0.5f))); + public static final Block PODZOL = register(new Block("podzol", builder().destroyTime(0.5f) .booleanState(SNOWY))); - public static final Block COBBLESTONE = register(new Block("cobblestone", builder())); - public static final Block OAK_PLANKS = register(new Block("oak_planks", builder())); - public static final Block SPRUCE_PLANKS = register(new Block("spruce_planks", builder())); - public static final Block BIRCH_PLANKS = register(new Block("birch_planks", builder())); - public static final Block JUNGLE_PLANKS = register(new Block("jungle_planks", builder())); - public static final Block ACACIA_PLANKS = register(new Block("acacia_planks", builder())); - public static final Block CHERRY_PLANKS = register(new Block("cherry_planks", builder())); - public static final Block DARK_OAK_PLANKS = register(new Block("dark_oak_planks", builder())); - public static final Block MANGROVE_PLANKS = register(new Block("mangrove_planks", builder())); - public static final Block BAMBOO_PLANKS = register(new Block("bamboo_planks", builder())); - public static final Block BAMBOO_MOSAIC = register(new Block("bamboo_mosaic", builder())); + public static final Block COBBLESTONE = register(new Block("cobblestone", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); + public static final Block OAK_PLANKS = register(new Block("oak_planks", builder().destroyTime(2.0f))); + public static final Block SPRUCE_PLANKS = register(new Block("spruce_planks", builder().destroyTime(2.0f))); + public static final Block BIRCH_PLANKS = register(new Block("birch_planks", builder().destroyTime(2.0f))); + public static final Block JUNGLE_PLANKS = register(new Block("jungle_planks", builder().destroyTime(2.0f))); + public static final Block ACACIA_PLANKS = register(new Block("acacia_planks", builder().destroyTime(2.0f))); + public static final Block CHERRY_PLANKS = register(new Block("cherry_planks", builder().destroyTime(2.0f))); + public static final Block DARK_OAK_PLANKS = register(new Block("dark_oak_planks", builder().destroyTime(2.0f))); + public static final Block MANGROVE_PLANKS = register(new Block("mangrove_planks", builder().destroyTime(2.0f))); + public static final Block BAMBOO_PLANKS = register(new Block("bamboo_planks", builder().destroyTime(2.0f))); + public static final Block BAMBOO_MOSAIC = register(new Block("bamboo_mosaic", builder().destroyTime(2.0f))); public static final Block OAK_SAPLING = register(new Block("oak_sapling", builder() .intState(STAGE, 0, 1))); public static final Block SPRUCE_SAPLING = register(new Block("spruce_sapling", builder() @@ -81,259 +81,259 @@ public final class Blocks { .booleanState(HANGING) .intState(STAGE, 0, 1) .booleanState(WATERLOGGED))); - public static final Block BEDROCK = register(new Block("bedrock", builder())); - public static final Block WATER = register(new Block("water", builder() + public static final Block BEDROCK = register(new Block("bedrock", builder().destroyTime(-1.0f))); + public static final Block WATER = register(new Block("water", builder().destroyTime(100.0f) .intState(LEVEL, 0, 15))); - public static final Block LAVA = register(new Block("lava", builder() + public static final Block LAVA = register(new Block("lava", builder().destroyTime(100.0f) .intState(LEVEL, 0, 15))); - public static final Block SAND = register(new Block("sand", builder())); - public static final Block SUSPICIOUS_SAND = register(new Block("suspicious_sand", builder() + public static final Block SAND = register(new Block("sand", builder().destroyTime(0.5f))); + public static final Block SUSPICIOUS_SAND = register(new Block("suspicious_sand", builder().setBlockEntity().destroyTime(0.25f) .intState(DUSTED, 0, 3))); - public static final Block RED_SAND = register(new Block("red_sand", builder())); - public static final Block GRAVEL = register(new Block("gravel", builder())); - public static final Block SUSPICIOUS_GRAVEL = register(new Block("suspicious_gravel", builder() + public static final Block RED_SAND = register(new Block("red_sand", builder().destroyTime(0.5f))); + public static final Block GRAVEL = register(new Block("gravel", builder().destroyTime(0.6f))); + public static final Block SUSPICIOUS_GRAVEL = register(new Block("suspicious_gravel", builder().setBlockEntity().destroyTime(0.25f) .intState(DUSTED, 0, 3))); - public static final Block GOLD_ORE = register(new Block("gold_ore", builder())); - public static final Block DEEPSLATE_GOLD_ORE = register(new Block("deepslate_gold_ore", builder())); - public static final Block IRON_ORE = register(new Block("iron_ore", builder())); - public static final Block DEEPSLATE_IRON_ORE = register(new Block("deepslate_iron_ore", builder())); - public static final Block COAL_ORE = register(new Block("coal_ore", builder())); - public static final Block DEEPSLATE_COAL_ORE = register(new Block("deepslate_coal_ore", builder())); - public static final Block NETHER_GOLD_ORE = register(new Block("nether_gold_ore", builder())); - public static final Block OAK_LOG = register(new Block("oak_log", builder() + public static final Block GOLD_ORE = register(new Block("gold_ore", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block DEEPSLATE_GOLD_ORE = register(new Block("deepslate_gold_ore", builder().requiresCorrectToolForDrops().destroyTime(4.5f))); + public static final Block IRON_ORE = register(new Block("iron_ore", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block DEEPSLATE_IRON_ORE = register(new Block("deepslate_iron_ore", builder().requiresCorrectToolForDrops().destroyTime(4.5f))); + public static final Block COAL_ORE = register(new Block("coal_ore", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block DEEPSLATE_COAL_ORE = register(new Block("deepslate_coal_ore", builder().requiresCorrectToolForDrops().destroyTime(4.5f))); + public static final Block NETHER_GOLD_ORE = register(new Block("nether_gold_ore", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block OAK_LOG = register(new Block("oak_log", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block SPRUCE_LOG = register(new Block("spruce_log", builder() + public static final Block SPRUCE_LOG = register(new Block("spruce_log", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block BIRCH_LOG = register(new Block("birch_log", builder() + public static final Block BIRCH_LOG = register(new Block("birch_log", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block JUNGLE_LOG = register(new Block("jungle_log", builder() + public static final Block JUNGLE_LOG = register(new Block("jungle_log", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block ACACIA_LOG = register(new Block("acacia_log", builder() + public static final Block ACACIA_LOG = register(new Block("acacia_log", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block CHERRY_LOG = register(new Block("cherry_log", builder() + public static final Block CHERRY_LOG = register(new Block("cherry_log", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block DARK_OAK_LOG = register(new Block("dark_oak_log", builder() + public static final Block DARK_OAK_LOG = register(new Block("dark_oak_log", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block MANGROVE_LOG = register(new Block("mangrove_log", builder() + public static final Block MANGROVE_LOG = register(new Block("mangrove_log", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block MANGROVE_ROOTS = register(new Block("mangrove_roots", builder() + public static final Block MANGROVE_ROOTS = register(new Block("mangrove_roots", builder().destroyTime(0.7f) .booleanState(WATERLOGGED))); - public static final Block MUDDY_MANGROVE_ROOTS = register(new Block("muddy_mangrove_roots", builder() + public static final Block MUDDY_MANGROVE_ROOTS = register(new Block("muddy_mangrove_roots", builder().destroyTime(0.7f) .enumState(AXIS, Axis.VALUES))); - public static final Block BAMBOO_BLOCK = register(new Block("bamboo_block", builder() + public static final Block BAMBOO_BLOCK = register(new Block("bamboo_block", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block STRIPPED_SPRUCE_LOG = register(new Block("stripped_spruce_log", builder() + public static final Block STRIPPED_SPRUCE_LOG = register(new Block("stripped_spruce_log", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block STRIPPED_BIRCH_LOG = register(new Block("stripped_birch_log", builder() + public static final Block STRIPPED_BIRCH_LOG = register(new Block("stripped_birch_log", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block STRIPPED_JUNGLE_LOG = register(new Block("stripped_jungle_log", builder() + public static final Block STRIPPED_JUNGLE_LOG = register(new Block("stripped_jungle_log", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block STRIPPED_ACACIA_LOG = register(new Block("stripped_acacia_log", builder() + public static final Block STRIPPED_ACACIA_LOG = register(new Block("stripped_acacia_log", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block STRIPPED_CHERRY_LOG = register(new Block("stripped_cherry_log", builder() + public static final Block STRIPPED_CHERRY_LOG = register(new Block("stripped_cherry_log", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block STRIPPED_DARK_OAK_LOG = register(new Block("stripped_dark_oak_log", builder() + public static final Block STRIPPED_DARK_OAK_LOG = register(new Block("stripped_dark_oak_log", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block STRIPPED_OAK_LOG = register(new Block("stripped_oak_log", builder() + public static final Block STRIPPED_OAK_LOG = register(new Block("stripped_oak_log", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block STRIPPED_MANGROVE_LOG = register(new Block("stripped_mangrove_log", builder() + public static final Block STRIPPED_MANGROVE_LOG = register(new Block("stripped_mangrove_log", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block STRIPPED_BAMBOO_BLOCK = register(new Block("stripped_bamboo_block", builder() + public static final Block STRIPPED_BAMBOO_BLOCK = register(new Block("stripped_bamboo_block", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block OAK_WOOD = register(new Block("oak_wood", builder() + public static final Block OAK_WOOD = register(new Block("oak_wood", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block SPRUCE_WOOD = register(new Block("spruce_wood", builder() + public static final Block SPRUCE_WOOD = register(new Block("spruce_wood", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block BIRCH_WOOD = register(new Block("birch_wood", builder() + public static final Block BIRCH_WOOD = register(new Block("birch_wood", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block JUNGLE_WOOD = register(new Block("jungle_wood", builder() + public static final Block JUNGLE_WOOD = register(new Block("jungle_wood", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block ACACIA_WOOD = register(new Block("acacia_wood", builder() + public static final Block ACACIA_WOOD = register(new Block("acacia_wood", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block CHERRY_WOOD = register(new Block("cherry_wood", builder() + public static final Block CHERRY_WOOD = register(new Block("cherry_wood", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block DARK_OAK_WOOD = register(new Block("dark_oak_wood", builder() + public static final Block DARK_OAK_WOOD = register(new Block("dark_oak_wood", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block MANGROVE_WOOD = register(new Block("mangrove_wood", builder() + public static final Block MANGROVE_WOOD = register(new Block("mangrove_wood", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block STRIPPED_OAK_WOOD = register(new Block("stripped_oak_wood", builder() + public static final Block STRIPPED_OAK_WOOD = register(new Block("stripped_oak_wood", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block STRIPPED_SPRUCE_WOOD = register(new Block("stripped_spruce_wood", builder() + public static final Block STRIPPED_SPRUCE_WOOD = register(new Block("stripped_spruce_wood", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block STRIPPED_BIRCH_WOOD = register(new Block("stripped_birch_wood", builder() + public static final Block STRIPPED_BIRCH_WOOD = register(new Block("stripped_birch_wood", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block STRIPPED_JUNGLE_WOOD = register(new Block("stripped_jungle_wood", builder() + public static final Block STRIPPED_JUNGLE_WOOD = register(new Block("stripped_jungle_wood", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block STRIPPED_ACACIA_WOOD = register(new Block("stripped_acacia_wood", builder() + public static final Block STRIPPED_ACACIA_WOOD = register(new Block("stripped_acacia_wood", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block STRIPPED_CHERRY_WOOD = register(new Block("stripped_cherry_wood", builder() + public static final Block STRIPPED_CHERRY_WOOD = register(new Block("stripped_cherry_wood", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block STRIPPED_DARK_OAK_WOOD = register(new Block("stripped_dark_oak_wood", builder() + public static final Block STRIPPED_DARK_OAK_WOOD = register(new Block("stripped_dark_oak_wood", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block STRIPPED_MANGROVE_WOOD = register(new Block("stripped_mangrove_wood", builder() + public static final Block STRIPPED_MANGROVE_WOOD = register(new Block("stripped_mangrove_wood", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block OAK_LEAVES = register(new Block("oak_leaves", builder() + public static final Block OAK_LEAVES = register(new Block("oak_leaves", builder().destroyTime(0.2f) .intState(DISTANCE, 1, 7) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); - public static final Block SPRUCE_LEAVES = register(new Block("spruce_leaves", builder() + public static final Block SPRUCE_LEAVES = register(new Block("spruce_leaves", builder().destroyTime(0.2f) .intState(DISTANCE, 1, 7) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); - public static final Block BIRCH_LEAVES = register(new Block("birch_leaves", builder() + public static final Block BIRCH_LEAVES = register(new Block("birch_leaves", builder().destroyTime(0.2f) .intState(DISTANCE, 1, 7) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); - public static final Block JUNGLE_LEAVES = register(new Block("jungle_leaves", builder() + public static final Block JUNGLE_LEAVES = register(new Block("jungle_leaves", builder().destroyTime(0.2f) .intState(DISTANCE, 1, 7) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); - public static final Block ACACIA_LEAVES = register(new Block("acacia_leaves", builder() + public static final Block ACACIA_LEAVES = register(new Block("acacia_leaves", builder().destroyTime(0.2f) .intState(DISTANCE, 1, 7) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); - public static final Block CHERRY_LEAVES = register(new Block("cherry_leaves", builder() + public static final Block CHERRY_LEAVES = register(new Block("cherry_leaves", builder().destroyTime(0.2f) .intState(DISTANCE, 1, 7) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); - public static final Block DARK_OAK_LEAVES = register(new Block("dark_oak_leaves", builder() + public static final Block DARK_OAK_LEAVES = register(new Block("dark_oak_leaves", builder().destroyTime(0.2f) .intState(DISTANCE, 1, 7) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); - public static final Block MANGROVE_LEAVES = register(new Block("mangrove_leaves", builder() + public static final Block MANGROVE_LEAVES = register(new Block("mangrove_leaves", builder().destroyTime(0.2f) .intState(DISTANCE, 1, 7) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); - public static final Block AZALEA_LEAVES = register(new Block("azalea_leaves", builder() + public static final Block AZALEA_LEAVES = register(new Block("azalea_leaves", builder().destroyTime(0.2f) .intState(DISTANCE, 1, 7) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); - public static final Block FLOWERING_AZALEA_LEAVES = register(new Block("flowering_azalea_leaves", builder() + public static final Block FLOWERING_AZALEA_LEAVES = register(new Block("flowering_azalea_leaves", builder().destroyTime(0.2f) .intState(DISTANCE, 1, 7) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); - public static final Block SPONGE = register(new Block("sponge", builder())); - public static final Block WET_SPONGE = register(new Block("wet_sponge", builder())); - public static final Block GLASS = register(new Block("glass", builder())); - public static final Block LAPIS_ORE = register(new Block("lapis_ore", builder())); - public static final Block DEEPSLATE_LAPIS_ORE = register(new Block("deepslate_lapis_ore", builder())); - public static final Block LAPIS_BLOCK = register(new Block("lapis_block", builder())); - public static final Block DISPENSER = register(new Block("dispenser", builder() + public static final Block SPONGE = register(new Block("sponge", builder().destroyTime(0.6f))); + public static final Block WET_SPONGE = register(new Block("wet_sponge", builder().destroyTime(0.6f))); + public static final Block GLASS = register(new Block("glass", builder().destroyTime(0.3f))); + public static final Block LAPIS_ORE = register(new Block("lapis_ore", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block DEEPSLATE_LAPIS_ORE = register(new Block("deepslate_lapis_ore", builder().requiresCorrectToolForDrops().destroyTime(4.5f))); + public static final Block LAPIS_BLOCK = register(new Block("lapis_block", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block DISPENSER = register(new Block("dispenser", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) .booleanState(TRIGGERED))); - public static final Block SANDSTONE = register(new Block("sandstone", builder())); - public static final Block CHISELED_SANDSTONE = register(new Block("chiseled_sandstone", builder())); - public static final Block CUT_SANDSTONE = register(new Block("cut_sandstone", builder())); - public static final Block NOTE_BLOCK = register(new Block("note_block", builder() + public static final Block SANDSTONE = register(new Block("sandstone", builder().requiresCorrectToolForDrops().destroyTime(0.8f))); + public static final Block CHISELED_SANDSTONE = register(new Block("chiseled_sandstone", builder().requiresCorrectToolForDrops().destroyTime(0.8f))); + public static final Block CUT_SANDSTONE = register(new Block("cut_sandstone", builder().requiresCorrectToolForDrops().destroyTime(0.8f))); + public static final Block NOTE_BLOCK = register(new Block("note_block", builder().destroyTime(0.8f) .enumState(NOTEBLOCK_INSTRUMENT, "harp", "basedrum", "snare", "hat", "bass", "flute", "bell", "guitar", "chime", "xylophone", "iron_xylophone", "cow_bell", "didgeridoo", "bit", "banjo", "pling", "zombie", "skeleton", "creeper", "dragon", "wither_skeleton", "piglin", "custom_head") .intState(NOTE, 0, 24) .booleanState(POWERED))); - public static final Block WHITE_BED = register(new BedBlock("white_bed", 0, builder() + public static final Block WHITE_BED = register(new BedBlock("white_bed", 0, builder().setBlockEntity().destroyTime(0.2f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block ORANGE_BED = register(new BedBlock("orange_bed", 1, builder() + public static final Block ORANGE_BED = register(new BedBlock("orange_bed", 1, builder().setBlockEntity().destroyTime(0.2f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block MAGENTA_BED = register(new BedBlock("magenta_bed", 2, builder() + public static final Block MAGENTA_BED = register(new BedBlock("magenta_bed", 2, builder().setBlockEntity().destroyTime(0.2f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block LIGHT_BLUE_BED = register(new BedBlock("light_blue_bed", 3, builder() + public static final Block LIGHT_BLUE_BED = register(new BedBlock("light_blue_bed", 3, builder().setBlockEntity().destroyTime(0.2f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block YELLOW_BED = register(new BedBlock("yellow_bed", 4, builder() + public static final Block YELLOW_BED = register(new BedBlock("yellow_bed", 4, builder().setBlockEntity().destroyTime(0.2f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block LIME_BED = register(new BedBlock("lime_bed", 5, builder() + public static final Block LIME_BED = register(new BedBlock("lime_bed", 5, builder().setBlockEntity().destroyTime(0.2f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block PINK_BED = register(new BedBlock("pink_bed", 6, builder() + public static final Block PINK_BED = register(new BedBlock("pink_bed", 6, builder().setBlockEntity().destroyTime(0.2f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block GRAY_BED = register(new BedBlock("gray_bed", 7, builder() + public static final Block GRAY_BED = register(new BedBlock("gray_bed", 7, builder().setBlockEntity().destroyTime(0.2f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block LIGHT_GRAY_BED = register(new BedBlock("light_gray_bed", 8, builder() + public static final Block LIGHT_GRAY_BED = register(new BedBlock("light_gray_bed", 8, builder().setBlockEntity().destroyTime(0.2f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block CYAN_BED = register(new BedBlock("cyan_bed", 9, builder() + public static final Block CYAN_BED = register(new BedBlock("cyan_bed", 9, builder().setBlockEntity().destroyTime(0.2f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block PURPLE_BED = register(new BedBlock("purple_bed", 10, builder() + public static final Block PURPLE_BED = register(new BedBlock("purple_bed", 10, builder().setBlockEntity().destroyTime(0.2f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block BLUE_BED = register(new BedBlock("blue_bed", 11, builder() + public static final Block BLUE_BED = register(new BedBlock("blue_bed", 11, builder().setBlockEntity().destroyTime(0.2f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block BROWN_BED = register(new BedBlock("brown_bed", 12, builder() + public static final Block BROWN_BED = register(new BedBlock("brown_bed", 12, builder().setBlockEntity().destroyTime(0.2f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block GREEN_BED = register(new BedBlock("green_bed", 13, builder() + public static final Block GREEN_BED = register(new BedBlock("green_bed", 13, builder().setBlockEntity().destroyTime(0.2f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block RED_BED = register(new BedBlock("red_bed", 14, builder() + public static final Block RED_BED = register(new BedBlock("red_bed", 14, builder().setBlockEntity().destroyTime(0.2f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block BLACK_BED = register(new BedBlock("black_bed", 15, builder() + public static final Block BLACK_BED = register(new BedBlock("black_bed", 15, builder().setBlockEntity().destroyTime(0.2f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block POWERED_RAIL = register(new Block("powered_rail", builder() + public static final Block POWERED_RAIL = register(new Block("powered_rail", builder().destroyTime(0.7f) .booleanState(POWERED) .enumState(RAIL_SHAPE_STRAIGHT, "north_south", "east_west", "ascending_east", "ascending_west", "ascending_north", "ascending_south") .booleanState(WATERLOGGED))); - public static final Block DETECTOR_RAIL = register(new Block("detector_rail", builder() + public static final Block DETECTOR_RAIL = register(new Block("detector_rail", builder().destroyTime(0.7f) .booleanState(POWERED) .enumState(RAIL_SHAPE_STRAIGHT, "north_south", "east_west", "ascending_east", "ascending_west", "ascending_north", "ascending_south") .booleanState(WATERLOGGED))); - public static final Block STICKY_PISTON = register(new Block("sticky_piston", builder() + public static final Block STICKY_PISTON = register(new Block("sticky_piston", builder().destroyTime(1.5f) .booleanState(EXTENDED) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block COBWEB = register(new Block("cobweb", builder())); + public static final Block COBWEB = register(new Block("cobweb", builder().requiresCorrectToolForDrops().destroyTime(4.0f))); public static final Block SHORT_GRASS = register(new Block("short_grass", builder())); public static final Block FERN = register(new Block("fern", builder())); public static final Block DEAD_BUSH = register(new Block("dead_bush", builder())); public static final Block SEAGRASS = register(new Block("seagrass", builder())); public static final Block TALL_SEAGRASS = register(new Block("tall_seagrass", builder() .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); - public static final Block PISTON = register(new Block("piston", builder() + public static final Block PISTON = register(new Block("piston", builder().destroyTime(1.5f) .booleanState(EXTENDED) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block PISTON_HEAD = register(new Block("piston_head", builder() + public static final Block PISTON_HEAD = register(new Block("piston_head", builder().destroyTime(1.5f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) .booleanState(SHORT) .enumState(PISTON_TYPE, "normal", "sticky"))); - public static final Block WHITE_WOOL = register(new Block("white_wool", builder())); - public static final Block ORANGE_WOOL = register(new Block("orange_wool", builder())); - public static final Block MAGENTA_WOOL = register(new Block("magenta_wool", builder())); - public static final Block LIGHT_BLUE_WOOL = register(new Block("light_blue_wool", builder())); - public static final Block YELLOW_WOOL = register(new Block("yellow_wool", builder())); - public static final Block LIME_WOOL = register(new Block("lime_wool", builder())); - public static final Block PINK_WOOL = register(new Block("pink_wool", builder())); - public static final Block GRAY_WOOL = register(new Block("gray_wool", builder())); - public static final Block LIGHT_GRAY_WOOL = register(new Block("light_gray_wool", builder())); - public static final Block CYAN_WOOL = register(new Block("cyan_wool", builder())); - public static final Block PURPLE_WOOL = register(new Block("purple_wool", builder())); - public static final Block BLUE_WOOL = register(new Block("blue_wool", builder())); - public static final Block BROWN_WOOL = register(new Block("brown_wool", builder())); - public static final Block GREEN_WOOL = register(new Block("green_wool", builder())); - public static final Block RED_WOOL = register(new Block("red_wool", builder())); - public static final Block BLACK_WOOL = register(new Block("black_wool", builder())); - public static final Block MOVING_PISTON = register(new Block("moving_piston", builder() + public static final Block WHITE_WOOL = register(new Block("white_wool", builder().destroyTime(0.8f))); + public static final Block ORANGE_WOOL = register(new Block("orange_wool", builder().destroyTime(0.8f))); + public static final Block MAGENTA_WOOL = register(new Block("magenta_wool", builder().destroyTime(0.8f))); + public static final Block LIGHT_BLUE_WOOL = register(new Block("light_blue_wool", builder().destroyTime(0.8f))); + public static final Block YELLOW_WOOL = register(new Block("yellow_wool", builder().destroyTime(0.8f))); + public static final Block LIME_WOOL = register(new Block("lime_wool", builder().destroyTime(0.8f))); + public static final Block PINK_WOOL = register(new Block("pink_wool", builder().destroyTime(0.8f))); + public static final Block GRAY_WOOL = register(new Block("gray_wool", builder().destroyTime(0.8f))); + public static final Block LIGHT_GRAY_WOOL = register(new Block("light_gray_wool", builder().destroyTime(0.8f))); + public static final Block CYAN_WOOL = register(new Block("cyan_wool", builder().destroyTime(0.8f))); + public static final Block PURPLE_WOOL = register(new Block("purple_wool", builder().destroyTime(0.8f))); + public static final Block BLUE_WOOL = register(new Block("blue_wool", builder().destroyTime(0.8f))); + public static final Block BROWN_WOOL = register(new Block("brown_wool", builder().destroyTime(0.8f))); + public static final Block GREEN_WOOL = register(new Block("green_wool", builder().destroyTime(0.8f))); + public static final Block RED_WOOL = register(new Block("red_wool", builder().destroyTime(0.8f))); + public static final Block BLACK_WOOL = register(new Block("black_wool", builder().destroyTime(0.8f))); + public static final Block MOVING_PISTON = register(new Block("moving_piston", builder().setBlockEntity().destroyTime(-1.0f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) .enumState(PISTON_TYPE, "normal", "sticky"))); public static final Block DANDELION = register(new Block("dandelion", builder())); @@ -352,13 +352,13 @@ public final class Blocks { public static final Block LILY_OF_THE_VALLEY = register(new Block("lily_of_the_valley", builder())); public static final Block BROWN_MUSHROOM = register(new Block("brown_mushroom", builder())); public static final Block RED_MUSHROOM = register(new Block("red_mushroom", builder())); - public static final Block GOLD_BLOCK = register(new Block("gold_block", builder())); - public static final Block IRON_BLOCK = register(new Block("iron_block", builder())); - public static final Block BRICKS = register(new Block("bricks", builder())); + public static final Block GOLD_BLOCK = register(new Block("gold_block", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block IRON_BLOCK = register(new Block("iron_block", builder().requiresCorrectToolForDrops().destroyTime(5.0f))); + public static final Block BRICKS = register(new Block("bricks", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); public static final Block TNT = register(new Block("tnt", builder() .booleanState(UNSTABLE))); - public static final Block BOOKSHELF = register(new Block("bookshelf", builder())); - public static final Block CHISELED_BOOKSHELF = register(new Block("chiseled_bookshelf", builder() + public static final Block BOOKSHELF = register(new Block("bookshelf", builder().destroyTime(1.5f))); + public static final Block CHISELED_BOOKSHELF = register(new Block("chiseled_bookshelf", builder().setBlockEntity().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(CHISELED_BOOKSHELF_SLOT_0_OCCUPIED) .booleanState(CHISELED_BOOKSHELF_SLOT_1_OCCUPIED) @@ -366,8 +366,8 @@ public final class Blocks { .booleanState(CHISELED_BOOKSHELF_SLOT_3_OCCUPIED) .booleanState(CHISELED_BOOKSHELF_SLOT_4_OCCUPIED) .booleanState(CHISELED_BOOKSHELF_SLOT_5_OCCUPIED))); - public static final Block MOSSY_COBBLESTONE = register(new Block("mossy_cobblestone", builder())); - public static final Block OBSIDIAN = register(new Block("obsidian", builder())); + public static final Block MOSSY_COBBLESTONE = register(new Block("mossy_cobblestone", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); + public static final Block OBSIDIAN = register(new Block("obsidian", builder().requiresCorrectToolForDrops().destroyTime(50.0f))); public static final Block TORCH = register(new Block("torch", builder())); public static final Block WALL_TORCH = register(new Block("wall_torch", builder() .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); @@ -379,13 +379,13 @@ public final class Blocks { .booleanState(UP) .booleanState(WEST))); public static final Block SOUL_FIRE = register(new Block("soul_fire", builder())); - public static final Block SPAWNER = register(new Block("spawner", builder())); - public static final Block OAK_STAIRS = register(new Block("oak_stairs", builder() + public static final Block SPAWNER = register(new Block("spawner", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(5.0f))); + public static final Block OAK_STAIRS = register(new Block("oak_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block CHEST = register(new Block("chest", builder() + public static final Block CHEST = register(new Block("chest", builder().setBlockEntity().destroyTime(2.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(CHEST_TYPE, "single", "left", "right") .booleanState(WATERLOGGED))); @@ -395,369 +395,369 @@ public final class Blocks { .intState(POWER, 0, 15) .enumState(SOUTH_REDSTONE, "up", "side", "none") .enumState(WEST_REDSTONE, "up", "side", "none"))); - public static final Block DIAMOND_ORE = register(new Block("diamond_ore", builder())); - public static final Block DEEPSLATE_DIAMOND_ORE = register(new Block("deepslate_diamond_ore", builder())); - public static final Block DIAMOND_BLOCK = register(new Block("diamond_block", builder())); - public static final Block CRAFTING_TABLE = register(new Block("crafting_table", builder())); + public static final Block DIAMOND_ORE = register(new Block("diamond_ore", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block DEEPSLATE_DIAMOND_ORE = register(new Block("deepslate_diamond_ore", builder().requiresCorrectToolForDrops().destroyTime(4.5f))); + public static final Block DIAMOND_BLOCK = register(new Block("diamond_block", builder().requiresCorrectToolForDrops().destroyTime(5.0f))); + public static final Block CRAFTING_TABLE = register(new Block("crafting_table", builder().destroyTime(2.5f))); public static final Block WHEAT = register(new Block("wheat", builder() .intState(AGE_7, 0, 7))); - public static final Block FARMLAND = register(new Block("farmland", builder() + public static final Block FARMLAND = register(new Block("farmland", builder().destroyTime(0.6f) .intState(MOISTURE, 0, 7))); - public static final Block FURNACE = register(new Block("furnace", builder() + public static final Block FURNACE = register(new Block("furnace", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(LIT))); - public static final Block OAK_SIGN = register(new Block("oak_sign", builder() + public static final Block OAK_SIGN = register(new Block("oak_sign", builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15) .booleanState(WATERLOGGED))); - public static final Block SPRUCE_SIGN = register(new Block("spruce_sign", builder() + public static final Block SPRUCE_SIGN = register(new Block("spruce_sign", builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15) .booleanState(WATERLOGGED))); - public static final Block BIRCH_SIGN = register(new Block("birch_sign", builder() + public static final Block BIRCH_SIGN = register(new Block("birch_sign", builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15) .booleanState(WATERLOGGED))); - public static final Block ACACIA_SIGN = register(new Block("acacia_sign", builder() + public static final Block ACACIA_SIGN = register(new Block("acacia_sign", builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15) .booleanState(WATERLOGGED))); - public static final Block CHERRY_SIGN = register(new Block("cherry_sign", builder() + public static final Block CHERRY_SIGN = register(new Block("cherry_sign", builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15) .booleanState(WATERLOGGED))); - public static final Block JUNGLE_SIGN = register(new Block("jungle_sign", builder() + public static final Block JUNGLE_SIGN = register(new Block("jungle_sign", builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15) .booleanState(WATERLOGGED))); - public static final Block DARK_OAK_SIGN = register(new Block("dark_oak_sign", builder() + public static final Block DARK_OAK_SIGN = register(new Block("dark_oak_sign", builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15) .booleanState(WATERLOGGED))); - public static final Block MANGROVE_SIGN = register(new Block("mangrove_sign", builder() + public static final Block MANGROVE_SIGN = register(new Block("mangrove_sign", builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15) .booleanState(WATERLOGGED))); - public static final Block BAMBOO_SIGN = register(new Block("bamboo_sign", builder() + public static final Block BAMBOO_SIGN = register(new Block("bamboo_sign", builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15) .booleanState(WATERLOGGED))); - public static final Block OAK_DOOR = register(new Block("oak_door", builder() + public static final Block OAK_DOOR = register(new Block("oak_door", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block LADDER = register(new Block("ladder", builder() + public static final Block LADDER = register(new Block("ladder", builder().destroyTime(0.4f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block RAIL = register(new Block("rail", builder() + public static final Block RAIL = register(new Block("rail", builder().destroyTime(0.7f) .enumState(RAIL_SHAPE, "north_south", "east_west", "ascending_east", "ascending_west", "ascending_north", "ascending_south", "south_east", "south_west", "north_west", "north_east") .booleanState(WATERLOGGED))); - public static final Block COBBLESTONE_STAIRS = register(new Block("cobblestone_stairs", builder() + public static final Block COBBLESTONE_STAIRS = register(new Block("cobblestone_stairs", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block OAK_WALL_SIGN = register(new Block("oak_wall_sign", builder() + public static final Block OAK_WALL_SIGN = register(new Block("oak_wall_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block SPRUCE_WALL_SIGN = register(new Block("spruce_wall_sign", builder() + public static final Block SPRUCE_WALL_SIGN = register(new Block("spruce_wall_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block BIRCH_WALL_SIGN = register(new Block("birch_wall_sign", builder() + public static final Block BIRCH_WALL_SIGN = register(new Block("birch_wall_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block ACACIA_WALL_SIGN = register(new Block("acacia_wall_sign", builder() + public static final Block ACACIA_WALL_SIGN = register(new Block("acacia_wall_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block CHERRY_WALL_SIGN = register(new Block("cherry_wall_sign", builder() + public static final Block CHERRY_WALL_SIGN = register(new Block("cherry_wall_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block JUNGLE_WALL_SIGN = register(new Block("jungle_wall_sign", builder() + public static final Block JUNGLE_WALL_SIGN = register(new Block("jungle_wall_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block DARK_OAK_WALL_SIGN = register(new Block("dark_oak_wall_sign", builder() + public static final Block DARK_OAK_WALL_SIGN = register(new Block("dark_oak_wall_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block MANGROVE_WALL_SIGN = register(new Block("mangrove_wall_sign", builder() + public static final Block MANGROVE_WALL_SIGN = register(new Block("mangrove_wall_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block BAMBOO_WALL_SIGN = register(new Block("bamboo_wall_sign", builder() + public static final Block BAMBOO_WALL_SIGN = register(new Block("bamboo_wall_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block OAK_HANGING_SIGN = register(new Block("oak_hanging_sign", builder() + public static final Block OAK_HANGING_SIGN = register(new Block("oak_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) .intState(ROTATION_16, 0, 15) .booleanState(WATERLOGGED))); - public static final Block SPRUCE_HANGING_SIGN = register(new Block("spruce_hanging_sign", builder() + public static final Block SPRUCE_HANGING_SIGN = register(new Block("spruce_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) .intState(ROTATION_16, 0, 15) .booleanState(WATERLOGGED))); - public static final Block BIRCH_HANGING_SIGN = register(new Block("birch_hanging_sign", builder() + public static final Block BIRCH_HANGING_SIGN = register(new Block("birch_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) .intState(ROTATION_16, 0, 15) .booleanState(WATERLOGGED))); - public static final Block ACACIA_HANGING_SIGN = register(new Block("acacia_hanging_sign", builder() + public static final Block ACACIA_HANGING_SIGN = register(new Block("acacia_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) .intState(ROTATION_16, 0, 15) .booleanState(WATERLOGGED))); - public static final Block CHERRY_HANGING_SIGN = register(new Block("cherry_hanging_sign", builder() + public static final Block CHERRY_HANGING_SIGN = register(new Block("cherry_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) .intState(ROTATION_16, 0, 15) .booleanState(WATERLOGGED))); - public static final Block JUNGLE_HANGING_SIGN = register(new Block("jungle_hanging_sign", builder() + public static final Block JUNGLE_HANGING_SIGN = register(new Block("jungle_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) .intState(ROTATION_16, 0, 15) .booleanState(WATERLOGGED))); - public static final Block DARK_OAK_HANGING_SIGN = register(new Block("dark_oak_hanging_sign", builder() + public static final Block DARK_OAK_HANGING_SIGN = register(new Block("dark_oak_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) .intState(ROTATION_16, 0, 15) .booleanState(WATERLOGGED))); - public static final Block CRIMSON_HANGING_SIGN = register(new Block("crimson_hanging_sign", builder() + public static final Block CRIMSON_HANGING_SIGN = register(new Block("crimson_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) .intState(ROTATION_16, 0, 15) .booleanState(WATERLOGGED))); - public static final Block WARPED_HANGING_SIGN = register(new Block("warped_hanging_sign", builder() + public static final Block WARPED_HANGING_SIGN = register(new Block("warped_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) .intState(ROTATION_16, 0, 15) .booleanState(WATERLOGGED))); - public static final Block MANGROVE_HANGING_SIGN = register(new Block("mangrove_hanging_sign", builder() + public static final Block MANGROVE_HANGING_SIGN = register(new Block("mangrove_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) .intState(ROTATION_16, 0, 15) .booleanState(WATERLOGGED))); - public static final Block BAMBOO_HANGING_SIGN = register(new Block("bamboo_hanging_sign", builder() + public static final Block BAMBOO_HANGING_SIGN = register(new Block("bamboo_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) .intState(ROTATION_16, 0, 15) .booleanState(WATERLOGGED))); - public static final Block OAK_WALL_HANGING_SIGN = register(new Block("oak_wall_hanging_sign", builder() + public static final Block OAK_WALL_HANGING_SIGN = register(new Block("oak_wall_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block SPRUCE_WALL_HANGING_SIGN = register(new Block("spruce_wall_hanging_sign", builder() + public static final Block SPRUCE_WALL_HANGING_SIGN = register(new Block("spruce_wall_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block BIRCH_WALL_HANGING_SIGN = register(new Block("birch_wall_hanging_sign", builder() + public static final Block BIRCH_WALL_HANGING_SIGN = register(new Block("birch_wall_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block ACACIA_WALL_HANGING_SIGN = register(new Block("acacia_wall_hanging_sign", builder() + public static final Block ACACIA_WALL_HANGING_SIGN = register(new Block("acacia_wall_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block CHERRY_WALL_HANGING_SIGN = register(new Block("cherry_wall_hanging_sign", builder() + public static final Block CHERRY_WALL_HANGING_SIGN = register(new Block("cherry_wall_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block JUNGLE_WALL_HANGING_SIGN = register(new Block("jungle_wall_hanging_sign", builder() + public static final Block JUNGLE_WALL_HANGING_SIGN = register(new Block("jungle_wall_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block DARK_OAK_WALL_HANGING_SIGN = register(new Block("dark_oak_wall_hanging_sign", builder() + public static final Block DARK_OAK_WALL_HANGING_SIGN = register(new Block("dark_oak_wall_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block MANGROVE_WALL_HANGING_SIGN = register(new Block("mangrove_wall_hanging_sign", builder() + public static final Block MANGROVE_WALL_HANGING_SIGN = register(new Block("mangrove_wall_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block CRIMSON_WALL_HANGING_SIGN = register(new Block("crimson_wall_hanging_sign", builder() + public static final Block CRIMSON_WALL_HANGING_SIGN = register(new Block("crimson_wall_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block WARPED_WALL_HANGING_SIGN = register(new Block("warped_wall_hanging_sign", builder() + public static final Block WARPED_WALL_HANGING_SIGN = register(new Block("warped_wall_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block BAMBOO_WALL_HANGING_SIGN = register(new Block("bamboo_wall_hanging_sign", builder() + public static final Block BAMBOO_WALL_HANGING_SIGN = register(new Block("bamboo_wall_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block LEVER = register(new Block("lever", builder() + public static final Block LEVER = register(new Block("lever", builder().destroyTime(0.5f) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block STONE_PRESSURE_PLATE = register(new Block("stone_pressure_plate", builder() + public static final Block STONE_PRESSURE_PLATE = register(new Block("stone_pressure_plate", builder().requiresCorrectToolForDrops().destroyTime(0.5f) .booleanState(POWERED))); - public static final Block IRON_DOOR = register(new Block("iron_door", builder() + public static final Block IRON_DOOR = register(new Block("iron_door", builder().requiresCorrectToolForDrops().destroyTime(5.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block OAK_PRESSURE_PLATE = register(new Block("oak_pressure_plate", builder() + public static final Block OAK_PRESSURE_PLATE = register(new Block("oak_pressure_plate", builder().destroyTime(0.5f) .booleanState(POWERED))); - public static final Block SPRUCE_PRESSURE_PLATE = register(new Block("spruce_pressure_plate", builder() + public static final Block SPRUCE_PRESSURE_PLATE = register(new Block("spruce_pressure_plate", builder().destroyTime(0.5f) .booleanState(POWERED))); - public static final Block BIRCH_PRESSURE_PLATE = register(new Block("birch_pressure_plate", builder() + public static final Block BIRCH_PRESSURE_PLATE = register(new Block("birch_pressure_plate", builder().destroyTime(0.5f) .booleanState(POWERED))); - public static final Block JUNGLE_PRESSURE_PLATE = register(new Block("jungle_pressure_plate", builder() + public static final Block JUNGLE_PRESSURE_PLATE = register(new Block("jungle_pressure_plate", builder().destroyTime(0.5f) .booleanState(POWERED))); - public static final Block ACACIA_PRESSURE_PLATE = register(new Block("acacia_pressure_plate", builder() + public static final Block ACACIA_PRESSURE_PLATE = register(new Block("acacia_pressure_plate", builder().destroyTime(0.5f) .booleanState(POWERED))); - public static final Block CHERRY_PRESSURE_PLATE = register(new Block("cherry_pressure_plate", builder() + public static final Block CHERRY_PRESSURE_PLATE = register(new Block("cherry_pressure_plate", builder().destroyTime(0.5f) .booleanState(POWERED))); - public static final Block DARK_OAK_PRESSURE_PLATE = register(new Block("dark_oak_pressure_plate", builder() + public static final Block DARK_OAK_PRESSURE_PLATE = register(new Block("dark_oak_pressure_plate", builder().destroyTime(0.5f) .booleanState(POWERED))); - public static final Block MANGROVE_PRESSURE_PLATE = register(new Block("mangrove_pressure_plate", builder() + public static final Block MANGROVE_PRESSURE_PLATE = register(new Block("mangrove_pressure_plate", builder().destroyTime(0.5f) .booleanState(POWERED))); - public static final Block BAMBOO_PRESSURE_PLATE = register(new Block("bamboo_pressure_plate", builder() + public static final Block BAMBOO_PRESSURE_PLATE = register(new Block("bamboo_pressure_plate", builder().destroyTime(0.5f) .booleanState(POWERED))); - public static final Block REDSTONE_ORE = register(new Block("redstone_ore", builder() + public static final Block REDSTONE_ORE = register(new Block("redstone_ore", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .booleanState(LIT))); - public static final Block DEEPSLATE_REDSTONE_ORE = register(new Block("deepslate_redstone_ore", builder() + public static final Block DEEPSLATE_REDSTONE_ORE = register(new Block("deepslate_redstone_ore", builder().requiresCorrectToolForDrops().destroyTime(4.5f) .booleanState(LIT))); public static final Block REDSTONE_TORCH = register(new Block("redstone_torch", builder() .booleanState(LIT))); public static final Block REDSTONE_WALL_TORCH = register(new Block("redstone_wall_torch", builder() .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(LIT))); - public static final Block STONE_BUTTON = register(new Block("stone_button", builder() + public static final Block STONE_BUTTON = register(new Block("stone_button", builder().destroyTime(0.5f) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block SNOW = register(new Block("snow", builder() + public static final Block SNOW = register(new Block("snow", builder().requiresCorrectToolForDrops().destroyTime(0.1f) .intState(LAYERS, 1, 8))); - public static final Block ICE = register(new Block("ice", builder())); - public static final Block SNOW_BLOCK = register(new Block("snow_block", builder())); - public static final Block CACTUS = register(new Block("cactus", builder() + public static final Block ICE = register(new Block("ice", builder().destroyTime(0.5f))); + public static final Block SNOW_BLOCK = register(new Block("snow_block", builder().requiresCorrectToolForDrops().destroyTime(0.2f))); + public static final Block CACTUS = register(new Block("cactus", builder().destroyTime(0.4f) .intState(AGE_15, 0, 15))); - public static final Block CLAY = register(new Block("clay", builder())); + public static final Block CLAY = register(new Block("clay", builder().destroyTime(0.6f))); public static final Block SUGAR_CANE = register(new Block("sugar_cane", builder() .intState(AGE_15, 0, 15))); - public static final Block JUKEBOX = register(new Block("jukebox", builder() + public static final Block JUKEBOX = register(new Block("jukebox", builder().setBlockEntity().destroyTime(2.0f) .booleanState(HAS_RECORD))); - public static final Block OAK_FENCE = register(new Block("oak_fence", builder() + public static final Block OAK_FENCE = register(new Block("oak_fence", builder().destroyTime(2.0f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block NETHERRACK = register(new Block("netherrack", builder())); - public static final Block SOUL_SAND = register(new Block("soul_sand", builder())); - public static final Block SOUL_SOIL = register(new Block("soul_soil", builder())); - public static final Block BASALT = register(new Block("basalt", builder() + public static final Block NETHERRACK = register(new Block("netherrack", builder().requiresCorrectToolForDrops().destroyTime(0.4f))); + public static final Block SOUL_SAND = register(new Block("soul_sand", builder().destroyTime(0.5f))); + public static final Block SOUL_SOIL = register(new Block("soul_soil", builder().destroyTime(0.5f))); + public static final Block BASALT = register(new Block("basalt", builder().requiresCorrectToolForDrops().destroyTime(1.25f) .enumState(AXIS, Axis.VALUES))); - public static final Block POLISHED_BASALT = register(new Block("polished_basalt", builder() + public static final Block POLISHED_BASALT = register(new Block("polished_basalt", builder().requiresCorrectToolForDrops().destroyTime(1.25f) .enumState(AXIS, Axis.VALUES))); public static final Block SOUL_TORCH = register(new Block("soul_torch", builder())); public static final Block SOUL_WALL_TORCH = register(new Block("soul_wall_torch", builder() .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block GLOWSTONE = register(new Block("glowstone", builder())); - public static final Block NETHER_PORTAL = register(new Block("nether_portal", builder() + public static final Block GLOWSTONE = register(new Block("glowstone", builder().destroyTime(0.3f))); + public static final Block NETHER_PORTAL = register(new Block("nether_portal", builder().destroyTime(-1.0f) .enumState(HORIZONTAL_AXIS, Axis.X, Axis.Z))); - public static final Block CARVED_PUMPKIN = register(new Block("carved_pumpkin", builder() + public static final Block CARVED_PUMPKIN = register(new Block("carved_pumpkin", builder().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block JACK_O_LANTERN = register(new Block("jack_o_lantern", builder() + public static final Block JACK_O_LANTERN = register(new Block("jack_o_lantern", builder().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block CAKE = register(new Block("cake", builder() + public static final Block CAKE = register(new Block("cake", builder().destroyTime(0.5f) .intState(BITES, 0, 6))); public static final Block REPEATER = register(new Block("repeater", builder() .intState(DELAY, 1, 4) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(LOCKED) .booleanState(POWERED))); - public static final Block WHITE_STAINED_GLASS = register(new Block("white_stained_glass", builder())); - public static final Block ORANGE_STAINED_GLASS = register(new Block("orange_stained_glass", builder())); - public static final Block MAGENTA_STAINED_GLASS = register(new Block("magenta_stained_glass", builder())); - public static final Block LIGHT_BLUE_STAINED_GLASS = register(new Block("light_blue_stained_glass", builder())); - public static final Block YELLOW_STAINED_GLASS = register(new Block("yellow_stained_glass", builder())); - public static final Block LIME_STAINED_GLASS = register(new Block("lime_stained_glass", builder())); - public static final Block PINK_STAINED_GLASS = register(new Block("pink_stained_glass", builder())); - public static final Block GRAY_STAINED_GLASS = register(new Block("gray_stained_glass", builder())); - public static final Block LIGHT_GRAY_STAINED_GLASS = register(new Block("light_gray_stained_glass", builder())); - public static final Block CYAN_STAINED_GLASS = register(new Block("cyan_stained_glass", builder())); - public static final Block PURPLE_STAINED_GLASS = register(new Block("purple_stained_glass", builder())); - public static final Block BLUE_STAINED_GLASS = register(new Block("blue_stained_glass", builder())); - public static final Block BROWN_STAINED_GLASS = register(new Block("brown_stained_glass", builder())); - public static final Block GREEN_STAINED_GLASS = register(new Block("green_stained_glass", builder())); - public static final Block RED_STAINED_GLASS = register(new Block("red_stained_glass", builder())); - public static final Block BLACK_STAINED_GLASS = register(new Block("black_stained_glass", builder())); - public static final Block OAK_TRAPDOOR = register(new Block("oak_trapdoor", builder() + public static final Block WHITE_STAINED_GLASS = register(new Block("white_stained_glass", builder().destroyTime(0.3f))); + public static final Block ORANGE_STAINED_GLASS = register(new Block("orange_stained_glass", builder().destroyTime(0.3f))); + public static final Block MAGENTA_STAINED_GLASS = register(new Block("magenta_stained_glass", builder().destroyTime(0.3f))); + public static final Block LIGHT_BLUE_STAINED_GLASS = register(new Block("light_blue_stained_glass", builder().destroyTime(0.3f))); + public static final Block YELLOW_STAINED_GLASS = register(new Block("yellow_stained_glass", builder().destroyTime(0.3f))); + public static final Block LIME_STAINED_GLASS = register(new Block("lime_stained_glass", builder().destroyTime(0.3f))); + public static final Block PINK_STAINED_GLASS = register(new Block("pink_stained_glass", builder().destroyTime(0.3f))); + public static final Block GRAY_STAINED_GLASS = register(new Block("gray_stained_glass", builder().destroyTime(0.3f))); + public static final Block LIGHT_GRAY_STAINED_GLASS = register(new Block("light_gray_stained_glass", builder().destroyTime(0.3f))); + public static final Block CYAN_STAINED_GLASS = register(new Block("cyan_stained_glass", builder().destroyTime(0.3f))); + public static final Block PURPLE_STAINED_GLASS = register(new Block("purple_stained_glass", builder().destroyTime(0.3f))); + public static final Block BLUE_STAINED_GLASS = register(new Block("blue_stained_glass", builder().destroyTime(0.3f))); + public static final Block BROWN_STAINED_GLASS = register(new Block("brown_stained_glass", builder().destroyTime(0.3f))); + public static final Block GREEN_STAINED_GLASS = register(new Block("green_stained_glass", builder().destroyTime(0.3f))); + public static final Block RED_STAINED_GLASS = register(new Block("red_stained_glass", builder().destroyTime(0.3f))); + public static final Block BLACK_STAINED_GLASS = register(new Block("black_stained_glass", builder().destroyTime(0.3f))); + public static final Block OAK_TRAPDOOR = register(new Block("oak_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block SPRUCE_TRAPDOOR = register(new Block("spruce_trapdoor", builder() + public static final Block SPRUCE_TRAPDOOR = register(new Block("spruce_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block BIRCH_TRAPDOOR = register(new Block("birch_trapdoor", builder() + public static final Block BIRCH_TRAPDOOR = register(new Block("birch_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block JUNGLE_TRAPDOOR = register(new Block("jungle_trapdoor", builder() + public static final Block JUNGLE_TRAPDOOR = register(new Block("jungle_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block ACACIA_TRAPDOOR = register(new Block("acacia_trapdoor", builder() + public static final Block ACACIA_TRAPDOOR = register(new Block("acacia_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block CHERRY_TRAPDOOR = register(new Block("cherry_trapdoor", builder() + public static final Block CHERRY_TRAPDOOR = register(new Block("cherry_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block DARK_OAK_TRAPDOOR = register(new Block("dark_oak_trapdoor", builder() + public static final Block DARK_OAK_TRAPDOOR = register(new Block("dark_oak_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block MANGROVE_TRAPDOOR = register(new Block("mangrove_trapdoor", builder() + public static final Block MANGROVE_TRAPDOOR = register(new Block("mangrove_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block BAMBOO_TRAPDOOR = register(new Block("bamboo_trapdoor", builder() + public static final Block BAMBOO_TRAPDOOR = register(new Block("bamboo_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block STONE_BRICKS = register(new Block("stone_bricks", builder())); - public static final Block MOSSY_STONE_BRICKS = register(new Block("mossy_stone_bricks", builder())); - public static final Block CRACKED_STONE_BRICKS = register(new Block("cracked_stone_bricks", builder())); - public static final Block CHISELED_STONE_BRICKS = register(new Block("chiseled_stone_bricks", builder())); - public static final Block PACKED_MUD = register(new Block("packed_mud", builder())); - public static final Block MUD_BRICKS = register(new Block("mud_bricks", builder())); - public static final Block INFESTED_STONE = register(new Block("infested_stone", builder())); - public static final Block INFESTED_COBBLESTONE = register(new Block("infested_cobblestone", builder())); - public static final Block INFESTED_STONE_BRICKS = register(new Block("infested_stone_bricks", builder())); - public static final Block INFESTED_MOSSY_STONE_BRICKS = register(new Block("infested_mossy_stone_bricks", builder())); - public static final Block INFESTED_CRACKED_STONE_BRICKS = register(new Block("infested_cracked_stone_bricks", builder())); - public static final Block INFESTED_CHISELED_STONE_BRICKS = register(new Block("infested_chiseled_stone_bricks", builder())); - public static final Block BROWN_MUSHROOM_BLOCK = register(new Block("brown_mushroom_block", builder() + public static final Block STONE_BRICKS = register(new Block("stone_bricks", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block MOSSY_STONE_BRICKS = register(new Block("mossy_stone_bricks", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block CRACKED_STONE_BRICKS = register(new Block("cracked_stone_bricks", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block CHISELED_STONE_BRICKS = register(new Block("chiseled_stone_bricks", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block PACKED_MUD = register(new Block("packed_mud", builder().destroyTime(1.0f))); + public static final Block MUD_BRICKS = register(new Block("mud_bricks", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block INFESTED_STONE = register(new Block("infested_stone", builder().destroyTime(0.75f))); + public static final Block INFESTED_COBBLESTONE = register(new Block("infested_cobblestone", builder().destroyTime(1.0f))); + public static final Block INFESTED_STONE_BRICKS = register(new Block("infested_stone_bricks", builder().destroyTime(0.75f))); + public static final Block INFESTED_MOSSY_STONE_BRICKS = register(new Block("infested_mossy_stone_bricks", builder().destroyTime(0.75f))); + public static final Block INFESTED_CRACKED_STONE_BRICKS = register(new Block("infested_cracked_stone_bricks", builder().destroyTime(0.75f))); + public static final Block INFESTED_CHISELED_STONE_BRICKS = register(new Block("infested_chiseled_stone_bricks", builder().destroyTime(0.75f))); + public static final Block BROWN_MUSHROOM_BLOCK = register(new Block("brown_mushroom_block", builder().destroyTime(0.2f) .booleanState(DOWN) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(UP) .booleanState(WEST))); - public static final Block RED_MUSHROOM_BLOCK = register(new Block("red_mushroom_block", builder() + public static final Block RED_MUSHROOM_BLOCK = register(new Block("red_mushroom_block", builder().destroyTime(0.2f) .booleanState(DOWN) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(UP) .booleanState(WEST))); - public static final Block MUSHROOM_STEM = register(new Block("mushroom_stem", builder() + public static final Block MUSHROOM_STEM = register(new Block("mushroom_stem", builder().destroyTime(0.2f) .booleanState(DOWN) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(UP) .booleanState(WEST))); - public static final Block IRON_BARS = register(new Block("iron_bars", builder() + public static final Block IRON_BARS = register(new Block("iron_bars", builder().requiresCorrectToolForDrops().destroyTime(5.0f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block CHAIN = register(new Block("chain", builder() + public static final Block CHAIN = register(new Block("chain", builder().requiresCorrectToolForDrops().destroyTime(5.0f) .enumState(AXIS, Axis.VALUES) .booleanState(WATERLOGGED))); - public static final Block GLASS_PANE = register(new Block("glass_pane", builder() + public static final Block GLASS_PANE = register(new Block("glass_pane", builder().destroyTime(0.3f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block PUMPKIN = register(new Block("pumpkin", builder())); - public static final Block MELON = register(new Block("melon", builder())); + public static final Block PUMPKIN = register(new Block("pumpkin", builder().destroyTime(1.0f))); + public static final Block MELON = register(new Block("melon", builder().destroyTime(1.0f))); public static final Block ATTACHED_PUMPKIN_STEM = register(new Block("attached_pumpkin_stem", builder() .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); public static final Block ATTACHED_MELON_STEM = register(new Block("attached_melon_stem", builder() @@ -766,13 +766,13 @@ public final class Blocks { .intState(AGE_7, 0, 7))); public static final Block MELON_STEM = register(new Block("melon_stem", builder() .intState(AGE_7, 0, 7))); - public static final Block VINE = register(new Block("vine", builder() + public static final Block VINE = register(new Block("vine", builder().destroyTime(0.2f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(UP) .booleanState(WEST))); - public static final Block GLOW_LICHEN = register(new Block("glow_lichen", builder() + public static final Block GLOW_LICHEN = register(new Block("glow_lichen", builder().destroyTime(0.2f) .booleanState(DOWN) .booleanState(EAST) .booleanState(NORTH) @@ -780,73 +780,73 @@ public final class Blocks { .booleanState(UP) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block OAK_FENCE_GATE = register(new Block("oak_fence_gate", builder() + public static final Block OAK_FENCE_GATE = register(new Block("oak_fence_gate", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(IN_WALL) .booleanState(OPEN) .booleanState(POWERED))); - public static final Block BRICK_STAIRS = register(new Block("brick_stairs", builder() + public static final Block BRICK_STAIRS = register(new Block("brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block STONE_BRICK_STAIRS = register(new Block("stone_brick_stairs", builder() + public static final Block STONE_BRICK_STAIRS = register(new Block("stone_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block MUD_BRICK_STAIRS = register(new Block("mud_brick_stairs", builder() + public static final Block MUD_BRICK_STAIRS = register(new Block("mud_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block MYCELIUM = register(new Block("mycelium", builder() + public static final Block MYCELIUM = register(new Block("mycelium", builder().destroyTime(0.6f) .booleanState(SNOWY))); public static final Block LILY_PAD = register(new Block("lily_pad", builder())); - public static final Block NETHER_BRICKS = register(new Block("nether_bricks", builder())); - public static final Block NETHER_BRICK_FENCE = register(new Block("nether_brick_fence", builder() + public static final Block NETHER_BRICKS = register(new Block("nether_bricks", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); + public static final Block NETHER_BRICK_FENCE = register(new Block("nether_brick_fence", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block NETHER_BRICK_STAIRS = register(new Block("nether_brick_stairs", builder() + public static final Block NETHER_BRICK_STAIRS = register(new Block("nether_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); public static final Block NETHER_WART = register(new Block("nether_wart", builder() .intState(AGE_3, 0, 3))); - public static final Block ENCHANTING_TABLE = register(new Block("enchanting_table", builder())); - public static final Block BREWING_STAND = register(new Block("brewing_stand", builder() + public static final Block ENCHANTING_TABLE = register(new Block("enchanting_table", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(5.0f))); + public static final Block BREWING_STAND = register(new Block("brewing_stand", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(0.5f) .booleanState(HAS_BOTTLE_0) .booleanState(HAS_BOTTLE_1) .booleanState(HAS_BOTTLE_2))); - public static final Block CAULDRON = register(new Block("cauldron", builder())); - public static final Block WATER_CAULDRON = register(new Block("water_cauldron", builder() + public static final Block CAULDRON = register(new Block("cauldron", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); + public static final Block WATER_CAULDRON = register(new Block("water_cauldron", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .intState(LEVEL_CAULDRON, 1, 3))); - public static final Block LAVA_CAULDRON = register(new Block("lava_cauldron", builder())); - public static final Block POWDER_SNOW_CAULDRON = register(new Block("powder_snow_cauldron", builder() + public static final Block LAVA_CAULDRON = register(new Block("lava_cauldron", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); + public static final Block POWDER_SNOW_CAULDRON = register(new Block("powder_snow_cauldron", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .intState(LEVEL_CAULDRON, 1, 3))); - public static final Block END_PORTAL = register(new Block("end_portal", builder())); - public static final Block END_PORTAL_FRAME = register(new Block("end_portal_frame", builder() + public static final Block END_PORTAL = register(new Block("end_portal", builder().setBlockEntity().destroyTime(-1.0f))); + public static final Block END_PORTAL_FRAME = register(new Block("end_portal_frame", builder().destroyTime(-1.0f) .booleanState(EYE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block END_STONE = register(new Block("end_stone", builder())); - public static final Block DRAGON_EGG = register(new Block("dragon_egg", builder())); - public static final Block REDSTONE_LAMP = register(new Block("redstone_lamp", builder() + public static final Block END_STONE = register(new Block("end_stone", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block DRAGON_EGG = register(new Block("dragon_egg", builder().destroyTime(3.0f))); + public static final Block REDSTONE_LAMP = register(new Block("redstone_lamp", builder().destroyTime(0.3f) .booleanState(LIT))); - public static final Block COCOA = register(new Block("cocoa", builder() + public static final Block COCOA = register(new Block("cocoa", builder().destroyTime(0.2f) .intState(AGE_2, 0, 2) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block SANDSTONE_STAIRS = register(new Block("sandstone_stairs", builder() + public static final Block SANDSTONE_STAIRS = register(new Block("sandstone_stairs", builder().requiresCorrectToolForDrops().destroyTime(0.8f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block EMERALD_ORE = register(new Block("emerald_ore", builder())); - public static final Block DEEPSLATE_EMERALD_ORE = register(new Block("deepslate_emerald_ore", builder())); - public static final Block ENDER_CHEST = register(new Block("ender_chest", builder() + public static final Block EMERALD_ORE = register(new Block("emerald_ore", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block DEEPSLATE_EMERALD_ORE = register(new Block("deepslate_emerald_ore", builder().requiresCorrectToolForDrops().destroyTime(4.5f))); + public static final Block ENDER_CHEST = register(new Block("ender_chest", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(22.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); public static final Block TRIPWIRE_HOOK = register(new Block("tripwire_hook", builder() @@ -861,34 +861,34 @@ public final class Blocks { .booleanState(POWERED) .booleanState(SOUTH) .booleanState(WEST))); - public static final Block EMERALD_BLOCK = register(new Block("emerald_block", builder())); - public static final Block SPRUCE_STAIRS = register(new Block("spruce_stairs", builder() + public static final Block EMERALD_BLOCK = register(new Block("emerald_block", builder().requiresCorrectToolForDrops().destroyTime(5.0f))); + public static final Block SPRUCE_STAIRS = register(new Block("spruce_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block BIRCH_STAIRS = register(new Block("birch_stairs", builder() + public static final Block BIRCH_STAIRS = register(new Block("birch_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block JUNGLE_STAIRS = register(new Block("jungle_stairs", builder() + public static final Block JUNGLE_STAIRS = register(new Block("jungle_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block COMMAND_BLOCK = register(new Block("command_block", builder() + public static final Block COMMAND_BLOCK = register(new Block("command_block", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(-1.0f) .booleanState(CONDITIONAL) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block BEACON = register(new Block("beacon", builder())); - public static final Block COBBLESTONE_WALL = register(new Block("cobblestone_wall", builder() + public static final Block BEACON = register(new Block("beacon", builder().setBlockEntity().destroyTime(3.0f))); + public static final Block COBBLESTONE_WALL = register(new Block("cobblestone_wall", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(EAST_WALL, "none", "low", "tall") .enumState(NORTH_WALL, "none", "low", "tall") .enumState(SOUTH_WALL, "none", "low", "tall") .booleanState(UP) .booleanState(WATERLOGGED) .enumState(WEST_WALL, "none", "low", "tall"))); - public static final Block MOSSY_COBBLESTONE_WALL = register(new Block("mossy_cobblestone_wall", builder() + public static final Block MOSSY_COBBLESTONE_WALL = register(new Block("mossy_cobblestone_wall", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(EAST_WALL, "none", "low", "tall") .enumState(NORTH_WALL, "none", "low", "tall") .enumState(SOUTH_WALL, "none", "low", "tall") @@ -927,329 +927,329 @@ public final class Blocks { .intState(AGE_7, 0, 7))); public static final Block POTATOES = register(new Block("potatoes", builder() .intState(AGE_7, 0, 7))); - public static final Block OAK_BUTTON = register(new Block("oak_button", builder() + public static final Block OAK_BUTTON = register(new Block("oak_button", builder().destroyTime(0.5f) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block SPRUCE_BUTTON = register(new Block("spruce_button", builder() + public static final Block SPRUCE_BUTTON = register(new Block("spruce_button", builder().destroyTime(0.5f) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block BIRCH_BUTTON = register(new Block("birch_button", builder() + public static final Block BIRCH_BUTTON = register(new Block("birch_button", builder().destroyTime(0.5f) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block JUNGLE_BUTTON = register(new Block("jungle_button", builder() + public static final Block JUNGLE_BUTTON = register(new Block("jungle_button", builder().destroyTime(0.5f) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block ACACIA_BUTTON = register(new Block("acacia_button", builder() + public static final Block ACACIA_BUTTON = register(new Block("acacia_button", builder().destroyTime(0.5f) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block CHERRY_BUTTON = register(new Block("cherry_button", builder() + public static final Block CHERRY_BUTTON = register(new Block("cherry_button", builder().destroyTime(0.5f) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block DARK_OAK_BUTTON = register(new Block("dark_oak_button", builder() + public static final Block DARK_OAK_BUTTON = register(new Block("dark_oak_button", builder().destroyTime(0.5f) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block MANGROVE_BUTTON = register(new Block("mangrove_button", builder() + public static final Block MANGROVE_BUTTON = register(new Block("mangrove_button", builder().destroyTime(0.5f) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block BAMBOO_BUTTON = register(new Block("bamboo_button", builder() + public static final Block BAMBOO_BUTTON = register(new Block("bamboo_button", builder().destroyTime(0.5f) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block SKELETON_SKULL = register(new Block("skeleton_skull", builder() + public static final Block SKELETON_SKULL = register(new Block("skeleton_skull", builder().setBlockEntity().destroyTime(1.0f) .booleanState(POWERED) .intState(ROTATION_16, 0, 15))); - public static final Block SKELETON_WALL_SKULL = register(new Block("skeleton_wall_skull", builder() + public static final Block SKELETON_WALL_SKULL = register(new Block("skeleton_wall_skull", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block WITHER_SKELETON_SKULL = register(new Block("wither_skeleton_skull", builder() + public static final Block WITHER_SKELETON_SKULL = register(new Block("wither_skeleton_skull", builder().setBlockEntity().destroyTime(1.0f) .booleanState(POWERED) .intState(ROTATION_16, 0, 15))); - public static final Block WITHER_SKELETON_WALL_SKULL = register(new Block("wither_skeleton_wall_skull", builder() + public static final Block WITHER_SKELETON_WALL_SKULL = register(new Block("wither_skeleton_wall_skull", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block ZOMBIE_HEAD = register(new Block("zombie_head", builder() + public static final Block ZOMBIE_HEAD = register(new Block("zombie_head", builder().setBlockEntity().destroyTime(1.0f) .booleanState(POWERED) .intState(ROTATION_16, 0, 15))); - public static final Block ZOMBIE_WALL_HEAD = register(new Block("zombie_wall_head", builder() + public static final Block ZOMBIE_WALL_HEAD = register(new Block("zombie_wall_head", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block PLAYER_HEAD = register(new Block("player_head", builder() + public static final Block PLAYER_HEAD = register(new Block("player_head", builder().setBlockEntity().destroyTime(1.0f) .booleanState(POWERED) .intState(ROTATION_16, 0, 15))); - public static final Block PLAYER_WALL_HEAD = register(new Block("player_wall_head", builder() + public static final Block PLAYER_WALL_HEAD = register(new Block("player_wall_head", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block CREEPER_HEAD = register(new Block("creeper_head", builder() + public static final Block CREEPER_HEAD = register(new Block("creeper_head", builder().setBlockEntity().destroyTime(1.0f) .booleanState(POWERED) .intState(ROTATION_16, 0, 15))); - public static final Block CREEPER_WALL_HEAD = register(new Block("creeper_wall_head", builder() + public static final Block CREEPER_WALL_HEAD = register(new Block("creeper_wall_head", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block DRAGON_HEAD = register(new Block("dragon_head", builder() + public static final Block DRAGON_HEAD = register(new Block("dragon_head", builder().setBlockEntity().destroyTime(1.0f) .booleanState(POWERED) .intState(ROTATION_16, 0, 15))); - public static final Block DRAGON_WALL_HEAD = register(new Block("dragon_wall_head", builder() + public static final Block DRAGON_WALL_HEAD = register(new Block("dragon_wall_head", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block PIGLIN_HEAD = register(new Block("piglin_head", builder() + public static final Block PIGLIN_HEAD = register(new Block("piglin_head", builder().setBlockEntity().destroyTime(1.0f) .booleanState(POWERED) .intState(ROTATION_16, 0, 15))); - public static final Block PIGLIN_WALL_HEAD = register(new Block("piglin_wall_head", builder() + public static final Block PIGLIN_WALL_HEAD = register(new Block("piglin_wall_head", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block ANVIL = register(new Block("anvil", builder() + public static final Block ANVIL = register(new Block("anvil", builder().requiresCorrectToolForDrops().destroyTime(5.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block CHIPPED_ANVIL = register(new Block("chipped_anvil", builder() + public static final Block CHIPPED_ANVIL = register(new Block("chipped_anvil", builder().requiresCorrectToolForDrops().destroyTime(5.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block DAMAGED_ANVIL = register(new Block("damaged_anvil", builder() + public static final Block DAMAGED_ANVIL = register(new Block("damaged_anvil", builder().requiresCorrectToolForDrops().destroyTime(5.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block TRAPPED_CHEST = register(new Block("trapped_chest", builder() + public static final Block TRAPPED_CHEST = register(new Block("trapped_chest", builder().setBlockEntity().destroyTime(2.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(CHEST_TYPE, "single", "left", "right") .booleanState(WATERLOGGED))); - public static final Block LIGHT_WEIGHTED_PRESSURE_PLATE = register(new Block("light_weighted_pressure_plate", builder() + public static final Block LIGHT_WEIGHTED_PRESSURE_PLATE = register(new Block("light_weighted_pressure_plate", builder().requiresCorrectToolForDrops().destroyTime(0.5f) .intState(POWER, 0, 15))); - public static final Block HEAVY_WEIGHTED_PRESSURE_PLATE = register(new Block("heavy_weighted_pressure_plate", builder() + public static final Block HEAVY_WEIGHTED_PRESSURE_PLATE = register(new Block("heavy_weighted_pressure_plate", builder().requiresCorrectToolForDrops().destroyTime(0.5f) .intState(POWER, 0, 15))); - public static final Block COMPARATOR = register(new Block("comparator", builder() + public static final Block COMPARATOR = register(new Block("comparator", builder().setBlockEntity() .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(MODE_COMPARATOR, "compare", "subtract") .booleanState(POWERED))); - public static final Block DAYLIGHT_DETECTOR = register(new Block("daylight_detector", builder() + public static final Block DAYLIGHT_DETECTOR = register(new Block("daylight_detector", builder().setBlockEntity().destroyTime(0.2f) .booleanState(INVERTED) .intState(POWER, 0, 15))); - public static final Block REDSTONE_BLOCK = register(new Block("redstone_block", builder())); - public static final Block NETHER_QUARTZ_ORE = register(new Block("nether_quartz_ore", builder())); - public static final Block HOPPER = register(new Block("hopper", builder() + public static final Block REDSTONE_BLOCK = register(new Block("redstone_block", builder().requiresCorrectToolForDrops().destroyTime(5.0f))); + public static final Block NETHER_QUARTZ_ORE = register(new Block("nether_quartz_ore", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block HOPPER = register(new Block("hopper", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(3.0f) .booleanState(ENABLED) .enumState(FACING_HOPPER, Direction.DOWN, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block QUARTZ_BLOCK = register(new Block("quartz_block", builder())); - public static final Block CHISELED_QUARTZ_BLOCK = register(new Block("chiseled_quartz_block", builder())); - public static final Block QUARTZ_PILLAR = register(new Block("quartz_pillar", builder() + public static final Block QUARTZ_BLOCK = register(new Block("quartz_block", builder().requiresCorrectToolForDrops().destroyTime(0.8f))); + public static final Block CHISELED_QUARTZ_BLOCK = register(new Block("chiseled_quartz_block", builder().requiresCorrectToolForDrops().destroyTime(0.8f))); + public static final Block QUARTZ_PILLAR = register(new Block("quartz_pillar", builder().requiresCorrectToolForDrops().destroyTime(0.8f) .enumState(AXIS, Axis.VALUES))); - public static final Block QUARTZ_STAIRS = register(new Block("quartz_stairs", builder() + public static final Block QUARTZ_STAIRS = register(new Block("quartz_stairs", builder().requiresCorrectToolForDrops().destroyTime(0.8f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block ACTIVATOR_RAIL = register(new Block("activator_rail", builder() + public static final Block ACTIVATOR_RAIL = register(new Block("activator_rail", builder().destroyTime(0.7f) .booleanState(POWERED) .enumState(RAIL_SHAPE_STRAIGHT, "north_south", "east_west", "ascending_east", "ascending_west", "ascending_north", "ascending_south") .booleanState(WATERLOGGED))); - public static final Block DROPPER = register(new Block("dropper", builder() + public static final Block DROPPER = register(new Block("dropper", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) .booleanState(TRIGGERED))); - public static final Block WHITE_TERRACOTTA = register(new Block("white_terracotta", builder())); - public static final Block ORANGE_TERRACOTTA = register(new Block("orange_terracotta", builder())); - public static final Block MAGENTA_TERRACOTTA = register(new Block("magenta_terracotta", builder())); - public static final Block LIGHT_BLUE_TERRACOTTA = register(new Block("light_blue_terracotta", builder())); - public static final Block YELLOW_TERRACOTTA = register(new Block("yellow_terracotta", builder())); - public static final Block LIME_TERRACOTTA = register(new Block("lime_terracotta", builder())); - public static final Block PINK_TERRACOTTA = register(new Block("pink_terracotta", builder())); - public static final Block GRAY_TERRACOTTA = register(new Block("gray_terracotta", builder())); - public static final Block LIGHT_GRAY_TERRACOTTA = register(new Block("light_gray_terracotta", builder())); - public static final Block CYAN_TERRACOTTA = register(new Block("cyan_terracotta", builder())); - public static final Block PURPLE_TERRACOTTA = register(new Block("purple_terracotta", builder())); - public static final Block BLUE_TERRACOTTA = register(new Block("blue_terracotta", builder())); - public static final Block BROWN_TERRACOTTA = register(new Block("brown_terracotta", builder())); - public static final Block GREEN_TERRACOTTA = register(new Block("green_terracotta", builder())); - public static final Block RED_TERRACOTTA = register(new Block("red_terracotta", builder())); - public static final Block BLACK_TERRACOTTA = register(new Block("black_terracotta", builder())); - public static final Block WHITE_STAINED_GLASS_PANE = register(new Block("white_stained_glass_pane", builder() + public static final Block WHITE_TERRACOTTA = register(new Block("white_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.25f))); + public static final Block ORANGE_TERRACOTTA = register(new Block("orange_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.25f))); + public static final Block MAGENTA_TERRACOTTA = register(new Block("magenta_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.25f))); + public static final Block LIGHT_BLUE_TERRACOTTA = register(new Block("light_blue_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.25f))); + public static final Block YELLOW_TERRACOTTA = register(new Block("yellow_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.25f))); + public static final Block LIME_TERRACOTTA = register(new Block("lime_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.25f))); + public static final Block PINK_TERRACOTTA = register(new Block("pink_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.25f))); + public static final Block GRAY_TERRACOTTA = register(new Block("gray_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.25f))); + public static final Block LIGHT_GRAY_TERRACOTTA = register(new Block("light_gray_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.25f))); + public static final Block CYAN_TERRACOTTA = register(new Block("cyan_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.25f))); + public static final Block PURPLE_TERRACOTTA = register(new Block("purple_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.25f))); + public static final Block BLUE_TERRACOTTA = register(new Block("blue_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.25f))); + public static final Block BROWN_TERRACOTTA = register(new Block("brown_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.25f))); + public static final Block GREEN_TERRACOTTA = register(new Block("green_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.25f))); + public static final Block RED_TERRACOTTA = register(new Block("red_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.25f))); + public static final Block BLACK_TERRACOTTA = register(new Block("black_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.25f))); + public static final Block WHITE_STAINED_GLASS_PANE = register(new Block("white_stained_glass_pane", builder().destroyTime(0.3f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block ORANGE_STAINED_GLASS_PANE = register(new Block("orange_stained_glass_pane", builder() + public static final Block ORANGE_STAINED_GLASS_PANE = register(new Block("orange_stained_glass_pane", builder().destroyTime(0.3f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block MAGENTA_STAINED_GLASS_PANE = register(new Block("magenta_stained_glass_pane", builder() + public static final Block MAGENTA_STAINED_GLASS_PANE = register(new Block("magenta_stained_glass_pane", builder().destroyTime(0.3f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block LIGHT_BLUE_STAINED_GLASS_PANE = register(new Block("light_blue_stained_glass_pane", builder() + public static final Block LIGHT_BLUE_STAINED_GLASS_PANE = register(new Block("light_blue_stained_glass_pane", builder().destroyTime(0.3f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block YELLOW_STAINED_GLASS_PANE = register(new Block("yellow_stained_glass_pane", builder() + public static final Block YELLOW_STAINED_GLASS_PANE = register(new Block("yellow_stained_glass_pane", builder().destroyTime(0.3f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block LIME_STAINED_GLASS_PANE = register(new Block("lime_stained_glass_pane", builder() + public static final Block LIME_STAINED_GLASS_PANE = register(new Block("lime_stained_glass_pane", builder().destroyTime(0.3f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block PINK_STAINED_GLASS_PANE = register(new Block("pink_stained_glass_pane", builder() + public static final Block PINK_STAINED_GLASS_PANE = register(new Block("pink_stained_glass_pane", builder().destroyTime(0.3f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block GRAY_STAINED_GLASS_PANE = register(new Block("gray_stained_glass_pane", builder() + public static final Block GRAY_STAINED_GLASS_PANE = register(new Block("gray_stained_glass_pane", builder().destroyTime(0.3f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block LIGHT_GRAY_STAINED_GLASS_PANE = register(new Block("light_gray_stained_glass_pane", builder() + public static final Block LIGHT_GRAY_STAINED_GLASS_PANE = register(new Block("light_gray_stained_glass_pane", builder().destroyTime(0.3f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block CYAN_STAINED_GLASS_PANE = register(new Block("cyan_stained_glass_pane", builder() + public static final Block CYAN_STAINED_GLASS_PANE = register(new Block("cyan_stained_glass_pane", builder().destroyTime(0.3f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block PURPLE_STAINED_GLASS_PANE = register(new Block("purple_stained_glass_pane", builder() + public static final Block PURPLE_STAINED_GLASS_PANE = register(new Block("purple_stained_glass_pane", builder().destroyTime(0.3f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block BLUE_STAINED_GLASS_PANE = register(new Block("blue_stained_glass_pane", builder() + public static final Block BLUE_STAINED_GLASS_PANE = register(new Block("blue_stained_glass_pane", builder().destroyTime(0.3f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block BROWN_STAINED_GLASS_PANE = register(new Block("brown_stained_glass_pane", builder() + public static final Block BROWN_STAINED_GLASS_PANE = register(new Block("brown_stained_glass_pane", builder().destroyTime(0.3f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block GREEN_STAINED_GLASS_PANE = register(new Block("green_stained_glass_pane", builder() + public static final Block GREEN_STAINED_GLASS_PANE = register(new Block("green_stained_glass_pane", builder().destroyTime(0.3f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block RED_STAINED_GLASS_PANE = register(new Block("red_stained_glass_pane", builder() + public static final Block RED_STAINED_GLASS_PANE = register(new Block("red_stained_glass_pane", builder().destroyTime(0.3f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block BLACK_STAINED_GLASS_PANE = register(new Block("black_stained_glass_pane", builder() + public static final Block BLACK_STAINED_GLASS_PANE = register(new Block("black_stained_glass_pane", builder().destroyTime(0.3f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block ACACIA_STAIRS = register(new Block("acacia_stairs", builder() + public static final Block ACACIA_STAIRS = register(new Block("acacia_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block CHERRY_STAIRS = register(new Block("cherry_stairs", builder() + public static final Block CHERRY_STAIRS = register(new Block("cherry_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block DARK_OAK_STAIRS = register(new Block("dark_oak_stairs", builder() + public static final Block DARK_OAK_STAIRS = register(new Block("dark_oak_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block MANGROVE_STAIRS = register(new Block("mangrove_stairs", builder() + public static final Block MANGROVE_STAIRS = register(new Block("mangrove_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block BAMBOO_STAIRS = register(new Block("bamboo_stairs", builder() + public static final Block BAMBOO_STAIRS = register(new Block("bamboo_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block BAMBOO_MOSAIC_STAIRS = register(new Block("bamboo_mosaic_stairs", builder() + public static final Block BAMBOO_MOSAIC_STAIRS = register(new Block("bamboo_mosaic_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); public static final Block SLIME_BLOCK = register(new Block("slime_block", builder())); - public static final Block BARRIER = register(new Block("barrier", builder() + public static final Block BARRIER = register(new Block("barrier", builder().destroyTime(-1.0f) .booleanState(WATERLOGGED))); - public static final Block LIGHT = register(new Block("light", builder() + public static final Block LIGHT = register(new Block("light", builder().destroyTime(-1.0f) .intState(LEVEL, 0, 15) .booleanState(WATERLOGGED))); - public static final Block IRON_TRAPDOOR = register(new Block("iron_trapdoor", builder() + public static final Block IRON_TRAPDOOR = register(new Block("iron_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(5.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block PRISMARINE = register(new Block("prismarine", builder())); - public static final Block PRISMARINE_BRICKS = register(new Block("prismarine_bricks", builder())); - public static final Block DARK_PRISMARINE = register(new Block("dark_prismarine", builder())); - public static final Block PRISMARINE_STAIRS = register(new Block("prismarine_stairs", builder() + public static final Block PRISMARINE = register(new Block("prismarine", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block PRISMARINE_BRICKS = register(new Block("prismarine_bricks", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block DARK_PRISMARINE = register(new Block("dark_prismarine", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block PRISMARINE_STAIRS = register(new Block("prismarine_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block PRISMARINE_BRICK_STAIRS = register(new Block("prismarine_brick_stairs", builder() + public static final Block PRISMARINE_BRICK_STAIRS = register(new Block("prismarine_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block DARK_PRISMARINE_STAIRS = register(new Block("dark_prismarine_stairs", builder() + public static final Block DARK_PRISMARINE_STAIRS = register(new Block("dark_prismarine_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block PRISMARINE_SLAB = register(new Block("prismarine_slab", builder() + public static final Block PRISMARINE_SLAB = register(new Block("prismarine_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block PRISMARINE_BRICK_SLAB = register(new Block("prismarine_brick_slab", builder() + public static final Block PRISMARINE_BRICK_SLAB = register(new Block("prismarine_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block DARK_PRISMARINE_SLAB = register(new Block("dark_prismarine_slab", builder() + public static final Block DARK_PRISMARINE_SLAB = register(new Block("dark_prismarine_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block SEA_LANTERN = register(new Block("sea_lantern", builder())); - public static final Block HAY_BLOCK = register(new Block("hay_block", builder() + public static final Block SEA_LANTERN = register(new Block("sea_lantern", builder().destroyTime(0.3f))); + public static final Block HAY_BLOCK = register(new Block("hay_block", builder().destroyTime(0.5f) .enumState(AXIS, Axis.VALUES))); - public static final Block WHITE_CARPET = register(new Block("white_carpet", builder())); - public static final Block ORANGE_CARPET = register(new Block("orange_carpet", builder())); - public static final Block MAGENTA_CARPET = register(new Block("magenta_carpet", builder())); - public static final Block LIGHT_BLUE_CARPET = register(new Block("light_blue_carpet", builder())); - public static final Block YELLOW_CARPET = register(new Block("yellow_carpet", builder())); - public static final Block LIME_CARPET = register(new Block("lime_carpet", builder())); - public static final Block PINK_CARPET = register(new Block("pink_carpet", builder())); - public static final Block GRAY_CARPET = register(new Block("gray_carpet", builder())); - public static final Block LIGHT_GRAY_CARPET = register(new Block("light_gray_carpet", builder())); - public static final Block CYAN_CARPET = register(new Block("cyan_carpet", builder())); - public static final Block PURPLE_CARPET = register(new Block("purple_carpet", builder())); - public static final Block BLUE_CARPET = register(new Block("blue_carpet", builder())); - public static final Block BROWN_CARPET = register(new Block("brown_carpet", builder())); - public static final Block GREEN_CARPET = register(new Block("green_carpet", builder())); - public static final Block RED_CARPET = register(new Block("red_carpet", builder())); - public static final Block BLACK_CARPET = register(new Block("black_carpet", builder())); - public static final Block TERRACOTTA = register(new Block("terracotta", builder())); - public static final Block COAL_BLOCK = register(new Block("coal_block", builder())); - public static final Block PACKED_ICE = register(new Block("packed_ice", builder())); + public static final Block WHITE_CARPET = register(new Block("white_carpet", builder().destroyTime(0.1f))); + public static final Block ORANGE_CARPET = register(new Block("orange_carpet", builder().destroyTime(0.1f))); + public static final Block MAGENTA_CARPET = register(new Block("magenta_carpet", builder().destroyTime(0.1f))); + public static final Block LIGHT_BLUE_CARPET = register(new Block("light_blue_carpet", builder().destroyTime(0.1f))); + public static final Block YELLOW_CARPET = register(new Block("yellow_carpet", builder().destroyTime(0.1f))); + public static final Block LIME_CARPET = register(new Block("lime_carpet", builder().destroyTime(0.1f))); + public static final Block PINK_CARPET = register(new Block("pink_carpet", builder().destroyTime(0.1f))); + public static final Block GRAY_CARPET = register(new Block("gray_carpet", builder().destroyTime(0.1f))); + public static final Block LIGHT_GRAY_CARPET = register(new Block("light_gray_carpet", builder().destroyTime(0.1f))); + public static final Block CYAN_CARPET = register(new Block("cyan_carpet", builder().destroyTime(0.1f))); + public static final Block PURPLE_CARPET = register(new Block("purple_carpet", builder().destroyTime(0.1f))); + public static final Block BLUE_CARPET = register(new Block("blue_carpet", builder().destroyTime(0.1f))); + public static final Block BROWN_CARPET = register(new Block("brown_carpet", builder().destroyTime(0.1f))); + public static final Block GREEN_CARPET = register(new Block("green_carpet", builder().destroyTime(0.1f))); + public static final Block RED_CARPET = register(new Block("red_carpet", builder().destroyTime(0.1f))); + public static final Block BLACK_CARPET = register(new Block("black_carpet", builder().destroyTime(0.1f))); + public static final Block TERRACOTTA = register(new Block("terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.25f))); + public static final Block COAL_BLOCK = register(new Block("coal_block", builder().requiresCorrectToolForDrops().destroyTime(5.0f))); + public static final Block PACKED_ICE = register(new Block("packed_ice", builder().destroyTime(0.5f))); public static final Block SUNFLOWER = register(new Block("sunflower", builder() .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); public static final Block LILAC = register(new Block("lilac", builder() @@ -1262,285 +1262,285 @@ public final class Blocks { .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); public static final Block LARGE_FERN = register(new Block("large_fern", builder() .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); - public static final Block WHITE_BANNER = register(new BannerBlock("white_banner", 0, builder() + public static final Block WHITE_BANNER = register(new BannerBlock("white_banner", 0, builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15))); - public static final Block ORANGE_BANNER = register(new BannerBlock("orange_banner", 1, builder() + public static final Block ORANGE_BANNER = register(new BannerBlock("orange_banner", 1, builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15))); - public static final Block MAGENTA_BANNER = register(new BannerBlock("magenta_banner", 2, builder() + public static final Block MAGENTA_BANNER = register(new BannerBlock("magenta_banner", 2, builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15))); - public static final Block LIGHT_BLUE_BANNER = register(new BannerBlock("light_blue_banner", 3, builder() + public static final Block LIGHT_BLUE_BANNER = register(new BannerBlock("light_blue_banner", 3, builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15))); - public static final Block YELLOW_BANNER = register(new BannerBlock("yellow_banner", 4, builder() + public static final Block YELLOW_BANNER = register(new BannerBlock("yellow_banner", 4, builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15))); - public static final Block LIME_BANNER = register(new BannerBlock("lime_banner", 5, builder() + public static final Block LIME_BANNER = register(new BannerBlock("lime_banner", 5, builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15))); - public static final Block PINK_BANNER = register(new BannerBlock("pink_banner", 6, builder() + public static final Block PINK_BANNER = register(new BannerBlock("pink_banner", 6, builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15))); - public static final Block GRAY_BANNER = register(new BannerBlock("gray_banner", 7, builder() + public static final Block GRAY_BANNER = register(new BannerBlock("gray_banner", 7, builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15))); - public static final Block LIGHT_GRAY_BANNER = register(new BannerBlock("light_gray_banner", 8, builder() + public static final Block LIGHT_GRAY_BANNER = register(new BannerBlock("light_gray_banner", 8, builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15))); - public static final Block CYAN_BANNER = register(new BannerBlock("cyan_banner", 9, builder() + public static final Block CYAN_BANNER = register(new BannerBlock("cyan_banner", 9, builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15))); - public static final Block PURPLE_BANNER = register(new BannerBlock("purple_banner", 10, builder() + public static final Block PURPLE_BANNER = register(new BannerBlock("purple_banner", 10, builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15))); - public static final Block BLUE_BANNER = register(new BannerBlock("blue_banner", 11, builder() + public static final Block BLUE_BANNER = register(new BannerBlock("blue_banner", 11, builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15))); - public static final Block BROWN_BANNER = register(new BannerBlock("brown_banner", 12, builder() + public static final Block BROWN_BANNER = register(new BannerBlock("brown_banner", 12, builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15))); - public static final Block GREEN_BANNER = register(new BannerBlock("green_banner", 13, builder() + public static final Block GREEN_BANNER = register(new BannerBlock("green_banner", 13, builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15))); - public static final Block RED_BANNER = register(new BannerBlock("red_banner", 14, builder() + public static final Block RED_BANNER = register(new BannerBlock("red_banner", 14, builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15))); - public static final Block BLACK_BANNER = register(new BannerBlock("black_banner", 15, builder() + public static final Block BLACK_BANNER = register(new BannerBlock("black_banner", 15, builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15))); - public static final Block WHITE_WALL_BANNER = register(new BannerBlock("white_wall_banner", 0, builder() + public static final Block WHITE_WALL_BANNER = register(new BannerBlock("white_wall_banner", 0, builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block ORANGE_WALL_BANNER = register(new BannerBlock("orange_wall_banner", 1, builder() + public static final Block ORANGE_WALL_BANNER = register(new BannerBlock("orange_wall_banner", 1, builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block MAGENTA_WALL_BANNER = register(new BannerBlock("magenta_wall_banner", 2, builder() + public static final Block MAGENTA_WALL_BANNER = register(new BannerBlock("magenta_wall_banner", 2, builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block LIGHT_BLUE_WALL_BANNER = register(new BannerBlock("light_blue_wall_banner", 3, builder() + public static final Block LIGHT_BLUE_WALL_BANNER = register(new BannerBlock("light_blue_wall_banner", 3, builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block YELLOW_WALL_BANNER = register(new BannerBlock("yellow_wall_banner", 4, builder() + public static final Block YELLOW_WALL_BANNER = register(new BannerBlock("yellow_wall_banner", 4, builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block LIME_WALL_BANNER = register(new BannerBlock("lime_wall_banner", 5, builder() + public static final Block LIME_WALL_BANNER = register(new BannerBlock("lime_wall_banner", 5, builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block PINK_WALL_BANNER = register(new BannerBlock("pink_wall_banner", 6, builder() + public static final Block PINK_WALL_BANNER = register(new BannerBlock("pink_wall_banner", 6, builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block GRAY_WALL_BANNER = register(new BannerBlock("gray_wall_banner", 7, builder() + public static final Block GRAY_WALL_BANNER = register(new BannerBlock("gray_wall_banner", 7, builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block LIGHT_GRAY_WALL_BANNER = register(new BannerBlock("light_gray_wall_banner", 8, builder() + public static final Block LIGHT_GRAY_WALL_BANNER = register(new BannerBlock("light_gray_wall_banner", 8, builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block CYAN_WALL_BANNER = register(new BannerBlock("cyan_wall_banner", 9, builder() + public static final Block CYAN_WALL_BANNER = register(new BannerBlock("cyan_wall_banner", 9, builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block PURPLE_WALL_BANNER = register(new BannerBlock("purple_wall_banner", 10, builder() + public static final Block PURPLE_WALL_BANNER = register(new BannerBlock("purple_wall_banner", 10, builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block BLUE_WALL_BANNER = register(new BannerBlock("blue_wall_banner", 11, builder() + public static final Block BLUE_WALL_BANNER = register(new BannerBlock("blue_wall_banner", 11, builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block BROWN_WALL_BANNER = register(new BannerBlock("brown_wall_banner", 12, builder() + public static final Block BROWN_WALL_BANNER = register(new BannerBlock("brown_wall_banner", 12, builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block GREEN_WALL_BANNER = register(new BannerBlock("green_wall_banner", 13, builder() + public static final Block GREEN_WALL_BANNER = register(new BannerBlock("green_wall_banner", 13, builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block RED_WALL_BANNER = register(new BannerBlock("red_wall_banner", 14, builder() + public static final Block RED_WALL_BANNER = register(new BannerBlock("red_wall_banner", 14, builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block BLACK_WALL_BANNER = register(new BannerBlock("black_wall_banner", 15, builder() + public static final Block BLACK_WALL_BANNER = register(new BannerBlock("black_wall_banner", 15, builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block RED_SANDSTONE = register(new Block("red_sandstone", builder())); - public static final Block CHISELED_RED_SANDSTONE = register(new Block("chiseled_red_sandstone", builder())); - public static final Block CUT_RED_SANDSTONE = register(new Block("cut_red_sandstone", builder())); - public static final Block RED_SANDSTONE_STAIRS = register(new Block("red_sandstone_stairs", builder() + public static final Block RED_SANDSTONE = register(new Block("red_sandstone", builder().requiresCorrectToolForDrops().destroyTime(0.8f))); + public static final Block CHISELED_RED_SANDSTONE = register(new Block("chiseled_red_sandstone", builder().requiresCorrectToolForDrops().destroyTime(0.8f))); + public static final Block CUT_RED_SANDSTONE = register(new Block("cut_red_sandstone", builder().requiresCorrectToolForDrops().destroyTime(0.8f))); + public static final Block RED_SANDSTONE_STAIRS = register(new Block("red_sandstone_stairs", builder().requiresCorrectToolForDrops().destroyTime(0.8f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block OAK_SLAB = register(new Block("oak_slab", builder() + public static final Block OAK_SLAB = register(new Block("oak_slab", builder().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block SPRUCE_SLAB = register(new Block("spruce_slab", builder() + public static final Block SPRUCE_SLAB = register(new Block("spruce_slab", builder().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block BIRCH_SLAB = register(new Block("birch_slab", builder() + public static final Block BIRCH_SLAB = register(new Block("birch_slab", builder().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block JUNGLE_SLAB = register(new Block("jungle_slab", builder() + public static final Block JUNGLE_SLAB = register(new Block("jungle_slab", builder().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block ACACIA_SLAB = register(new Block("acacia_slab", builder() + public static final Block ACACIA_SLAB = register(new Block("acacia_slab", builder().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block CHERRY_SLAB = register(new Block("cherry_slab", builder() + public static final Block CHERRY_SLAB = register(new Block("cherry_slab", builder().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block DARK_OAK_SLAB = register(new Block("dark_oak_slab", builder() + public static final Block DARK_OAK_SLAB = register(new Block("dark_oak_slab", builder().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block MANGROVE_SLAB = register(new Block("mangrove_slab", builder() + public static final Block MANGROVE_SLAB = register(new Block("mangrove_slab", builder().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block BAMBOO_SLAB = register(new Block("bamboo_slab", builder() + public static final Block BAMBOO_SLAB = register(new Block("bamboo_slab", builder().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block BAMBOO_MOSAIC_SLAB = register(new Block("bamboo_mosaic_slab", builder() + public static final Block BAMBOO_MOSAIC_SLAB = register(new Block("bamboo_mosaic_slab", builder().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block STONE_SLAB = register(new Block("stone_slab", builder() + public static final Block STONE_SLAB = register(new Block("stone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block SMOOTH_STONE_SLAB = register(new Block("smooth_stone_slab", builder() + public static final Block SMOOTH_STONE_SLAB = register(new Block("smooth_stone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block SANDSTONE_SLAB = register(new Block("sandstone_slab", builder() + public static final Block SANDSTONE_SLAB = register(new Block("sandstone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block CUT_SANDSTONE_SLAB = register(new Block("cut_sandstone_slab", builder() + public static final Block CUT_SANDSTONE_SLAB = register(new Block("cut_sandstone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block PETRIFIED_OAK_SLAB = register(new Block("petrified_oak_slab", builder() + public static final Block PETRIFIED_OAK_SLAB = register(new Block("petrified_oak_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block COBBLESTONE_SLAB = register(new Block("cobblestone_slab", builder() + public static final Block COBBLESTONE_SLAB = register(new Block("cobblestone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block BRICK_SLAB = register(new Block("brick_slab", builder() + public static final Block BRICK_SLAB = register(new Block("brick_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block STONE_BRICK_SLAB = register(new Block("stone_brick_slab", builder() + public static final Block STONE_BRICK_SLAB = register(new Block("stone_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block MUD_BRICK_SLAB = register(new Block("mud_brick_slab", builder() + public static final Block MUD_BRICK_SLAB = register(new Block("mud_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block NETHER_BRICK_SLAB = register(new Block("nether_brick_slab", builder() + public static final Block NETHER_BRICK_SLAB = register(new Block("nether_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block QUARTZ_SLAB = register(new Block("quartz_slab", builder() + public static final Block QUARTZ_SLAB = register(new Block("quartz_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block RED_SANDSTONE_SLAB = register(new Block("red_sandstone_slab", builder() + public static final Block RED_SANDSTONE_SLAB = register(new Block("red_sandstone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block CUT_RED_SANDSTONE_SLAB = register(new Block("cut_red_sandstone_slab", builder() + public static final Block CUT_RED_SANDSTONE_SLAB = register(new Block("cut_red_sandstone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block PURPUR_SLAB = register(new Block("purpur_slab", builder() + public static final Block PURPUR_SLAB = register(new Block("purpur_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block SMOOTH_STONE = register(new Block("smooth_stone", builder())); - public static final Block SMOOTH_SANDSTONE = register(new Block("smooth_sandstone", builder())); - public static final Block SMOOTH_QUARTZ = register(new Block("smooth_quartz", builder())); - public static final Block SMOOTH_RED_SANDSTONE = register(new Block("smooth_red_sandstone", builder())); - public static final Block SPRUCE_FENCE_GATE = register(new Block("spruce_fence_gate", builder() + public static final Block SMOOTH_STONE = register(new Block("smooth_stone", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); + public static final Block SMOOTH_SANDSTONE = register(new Block("smooth_sandstone", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); + public static final Block SMOOTH_QUARTZ = register(new Block("smooth_quartz", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); + public static final Block SMOOTH_RED_SANDSTONE = register(new Block("smooth_red_sandstone", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); + public static final Block SPRUCE_FENCE_GATE = register(new Block("spruce_fence_gate", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(IN_WALL) .booleanState(OPEN) .booleanState(POWERED))); - public static final Block BIRCH_FENCE_GATE = register(new Block("birch_fence_gate", builder() + public static final Block BIRCH_FENCE_GATE = register(new Block("birch_fence_gate", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(IN_WALL) .booleanState(OPEN) .booleanState(POWERED))); - public static final Block JUNGLE_FENCE_GATE = register(new Block("jungle_fence_gate", builder() + public static final Block JUNGLE_FENCE_GATE = register(new Block("jungle_fence_gate", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(IN_WALL) .booleanState(OPEN) .booleanState(POWERED))); - public static final Block ACACIA_FENCE_GATE = register(new Block("acacia_fence_gate", builder() + public static final Block ACACIA_FENCE_GATE = register(new Block("acacia_fence_gate", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(IN_WALL) .booleanState(OPEN) .booleanState(POWERED))); - public static final Block CHERRY_FENCE_GATE = register(new Block("cherry_fence_gate", builder() + public static final Block CHERRY_FENCE_GATE = register(new Block("cherry_fence_gate", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(IN_WALL) .booleanState(OPEN) .booleanState(POWERED))); - public static final Block DARK_OAK_FENCE_GATE = register(new Block("dark_oak_fence_gate", builder() + public static final Block DARK_OAK_FENCE_GATE = register(new Block("dark_oak_fence_gate", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(IN_WALL) .booleanState(OPEN) .booleanState(POWERED))); - public static final Block MANGROVE_FENCE_GATE = register(new Block("mangrove_fence_gate", builder() + public static final Block MANGROVE_FENCE_GATE = register(new Block("mangrove_fence_gate", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(IN_WALL) .booleanState(OPEN) .booleanState(POWERED))); - public static final Block BAMBOO_FENCE_GATE = register(new Block("bamboo_fence_gate", builder() + public static final Block BAMBOO_FENCE_GATE = register(new Block("bamboo_fence_gate", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(IN_WALL) .booleanState(OPEN) .booleanState(POWERED))); - public static final Block SPRUCE_FENCE = register(new Block("spruce_fence", builder() + public static final Block SPRUCE_FENCE = register(new Block("spruce_fence", builder().destroyTime(2.0f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block BIRCH_FENCE = register(new Block("birch_fence", builder() + public static final Block BIRCH_FENCE = register(new Block("birch_fence", builder().destroyTime(2.0f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block JUNGLE_FENCE = register(new Block("jungle_fence", builder() + public static final Block JUNGLE_FENCE = register(new Block("jungle_fence", builder().destroyTime(2.0f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block ACACIA_FENCE = register(new Block("acacia_fence", builder() + public static final Block ACACIA_FENCE = register(new Block("acacia_fence", builder().destroyTime(2.0f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block CHERRY_FENCE = register(new Block("cherry_fence", builder() + public static final Block CHERRY_FENCE = register(new Block("cherry_fence", builder().destroyTime(2.0f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block DARK_OAK_FENCE = register(new Block("dark_oak_fence", builder() + public static final Block DARK_OAK_FENCE = register(new Block("dark_oak_fence", builder().destroyTime(2.0f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block MANGROVE_FENCE = register(new Block("mangrove_fence", builder() + public static final Block MANGROVE_FENCE = register(new Block("mangrove_fence", builder().destroyTime(2.0f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block BAMBOO_FENCE = register(new Block("bamboo_fence", builder() + public static final Block BAMBOO_FENCE = register(new Block("bamboo_fence", builder().destroyTime(2.0f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block SPRUCE_DOOR = register(new Block("spruce_door", builder() + public static final Block SPRUCE_DOOR = register(new Block("spruce_door", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block BIRCH_DOOR = register(new Block("birch_door", builder() + public static final Block BIRCH_DOOR = register(new Block("birch_door", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block JUNGLE_DOOR = register(new Block("jungle_door", builder() + public static final Block JUNGLE_DOOR = register(new Block("jungle_door", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block ACACIA_DOOR = register(new Block("acacia_door", builder() + public static final Block ACACIA_DOOR = register(new Block("acacia_door", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block CHERRY_DOOR = register(new Block("cherry_door", builder() + public static final Block CHERRY_DOOR = register(new Block("cherry_door", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block DARK_OAK_DOOR = register(new Block("dark_oak_door", builder() + public static final Block DARK_OAK_DOOR = register(new Block("dark_oak_door", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block MANGROVE_DOOR = register(new Block("mangrove_door", builder() + public static final Block MANGROVE_DOOR = register(new Block("mangrove_door", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block BAMBOO_DOOR = register(new Block("bamboo_door", builder() + public static final Block BAMBOO_DOOR = register(new Block("bamboo_door", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") @@ -1548,24 +1548,24 @@ public final class Blocks { .booleanState(POWERED))); public static final Block END_ROD = register(new Block("end_rod", builder() .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block CHORUS_PLANT = register(new Block("chorus_plant", builder() + public static final Block CHORUS_PLANT = register(new Block("chorus_plant", builder().destroyTime(0.4f) .booleanState(DOWN) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(UP) .booleanState(WEST))); - public static final Block CHORUS_FLOWER = register(new Block("chorus_flower", builder() + public static final Block CHORUS_FLOWER = register(new Block("chorus_flower", builder().destroyTime(0.4f) .intState(AGE_5, 0, 5))); - public static final Block PURPUR_BLOCK = register(new Block("purpur_block", builder())); - public static final Block PURPUR_PILLAR = register(new Block("purpur_pillar", builder() + public static final Block PURPUR_BLOCK = register(new Block("purpur_block", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block PURPUR_PILLAR = register(new Block("purpur_pillar", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(AXIS, Axis.VALUES))); - public static final Block PURPUR_STAIRS = register(new Block("purpur_stairs", builder() + public static final Block PURPUR_STAIRS = register(new Block("purpur_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block END_STONE_BRICKS = register(new Block("end_stone_bricks", builder())); + public static final Block END_STONE_BRICKS = register(new Block("end_stone_bricks", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); public static final Block TORCHFLOWER_CROP = register(new Block("torchflower_crop", builder() .intState(AGE_1, 0, 1))); public static final Block PITCHER_CROP = register(new Block("pitcher_crop", builder() @@ -1575,151 +1575,151 @@ public final class Blocks { .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); public static final Block BEETROOTS = register(new Block("beetroots", builder() .intState(AGE_3, 0, 3))); - public static final Block DIRT_PATH = register(new Block("dirt_path", builder())); - public static final Block END_GATEWAY = register(new Block("end_gateway", builder())); - public static final Block REPEATING_COMMAND_BLOCK = register(new Block("repeating_command_block", builder() + public static final Block DIRT_PATH = register(new Block("dirt_path", builder().destroyTime(0.65f))); + public static final Block END_GATEWAY = register(new Block("end_gateway", builder().setBlockEntity().destroyTime(-1.0f))); + public static final Block REPEATING_COMMAND_BLOCK = register(new Block("repeating_command_block", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(-1.0f) .booleanState(CONDITIONAL) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block CHAIN_COMMAND_BLOCK = register(new Block("chain_command_block", builder() + public static final Block CHAIN_COMMAND_BLOCK = register(new Block("chain_command_block", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(-1.0f) .booleanState(CONDITIONAL) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block FROSTED_ICE = register(new Block("frosted_ice", builder() + public static final Block FROSTED_ICE = register(new Block("frosted_ice", builder().destroyTime(0.5f) .intState(AGE_3, 0, 3))); - public static final Block MAGMA_BLOCK = register(new Block("magma_block", builder())); - public static final Block NETHER_WART_BLOCK = register(new Block("nether_wart_block", builder())); - public static final Block RED_NETHER_BRICKS = register(new Block("red_nether_bricks", builder())); - public static final Block BONE_BLOCK = register(new Block("bone_block", builder() + public static final Block MAGMA_BLOCK = register(new Block("magma_block", builder().requiresCorrectToolForDrops().destroyTime(0.5f))); + public static final Block NETHER_WART_BLOCK = register(new Block("nether_wart_block", builder().destroyTime(1.0f))); + public static final Block RED_NETHER_BRICKS = register(new Block("red_nether_bricks", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); + public static final Block BONE_BLOCK = register(new Block("bone_block", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); public static final Block STRUCTURE_VOID = register(new Block("structure_void", builder())); - public static final Block OBSERVER = register(new Block("observer", builder() + public static final Block OBSERVER = register(new Block("observer", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) .booleanState(POWERED))); - public static final Block SHULKER_BOX = register(new Block("shulker_box", builder() + public static final Block SHULKER_BOX = register(new Block("shulker_box", builder().setBlockEntity().destroyTime(2.0f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block WHITE_SHULKER_BOX = register(new Block("white_shulker_box", builder() + public static final Block WHITE_SHULKER_BOX = register(new Block("white_shulker_box", builder().setBlockEntity().destroyTime(2.0f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block ORANGE_SHULKER_BOX = register(new Block("orange_shulker_box", builder() + public static final Block ORANGE_SHULKER_BOX = register(new Block("orange_shulker_box", builder().setBlockEntity().destroyTime(2.0f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block MAGENTA_SHULKER_BOX = register(new Block("magenta_shulker_box", builder() + public static final Block MAGENTA_SHULKER_BOX = register(new Block("magenta_shulker_box", builder().setBlockEntity().destroyTime(2.0f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block LIGHT_BLUE_SHULKER_BOX = register(new Block("light_blue_shulker_box", builder() + public static final Block LIGHT_BLUE_SHULKER_BOX = register(new Block("light_blue_shulker_box", builder().setBlockEntity().destroyTime(2.0f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block YELLOW_SHULKER_BOX = register(new Block("yellow_shulker_box", builder() + public static final Block YELLOW_SHULKER_BOX = register(new Block("yellow_shulker_box", builder().setBlockEntity().destroyTime(2.0f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block LIME_SHULKER_BOX = register(new Block("lime_shulker_box", builder() + public static final Block LIME_SHULKER_BOX = register(new Block("lime_shulker_box", builder().setBlockEntity().destroyTime(2.0f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block PINK_SHULKER_BOX = register(new Block("pink_shulker_box", builder() + public static final Block PINK_SHULKER_BOX = register(new Block("pink_shulker_box", builder().setBlockEntity().destroyTime(2.0f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block GRAY_SHULKER_BOX = register(new Block("gray_shulker_box", builder() + public static final Block GRAY_SHULKER_BOX = register(new Block("gray_shulker_box", builder().setBlockEntity().destroyTime(2.0f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block LIGHT_GRAY_SHULKER_BOX = register(new Block("light_gray_shulker_box", builder() + public static final Block LIGHT_GRAY_SHULKER_BOX = register(new Block("light_gray_shulker_box", builder().setBlockEntity().destroyTime(2.0f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block CYAN_SHULKER_BOX = register(new Block("cyan_shulker_box", builder() + public static final Block CYAN_SHULKER_BOX = register(new Block("cyan_shulker_box", builder().setBlockEntity().destroyTime(2.0f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block PURPLE_SHULKER_BOX = register(new Block("purple_shulker_box", builder() + public static final Block PURPLE_SHULKER_BOX = register(new Block("purple_shulker_box", builder().setBlockEntity().destroyTime(2.0f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block BLUE_SHULKER_BOX = register(new Block("blue_shulker_box", builder() + public static final Block BLUE_SHULKER_BOX = register(new Block("blue_shulker_box", builder().setBlockEntity().destroyTime(2.0f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block BROWN_SHULKER_BOX = register(new Block("brown_shulker_box", builder() + public static final Block BROWN_SHULKER_BOX = register(new Block("brown_shulker_box", builder().setBlockEntity().destroyTime(2.0f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block GREEN_SHULKER_BOX = register(new Block("green_shulker_box", builder() + public static final Block GREEN_SHULKER_BOX = register(new Block("green_shulker_box", builder().setBlockEntity().destroyTime(2.0f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block RED_SHULKER_BOX = register(new Block("red_shulker_box", builder() + public static final Block RED_SHULKER_BOX = register(new Block("red_shulker_box", builder().setBlockEntity().destroyTime(2.0f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block BLACK_SHULKER_BOX = register(new Block("black_shulker_box", builder() + public static final Block BLACK_SHULKER_BOX = register(new Block("black_shulker_box", builder().setBlockEntity().destroyTime(2.0f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block WHITE_GLAZED_TERRACOTTA = register(new Block("white_glazed_terracotta", builder() + public static final Block WHITE_GLAZED_TERRACOTTA = register(new Block("white_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block ORANGE_GLAZED_TERRACOTTA = register(new Block("orange_glazed_terracotta", builder() + public static final Block ORANGE_GLAZED_TERRACOTTA = register(new Block("orange_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block MAGENTA_GLAZED_TERRACOTTA = register(new Block("magenta_glazed_terracotta", builder() + public static final Block MAGENTA_GLAZED_TERRACOTTA = register(new Block("magenta_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block LIGHT_BLUE_GLAZED_TERRACOTTA = register(new Block("light_blue_glazed_terracotta", builder() + public static final Block LIGHT_BLUE_GLAZED_TERRACOTTA = register(new Block("light_blue_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block YELLOW_GLAZED_TERRACOTTA = register(new Block("yellow_glazed_terracotta", builder() + public static final Block YELLOW_GLAZED_TERRACOTTA = register(new Block("yellow_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block LIME_GLAZED_TERRACOTTA = register(new Block("lime_glazed_terracotta", builder() + public static final Block LIME_GLAZED_TERRACOTTA = register(new Block("lime_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block PINK_GLAZED_TERRACOTTA = register(new Block("pink_glazed_terracotta", builder() + public static final Block PINK_GLAZED_TERRACOTTA = register(new Block("pink_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block GRAY_GLAZED_TERRACOTTA = register(new Block("gray_glazed_terracotta", builder() + public static final Block GRAY_GLAZED_TERRACOTTA = register(new Block("gray_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block LIGHT_GRAY_GLAZED_TERRACOTTA = register(new Block("light_gray_glazed_terracotta", builder() + public static final Block LIGHT_GRAY_GLAZED_TERRACOTTA = register(new Block("light_gray_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block CYAN_GLAZED_TERRACOTTA = register(new Block("cyan_glazed_terracotta", builder() + public static final Block CYAN_GLAZED_TERRACOTTA = register(new Block("cyan_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block PURPLE_GLAZED_TERRACOTTA = register(new Block("purple_glazed_terracotta", builder() + public static final Block PURPLE_GLAZED_TERRACOTTA = register(new Block("purple_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block BLUE_GLAZED_TERRACOTTA = register(new Block("blue_glazed_terracotta", builder() + public static final Block BLUE_GLAZED_TERRACOTTA = register(new Block("blue_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block BROWN_GLAZED_TERRACOTTA = register(new Block("brown_glazed_terracotta", builder() + public static final Block BROWN_GLAZED_TERRACOTTA = register(new Block("brown_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block GREEN_GLAZED_TERRACOTTA = register(new Block("green_glazed_terracotta", builder() + public static final Block GREEN_GLAZED_TERRACOTTA = register(new Block("green_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block RED_GLAZED_TERRACOTTA = register(new Block("red_glazed_terracotta", builder() + public static final Block RED_GLAZED_TERRACOTTA = register(new Block("red_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block BLACK_GLAZED_TERRACOTTA = register(new Block("black_glazed_terracotta", builder() + public static final Block BLACK_GLAZED_TERRACOTTA = register(new Block("black_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block WHITE_CONCRETE = register(new Block("white_concrete", builder())); - public static final Block ORANGE_CONCRETE = register(new Block("orange_concrete", builder())); - public static final Block MAGENTA_CONCRETE = register(new Block("magenta_concrete", builder())); - public static final Block LIGHT_BLUE_CONCRETE = register(new Block("light_blue_concrete", builder())); - public static final Block YELLOW_CONCRETE = register(new Block("yellow_concrete", builder())); - public static final Block LIME_CONCRETE = register(new Block("lime_concrete", builder())); - public static final Block PINK_CONCRETE = register(new Block("pink_concrete", builder())); - public static final Block GRAY_CONCRETE = register(new Block("gray_concrete", builder())); - public static final Block LIGHT_GRAY_CONCRETE = register(new Block("light_gray_concrete", builder())); - public static final Block CYAN_CONCRETE = register(new Block("cyan_concrete", builder())); - public static final Block PURPLE_CONCRETE = register(new Block("purple_concrete", builder())); - public static final Block BLUE_CONCRETE = register(new Block("blue_concrete", builder())); - public static final Block BROWN_CONCRETE = register(new Block("brown_concrete", builder())); - public static final Block GREEN_CONCRETE = register(new Block("green_concrete", builder())); - public static final Block RED_CONCRETE = register(new Block("red_concrete", builder())); - public static final Block BLACK_CONCRETE = register(new Block("black_concrete", builder())); - public static final Block WHITE_CONCRETE_POWDER = register(new Block("white_concrete_powder", builder())); - public static final Block ORANGE_CONCRETE_POWDER = register(new Block("orange_concrete_powder", builder())); - public static final Block MAGENTA_CONCRETE_POWDER = register(new Block("magenta_concrete_powder", builder())); - public static final Block LIGHT_BLUE_CONCRETE_POWDER = register(new Block("light_blue_concrete_powder", builder())); - public static final Block YELLOW_CONCRETE_POWDER = register(new Block("yellow_concrete_powder", builder())); - public static final Block LIME_CONCRETE_POWDER = register(new Block("lime_concrete_powder", builder())); - public static final Block PINK_CONCRETE_POWDER = register(new Block("pink_concrete_powder", builder())); - public static final Block GRAY_CONCRETE_POWDER = register(new Block("gray_concrete_powder", builder())); - public static final Block LIGHT_GRAY_CONCRETE_POWDER = register(new Block("light_gray_concrete_powder", builder())); - public static final Block CYAN_CONCRETE_POWDER = register(new Block("cyan_concrete_powder", builder())); - public static final Block PURPLE_CONCRETE_POWDER = register(new Block("purple_concrete_powder", builder())); - public static final Block BLUE_CONCRETE_POWDER = register(new Block("blue_concrete_powder", builder())); - public static final Block BROWN_CONCRETE_POWDER = register(new Block("brown_concrete_powder", builder())); - public static final Block GREEN_CONCRETE_POWDER = register(new Block("green_concrete_powder", builder())); - public static final Block RED_CONCRETE_POWDER = register(new Block("red_concrete_powder", builder())); - public static final Block BLACK_CONCRETE_POWDER = register(new Block("black_concrete_powder", builder())); + public static final Block WHITE_CONCRETE = register(new Block("white_concrete", builder().requiresCorrectToolForDrops().destroyTime(1.8f))); + public static final Block ORANGE_CONCRETE = register(new Block("orange_concrete", builder().requiresCorrectToolForDrops().destroyTime(1.8f))); + public static final Block MAGENTA_CONCRETE = register(new Block("magenta_concrete", builder().requiresCorrectToolForDrops().destroyTime(1.8f))); + public static final Block LIGHT_BLUE_CONCRETE = register(new Block("light_blue_concrete", builder().requiresCorrectToolForDrops().destroyTime(1.8f))); + public static final Block YELLOW_CONCRETE = register(new Block("yellow_concrete", builder().requiresCorrectToolForDrops().destroyTime(1.8f))); + public static final Block LIME_CONCRETE = register(new Block("lime_concrete", builder().requiresCorrectToolForDrops().destroyTime(1.8f))); + public static final Block PINK_CONCRETE = register(new Block("pink_concrete", builder().requiresCorrectToolForDrops().destroyTime(1.8f))); + public static final Block GRAY_CONCRETE = register(new Block("gray_concrete", builder().requiresCorrectToolForDrops().destroyTime(1.8f))); + public static final Block LIGHT_GRAY_CONCRETE = register(new Block("light_gray_concrete", builder().requiresCorrectToolForDrops().destroyTime(1.8f))); + public static final Block CYAN_CONCRETE = register(new Block("cyan_concrete", builder().requiresCorrectToolForDrops().destroyTime(1.8f))); + public static final Block PURPLE_CONCRETE = register(new Block("purple_concrete", builder().requiresCorrectToolForDrops().destroyTime(1.8f))); + public static final Block BLUE_CONCRETE = register(new Block("blue_concrete", builder().requiresCorrectToolForDrops().destroyTime(1.8f))); + public static final Block BROWN_CONCRETE = register(new Block("brown_concrete", builder().requiresCorrectToolForDrops().destroyTime(1.8f))); + public static final Block GREEN_CONCRETE = register(new Block("green_concrete", builder().requiresCorrectToolForDrops().destroyTime(1.8f))); + public static final Block RED_CONCRETE = register(new Block("red_concrete", builder().requiresCorrectToolForDrops().destroyTime(1.8f))); + public static final Block BLACK_CONCRETE = register(new Block("black_concrete", builder().requiresCorrectToolForDrops().destroyTime(1.8f))); + public static final Block WHITE_CONCRETE_POWDER = register(new Block("white_concrete_powder", builder().destroyTime(0.5f))); + public static final Block ORANGE_CONCRETE_POWDER = register(new Block("orange_concrete_powder", builder().destroyTime(0.5f))); + public static final Block MAGENTA_CONCRETE_POWDER = register(new Block("magenta_concrete_powder", builder().destroyTime(0.5f))); + public static final Block LIGHT_BLUE_CONCRETE_POWDER = register(new Block("light_blue_concrete_powder", builder().destroyTime(0.5f))); + public static final Block YELLOW_CONCRETE_POWDER = register(new Block("yellow_concrete_powder", builder().destroyTime(0.5f))); + public static final Block LIME_CONCRETE_POWDER = register(new Block("lime_concrete_powder", builder().destroyTime(0.5f))); + public static final Block PINK_CONCRETE_POWDER = register(new Block("pink_concrete_powder", builder().destroyTime(0.5f))); + public static final Block GRAY_CONCRETE_POWDER = register(new Block("gray_concrete_powder", builder().destroyTime(0.5f))); + public static final Block LIGHT_GRAY_CONCRETE_POWDER = register(new Block("light_gray_concrete_powder", builder().destroyTime(0.5f))); + public static final Block CYAN_CONCRETE_POWDER = register(new Block("cyan_concrete_powder", builder().destroyTime(0.5f))); + public static final Block PURPLE_CONCRETE_POWDER = register(new Block("purple_concrete_powder", builder().destroyTime(0.5f))); + public static final Block BLUE_CONCRETE_POWDER = register(new Block("blue_concrete_powder", builder().destroyTime(0.5f))); + public static final Block BROWN_CONCRETE_POWDER = register(new Block("brown_concrete_powder", builder().destroyTime(0.5f))); + public static final Block GREEN_CONCRETE_POWDER = register(new Block("green_concrete_powder", builder().destroyTime(0.5f))); + public static final Block RED_CONCRETE_POWDER = register(new Block("red_concrete_powder", builder().destroyTime(0.5f))); + public static final Block BLACK_CONCRETE_POWDER = register(new Block("black_concrete_powder", builder().destroyTime(0.5f))); public static final Block KELP = register(new Block("kelp", builder() .intState(AGE_25, 0, 25))); public static final Block KELP_PLANT = register(new Block("kelp_plant", builder())); - public static final Block DRIED_KELP_BLOCK = register(new Block("dried_kelp_block", builder())); - public static final Block TURTLE_EGG = register(new Block("turtle_egg", builder() + public static final Block DRIED_KELP_BLOCK = register(new Block("dried_kelp_block", builder().destroyTime(0.5f))); + public static final Block TURTLE_EGG = register(new Block("turtle_egg", builder().destroyTime(0.5f) .intState(EGGS, 1, 4) .intState(HATCH, 0, 2))); - public static final Block SNIFFER_EGG = register(new Block("sniffer_egg", builder() + public static final Block SNIFFER_EGG = register(new Block("sniffer_egg", builder().destroyTime(0.5f) .intState(HATCH, 0, 2))); - public static final Block DEAD_TUBE_CORAL_BLOCK = register(new Block("dead_tube_coral_block", builder())); - public static final Block DEAD_BRAIN_CORAL_BLOCK = register(new Block("dead_brain_coral_block", builder())); - public static final Block DEAD_BUBBLE_CORAL_BLOCK = register(new Block("dead_bubble_coral_block", builder())); - public static final Block DEAD_FIRE_CORAL_BLOCK = register(new Block("dead_fire_coral_block", builder())); - public static final Block DEAD_HORN_CORAL_BLOCK = register(new Block("dead_horn_coral_block", builder())); - public static final Block TUBE_CORAL_BLOCK = register(new Block("tube_coral_block", builder())); - public static final Block BRAIN_CORAL_BLOCK = register(new Block("brain_coral_block", builder())); - public static final Block BUBBLE_CORAL_BLOCK = register(new Block("bubble_coral_block", builder())); - public static final Block FIRE_CORAL_BLOCK = register(new Block("fire_coral_block", builder())); - public static final Block HORN_CORAL_BLOCK = register(new Block("horn_coral_block", builder())); - public static final Block DEAD_TUBE_CORAL = register(new Block("dead_tube_coral", builder() + public static final Block DEAD_TUBE_CORAL_BLOCK = register(new Block("dead_tube_coral_block", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block DEAD_BRAIN_CORAL_BLOCK = register(new Block("dead_brain_coral_block", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block DEAD_BUBBLE_CORAL_BLOCK = register(new Block("dead_bubble_coral_block", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block DEAD_FIRE_CORAL_BLOCK = register(new Block("dead_fire_coral_block", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block DEAD_HORN_CORAL_BLOCK = register(new Block("dead_horn_coral_block", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block TUBE_CORAL_BLOCK = register(new Block("tube_coral_block", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block BRAIN_CORAL_BLOCK = register(new Block("brain_coral_block", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block BUBBLE_CORAL_BLOCK = register(new Block("bubble_coral_block", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block FIRE_CORAL_BLOCK = register(new Block("fire_coral_block", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block HORN_CORAL_BLOCK = register(new Block("horn_coral_block", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block DEAD_TUBE_CORAL = register(new Block("dead_tube_coral", builder().requiresCorrectToolForDrops() .booleanState(WATERLOGGED))); - public static final Block DEAD_BRAIN_CORAL = register(new Block("dead_brain_coral", builder() + public static final Block DEAD_BRAIN_CORAL = register(new Block("dead_brain_coral", builder().requiresCorrectToolForDrops() .booleanState(WATERLOGGED))); - public static final Block DEAD_BUBBLE_CORAL = register(new Block("dead_bubble_coral", builder() + public static final Block DEAD_BUBBLE_CORAL = register(new Block("dead_bubble_coral", builder().requiresCorrectToolForDrops() .booleanState(WATERLOGGED))); - public static final Block DEAD_FIRE_CORAL = register(new Block("dead_fire_coral", builder() + public static final Block DEAD_FIRE_CORAL = register(new Block("dead_fire_coral", builder().requiresCorrectToolForDrops() .booleanState(WATERLOGGED))); - public static final Block DEAD_HORN_CORAL = register(new Block("dead_horn_coral", builder() + public static final Block DEAD_HORN_CORAL = register(new Block("dead_horn_coral", builder().requiresCorrectToolForDrops() .booleanState(WATERLOGGED))); public static final Block TUBE_CORAL = register(new Block("tube_coral", builder() .booleanState(WATERLOGGED))); @@ -1731,15 +1731,15 @@ public final class Blocks { .booleanState(WATERLOGGED))); public static final Block HORN_CORAL = register(new Block("horn_coral", builder() .booleanState(WATERLOGGED))); - public static final Block DEAD_TUBE_CORAL_FAN = register(new Block("dead_tube_coral_fan", builder() + public static final Block DEAD_TUBE_CORAL_FAN = register(new Block("dead_tube_coral_fan", builder().requiresCorrectToolForDrops() .booleanState(WATERLOGGED))); - public static final Block DEAD_BRAIN_CORAL_FAN = register(new Block("dead_brain_coral_fan", builder() + public static final Block DEAD_BRAIN_CORAL_FAN = register(new Block("dead_brain_coral_fan", builder().requiresCorrectToolForDrops() .booleanState(WATERLOGGED))); - public static final Block DEAD_BUBBLE_CORAL_FAN = register(new Block("dead_bubble_coral_fan", builder() + public static final Block DEAD_BUBBLE_CORAL_FAN = register(new Block("dead_bubble_coral_fan", builder().requiresCorrectToolForDrops() .booleanState(WATERLOGGED))); - public static final Block DEAD_FIRE_CORAL_FAN = register(new Block("dead_fire_coral_fan", builder() + public static final Block DEAD_FIRE_CORAL_FAN = register(new Block("dead_fire_coral_fan", builder().requiresCorrectToolForDrops() .booleanState(WATERLOGGED))); - public static final Block DEAD_HORN_CORAL_FAN = register(new Block("dead_horn_coral_fan", builder() + public static final Block DEAD_HORN_CORAL_FAN = register(new Block("dead_horn_coral_fan", builder().requiresCorrectToolForDrops() .booleanState(WATERLOGGED))); public static final Block TUBE_CORAL_FAN = register(new Block("tube_coral_fan", builder() .booleanState(WATERLOGGED))); @@ -1751,19 +1751,19 @@ public final class Blocks { .booleanState(WATERLOGGED))); public static final Block HORN_CORAL_FAN = register(new Block("horn_coral_fan", builder() .booleanState(WATERLOGGED))); - public static final Block DEAD_TUBE_CORAL_WALL_FAN = register(new Block("dead_tube_coral_wall_fan", builder() + public static final Block DEAD_TUBE_CORAL_WALL_FAN = register(new Block("dead_tube_coral_wall_fan", builder().requiresCorrectToolForDrops() .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block DEAD_BRAIN_CORAL_WALL_FAN = register(new Block("dead_brain_coral_wall_fan", builder() + public static final Block DEAD_BRAIN_CORAL_WALL_FAN = register(new Block("dead_brain_coral_wall_fan", builder().requiresCorrectToolForDrops() .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block DEAD_BUBBLE_CORAL_WALL_FAN = register(new Block("dead_bubble_coral_wall_fan", builder() + public static final Block DEAD_BUBBLE_CORAL_WALL_FAN = register(new Block("dead_bubble_coral_wall_fan", builder().requiresCorrectToolForDrops() .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block DEAD_FIRE_CORAL_WALL_FAN = register(new Block("dead_fire_coral_wall_fan", builder() + public static final Block DEAD_FIRE_CORAL_WALL_FAN = register(new Block("dead_fire_coral_wall_fan", builder().requiresCorrectToolForDrops() .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block DEAD_HORN_CORAL_WALL_FAN = register(new Block("dead_horn_coral_wall_fan", builder() + public static final Block DEAD_HORN_CORAL_WALL_FAN = register(new Block("dead_horn_coral_wall_fan", builder().requiresCorrectToolForDrops() .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); public static final Block TUBE_CORAL_WALL_FAN = register(new Block("tube_coral_wall_fan", builder() @@ -1784,11 +1784,11 @@ public final class Blocks { public static final Block SEA_PICKLE = register(new Block("sea_pickle", builder() .intState(PICKLES, 1, 4) .booleanState(WATERLOGGED))); - public static final Block BLUE_ICE = register(new Block("blue_ice", builder())); - public static final Block CONDUIT = register(new Block("conduit", builder() + public static final Block BLUE_ICE = register(new Block("blue_ice", builder().destroyTime(2.8f))); + public static final Block CONDUIT = register(new Block("conduit", builder().setBlockEntity().destroyTime(3.0f) .booleanState(WATERLOGGED))); - public static final Block BAMBOO_SAPLING = register(new Block("bamboo_sapling", builder())); - public static final Block BAMBOO = register(new Block("bamboo", builder() + public static final Block BAMBOO_SAPLING = register(new Block("bamboo_sapling", builder().destroyTime(1.0f))); + public static final Block BAMBOO = register(new Block("bamboo", builder().destroyTime(1.0f) .intState(AGE_1, 0, 1) .enumState(BAMBOO_LEAVES, "none", "small", "large") .intState(STAGE, 0, 1))); @@ -1797,200 +1797,200 @@ public final class Blocks { public static final Block CAVE_AIR = register(new Block("cave_air", builder())); public static final Block BUBBLE_COLUMN = register(new Block("bubble_column", builder() .booleanState(DRAG))); - public static final Block POLISHED_GRANITE_STAIRS = register(new Block("polished_granite_stairs", builder() + public static final Block POLISHED_GRANITE_STAIRS = register(new Block("polished_granite_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block SMOOTH_RED_SANDSTONE_STAIRS = register(new Block("smooth_red_sandstone_stairs", builder() + public static final Block SMOOTH_RED_SANDSTONE_STAIRS = register(new Block("smooth_red_sandstone_stairs", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block MOSSY_STONE_BRICK_STAIRS = register(new Block("mossy_stone_brick_stairs", builder() + public static final Block MOSSY_STONE_BRICK_STAIRS = register(new Block("mossy_stone_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block POLISHED_DIORITE_STAIRS = register(new Block("polished_diorite_stairs", builder() + public static final Block POLISHED_DIORITE_STAIRS = register(new Block("polished_diorite_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block MOSSY_COBBLESTONE_STAIRS = register(new Block("mossy_cobblestone_stairs", builder() + public static final Block MOSSY_COBBLESTONE_STAIRS = register(new Block("mossy_cobblestone_stairs", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block END_STONE_BRICK_STAIRS = register(new Block("end_stone_brick_stairs", builder() + public static final Block END_STONE_BRICK_STAIRS = register(new Block("end_stone_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block STONE_STAIRS = register(new Block("stone_stairs", builder() + public static final Block STONE_STAIRS = register(new Block("stone_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block SMOOTH_SANDSTONE_STAIRS = register(new Block("smooth_sandstone_stairs", builder() + public static final Block SMOOTH_SANDSTONE_STAIRS = register(new Block("smooth_sandstone_stairs", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block SMOOTH_QUARTZ_STAIRS = register(new Block("smooth_quartz_stairs", builder() + public static final Block SMOOTH_QUARTZ_STAIRS = register(new Block("smooth_quartz_stairs", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block GRANITE_STAIRS = register(new Block("granite_stairs", builder() + public static final Block GRANITE_STAIRS = register(new Block("granite_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block ANDESITE_STAIRS = register(new Block("andesite_stairs", builder() + public static final Block ANDESITE_STAIRS = register(new Block("andesite_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block RED_NETHER_BRICK_STAIRS = register(new Block("red_nether_brick_stairs", builder() + public static final Block RED_NETHER_BRICK_STAIRS = register(new Block("red_nether_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block POLISHED_ANDESITE_STAIRS = register(new Block("polished_andesite_stairs", builder() + public static final Block POLISHED_ANDESITE_STAIRS = register(new Block("polished_andesite_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block DIORITE_STAIRS = register(new Block("diorite_stairs", builder() + public static final Block DIORITE_STAIRS = register(new Block("diorite_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block POLISHED_GRANITE_SLAB = register(new Block("polished_granite_slab", builder() + public static final Block POLISHED_GRANITE_SLAB = register(new Block("polished_granite_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block SMOOTH_RED_SANDSTONE_SLAB = register(new Block("smooth_red_sandstone_slab", builder() + public static final Block SMOOTH_RED_SANDSTONE_SLAB = register(new Block("smooth_red_sandstone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block MOSSY_STONE_BRICK_SLAB = register(new Block("mossy_stone_brick_slab", builder() + public static final Block MOSSY_STONE_BRICK_SLAB = register(new Block("mossy_stone_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block POLISHED_DIORITE_SLAB = register(new Block("polished_diorite_slab", builder() + public static final Block POLISHED_DIORITE_SLAB = register(new Block("polished_diorite_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block MOSSY_COBBLESTONE_SLAB = register(new Block("mossy_cobblestone_slab", builder() + public static final Block MOSSY_COBBLESTONE_SLAB = register(new Block("mossy_cobblestone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block END_STONE_BRICK_SLAB = register(new Block("end_stone_brick_slab", builder() + public static final Block END_STONE_BRICK_SLAB = register(new Block("end_stone_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block SMOOTH_SANDSTONE_SLAB = register(new Block("smooth_sandstone_slab", builder() + public static final Block SMOOTH_SANDSTONE_SLAB = register(new Block("smooth_sandstone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block SMOOTH_QUARTZ_SLAB = register(new Block("smooth_quartz_slab", builder() + public static final Block SMOOTH_QUARTZ_SLAB = register(new Block("smooth_quartz_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block GRANITE_SLAB = register(new Block("granite_slab", builder() + public static final Block GRANITE_SLAB = register(new Block("granite_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block ANDESITE_SLAB = register(new Block("andesite_slab", builder() + public static final Block ANDESITE_SLAB = register(new Block("andesite_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block RED_NETHER_BRICK_SLAB = register(new Block("red_nether_brick_slab", builder() + public static final Block RED_NETHER_BRICK_SLAB = register(new Block("red_nether_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block POLISHED_ANDESITE_SLAB = register(new Block("polished_andesite_slab", builder() + public static final Block POLISHED_ANDESITE_SLAB = register(new Block("polished_andesite_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block DIORITE_SLAB = register(new Block("diorite_slab", builder() + public static final Block DIORITE_SLAB = register(new Block("diorite_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block BRICK_WALL = register(new Block("brick_wall", builder() + public static final Block BRICK_WALL = register(new Block("brick_wall", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(EAST_WALL, "none", "low", "tall") .enumState(NORTH_WALL, "none", "low", "tall") .enumState(SOUTH_WALL, "none", "low", "tall") .booleanState(UP) .booleanState(WATERLOGGED) .enumState(WEST_WALL, "none", "low", "tall"))); - public static final Block PRISMARINE_WALL = register(new Block("prismarine_wall", builder() + public static final Block PRISMARINE_WALL = register(new Block("prismarine_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(EAST_WALL, "none", "low", "tall") .enumState(NORTH_WALL, "none", "low", "tall") .enumState(SOUTH_WALL, "none", "low", "tall") .booleanState(UP) .booleanState(WATERLOGGED) .enumState(WEST_WALL, "none", "low", "tall"))); - public static final Block RED_SANDSTONE_WALL = register(new Block("red_sandstone_wall", builder() + public static final Block RED_SANDSTONE_WALL = register(new Block("red_sandstone_wall", builder().requiresCorrectToolForDrops().destroyTime(0.8f) .enumState(EAST_WALL, "none", "low", "tall") .enumState(NORTH_WALL, "none", "low", "tall") .enumState(SOUTH_WALL, "none", "low", "tall") .booleanState(UP) .booleanState(WATERLOGGED) .enumState(WEST_WALL, "none", "low", "tall"))); - public static final Block MOSSY_STONE_BRICK_WALL = register(new Block("mossy_stone_brick_wall", builder() + public static final Block MOSSY_STONE_BRICK_WALL = register(new Block("mossy_stone_brick_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(EAST_WALL, "none", "low", "tall") .enumState(NORTH_WALL, "none", "low", "tall") .enumState(SOUTH_WALL, "none", "low", "tall") .booleanState(UP) .booleanState(WATERLOGGED) .enumState(WEST_WALL, "none", "low", "tall"))); - public static final Block GRANITE_WALL = register(new Block("granite_wall", builder() + public static final Block GRANITE_WALL = register(new Block("granite_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(EAST_WALL, "none", "low", "tall") .enumState(NORTH_WALL, "none", "low", "tall") .enumState(SOUTH_WALL, "none", "low", "tall") .booleanState(UP) .booleanState(WATERLOGGED) .enumState(WEST_WALL, "none", "low", "tall"))); - public static final Block STONE_BRICK_WALL = register(new Block("stone_brick_wall", builder() + public static final Block STONE_BRICK_WALL = register(new Block("stone_brick_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(EAST_WALL, "none", "low", "tall") .enumState(NORTH_WALL, "none", "low", "tall") .enumState(SOUTH_WALL, "none", "low", "tall") .booleanState(UP) .booleanState(WATERLOGGED) .enumState(WEST_WALL, "none", "low", "tall"))); - public static final Block MUD_BRICK_WALL = register(new Block("mud_brick_wall", builder() + public static final Block MUD_BRICK_WALL = register(new Block("mud_brick_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(EAST_WALL, "none", "low", "tall") .enumState(NORTH_WALL, "none", "low", "tall") .enumState(SOUTH_WALL, "none", "low", "tall") .booleanState(UP) .booleanState(WATERLOGGED) .enumState(WEST_WALL, "none", "low", "tall"))); - public static final Block NETHER_BRICK_WALL = register(new Block("nether_brick_wall", builder() + public static final Block NETHER_BRICK_WALL = register(new Block("nether_brick_wall", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(EAST_WALL, "none", "low", "tall") .enumState(NORTH_WALL, "none", "low", "tall") .enumState(SOUTH_WALL, "none", "low", "tall") .booleanState(UP) .booleanState(WATERLOGGED) .enumState(WEST_WALL, "none", "low", "tall"))); - public static final Block ANDESITE_WALL = register(new Block("andesite_wall", builder() + public static final Block ANDESITE_WALL = register(new Block("andesite_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(EAST_WALL, "none", "low", "tall") .enumState(NORTH_WALL, "none", "low", "tall") .enumState(SOUTH_WALL, "none", "low", "tall") .booleanState(UP) .booleanState(WATERLOGGED) .enumState(WEST_WALL, "none", "low", "tall"))); - public static final Block RED_NETHER_BRICK_WALL = register(new Block("red_nether_brick_wall", builder() + public static final Block RED_NETHER_BRICK_WALL = register(new Block("red_nether_brick_wall", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(EAST_WALL, "none", "low", "tall") .enumState(NORTH_WALL, "none", "low", "tall") .enumState(SOUTH_WALL, "none", "low", "tall") .booleanState(UP) .booleanState(WATERLOGGED) .enumState(WEST_WALL, "none", "low", "tall"))); - public static final Block SANDSTONE_WALL = register(new Block("sandstone_wall", builder() + public static final Block SANDSTONE_WALL = register(new Block("sandstone_wall", builder().requiresCorrectToolForDrops().destroyTime(0.8f) .enumState(EAST_WALL, "none", "low", "tall") .enumState(NORTH_WALL, "none", "low", "tall") .enumState(SOUTH_WALL, "none", "low", "tall") .booleanState(UP) .booleanState(WATERLOGGED) .enumState(WEST_WALL, "none", "low", "tall"))); - public static final Block END_STONE_BRICK_WALL = register(new Block("end_stone_brick_wall", builder() + public static final Block END_STONE_BRICK_WALL = register(new Block("end_stone_brick_wall", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(EAST_WALL, "none", "low", "tall") .enumState(NORTH_WALL, "none", "low", "tall") .enumState(SOUTH_WALL, "none", "low", "tall") .booleanState(UP) .booleanState(WATERLOGGED) .enumState(WEST_WALL, "none", "low", "tall"))); - public static final Block DIORITE_WALL = register(new Block("diorite_wall", builder() + public static final Block DIORITE_WALL = register(new Block("diorite_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(EAST_WALL, "none", "low", "tall") .enumState(NORTH_WALL, "none", "low", "tall") .enumState(SOUTH_WALL, "none", "low", "tall") @@ -2001,75 +2001,75 @@ public final class Blocks { .booleanState(BOTTOM) .intState(STABILITY_DISTANCE, 0, 7) .booleanState(WATERLOGGED))); - public static final Block LOOM = register(new Block("loom", builder() + public static final Block LOOM = register(new Block("loom", builder().destroyTime(2.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block BARREL = register(new Block("barrel", builder() + public static final Block BARREL = register(new Block("barrel", builder().setBlockEntity().destroyTime(2.5f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) .booleanState(OPEN))); - public static final Block SMOKER = register(new Block("smoker", builder() + public static final Block SMOKER = register(new Block("smoker", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(LIT))); - public static final Block BLAST_FURNACE = register(new Block("blast_furnace", builder() + public static final Block BLAST_FURNACE = register(new Block("blast_furnace", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(LIT))); - public static final Block CARTOGRAPHY_TABLE = register(new Block("cartography_table", builder())); - public static final Block FLETCHING_TABLE = register(new Block("fletching_table", builder())); - public static final Block GRINDSTONE = register(new Block("grindstone", builder() + public static final Block CARTOGRAPHY_TABLE = register(new Block("cartography_table", builder().destroyTime(2.5f))); + public static final Block FLETCHING_TABLE = register(new Block("fletching_table", builder().destroyTime(2.5f))); + public static final Block GRINDSTONE = register(new Block("grindstone", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block LECTERN = register(new Block("lectern", builder() + public static final Block LECTERN = register(new Block("lectern", builder().setBlockEntity().destroyTime(2.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(HAS_BOOK) .booleanState(POWERED))); - public static final Block SMITHING_TABLE = register(new Block("smithing_table", builder())); - public static final Block STONECUTTER = register(new Block("stonecutter", builder() + public static final Block SMITHING_TABLE = register(new Block("smithing_table", builder().destroyTime(2.5f))); + public static final Block STONECUTTER = register(new Block("stonecutter", builder().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block BELL = register(new Block("bell", builder() + public static final Block BELL = register(new Block("bell", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(5.0f) .enumState(BELL_ATTACHMENT, "floor", "ceiling", "single_wall", "double_wall") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block LANTERN = register(new Block("lantern", builder() + public static final Block LANTERN = register(new Block("lantern", builder().requiresCorrectToolForDrops().destroyTime(3.5f) .booleanState(HANGING) .booleanState(WATERLOGGED))); - public static final Block SOUL_LANTERN = register(new Block("soul_lantern", builder() + public static final Block SOUL_LANTERN = register(new Block("soul_lantern", builder().requiresCorrectToolForDrops().destroyTime(3.5f) .booleanState(HANGING) .booleanState(WATERLOGGED))); - public static final Block CAMPFIRE = register(new Block("campfire", builder() + public static final Block CAMPFIRE = register(new Block("campfire", builder().setBlockEntity().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(LIT) .booleanState(SIGNAL_FIRE) .booleanState(WATERLOGGED))); - public static final Block SOUL_CAMPFIRE = register(new Block("soul_campfire", builder() + public static final Block SOUL_CAMPFIRE = register(new Block("soul_campfire", builder().setBlockEntity().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(LIT) .booleanState(SIGNAL_FIRE) .booleanState(WATERLOGGED))); public static final Block SWEET_BERRY_BUSH = register(new Block("sweet_berry_bush", builder() .intState(AGE_3, 0, 3))); - public static final Block WARPED_STEM = register(new Block("warped_stem", builder() + public static final Block WARPED_STEM = register(new Block("warped_stem", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block STRIPPED_WARPED_STEM = register(new Block("stripped_warped_stem", builder() + public static final Block STRIPPED_WARPED_STEM = register(new Block("stripped_warped_stem", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block WARPED_HYPHAE = register(new Block("warped_hyphae", builder() + public static final Block WARPED_HYPHAE = register(new Block("warped_hyphae", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block STRIPPED_WARPED_HYPHAE = register(new Block("stripped_warped_hyphae", builder() + public static final Block STRIPPED_WARPED_HYPHAE = register(new Block("stripped_warped_hyphae", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block WARPED_NYLIUM = register(new Block("warped_nylium", builder())); + public static final Block WARPED_NYLIUM = register(new Block("warped_nylium", builder().requiresCorrectToolForDrops().destroyTime(0.4f))); public static final Block WARPED_FUNGUS = register(new Block("warped_fungus", builder())); - public static final Block WARPED_WART_BLOCK = register(new Block("warped_wart_block", builder())); + public static final Block WARPED_WART_BLOCK = register(new Block("warped_wart_block", builder().destroyTime(1.0f))); public static final Block WARPED_ROOTS = register(new Block("warped_roots", builder())); public static final Block NETHER_SPROUTS = register(new Block("nether_sprouts", builder())); - public static final Block CRIMSON_STEM = register(new Block("crimson_stem", builder() + public static final Block CRIMSON_STEM = register(new Block("crimson_stem", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block STRIPPED_CRIMSON_STEM = register(new Block("stripped_crimson_stem", builder() + public static final Block STRIPPED_CRIMSON_STEM = register(new Block("stripped_crimson_stem", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block CRIMSON_HYPHAE = register(new Block("crimson_hyphae", builder() + public static final Block CRIMSON_HYPHAE = register(new Block("crimson_hyphae", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block STRIPPED_CRIMSON_HYPHAE = register(new Block("stripped_crimson_hyphae", builder() + public static final Block STRIPPED_CRIMSON_HYPHAE = register(new Block("stripped_crimson_hyphae", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block CRIMSON_NYLIUM = register(new Block("crimson_nylium", builder())); + public static final Block CRIMSON_NYLIUM = register(new Block("crimson_nylium", builder().requiresCorrectToolForDrops().destroyTime(0.4f))); public static final Block CRIMSON_FUNGUS = register(new Block("crimson_fungus", builder())); - public static final Block SHROOMLIGHT = register(new Block("shroomlight", builder())); + public static final Block SHROOMLIGHT = register(new Block("shroomlight", builder().destroyTime(1.0f))); public static final Block WEEPING_VINES = register(new Block("weeping_vines", builder() .intState(AGE_25, 0, 25))); public static final Block WEEPING_VINES_PLANT = register(new Block("weeping_vines_plant", builder())); @@ -2077,360 +2077,360 @@ public final class Blocks { .intState(AGE_25, 0, 25))); public static final Block TWISTING_VINES_PLANT = register(new Block("twisting_vines_plant", builder())); public static final Block CRIMSON_ROOTS = register(new Block("crimson_roots", builder())); - public static final Block CRIMSON_PLANKS = register(new Block("crimson_planks", builder())); - public static final Block WARPED_PLANKS = register(new Block("warped_planks", builder())); - public static final Block CRIMSON_SLAB = register(new Block("crimson_slab", builder() + public static final Block CRIMSON_PLANKS = register(new Block("crimson_planks", builder().destroyTime(2.0f))); + public static final Block WARPED_PLANKS = register(new Block("warped_planks", builder().destroyTime(2.0f))); + public static final Block CRIMSON_SLAB = register(new Block("crimson_slab", builder().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block WARPED_SLAB = register(new Block("warped_slab", builder() + public static final Block WARPED_SLAB = register(new Block("warped_slab", builder().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block CRIMSON_PRESSURE_PLATE = register(new Block("crimson_pressure_plate", builder() + public static final Block CRIMSON_PRESSURE_PLATE = register(new Block("crimson_pressure_plate", builder().destroyTime(0.5f) .booleanState(POWERED))); - public static final Block WARPED_PRESSURE_PLATE = register(new Block("warped_pressure_plate", builder() + public static final Block WARPED_PRESSURE_PLATE = register(new Block("warped_pressure_plate", builder().destroyTime(0.5f) .booleanState(POWERED))); - public static final Block CRIMSON_FENCE = register(new Block("crimson_fence", builder() + public static final Block CRIMSON_FENCE = register(new Block("crimson_fence", builder().destroyTime(2.0f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block WARPED_FENCE = register(new Block("warped_fence", builder() + public static final Block WARPED_FENCE = register(new Block("warped_fence", builder().destroyTime(2.0f) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block CRIMSON_TRAPDOOR = register(new Block("crimson_trapdoor", builder() + public static final Block CRIMSON_TRAPDOOR = register(new Block("crimson_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block WARPED_TRAPDOOR = register(new Block("warped_trapdoor", builder() + public static final Block WARPED_TRAPDOOR = register(new Block("warped_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block CRIMSON_FENCE_GATE = register(new Block("crimson_fence_gate", builder() + public static final Block CRIMSON_FENCE_GATE = register(new Block("crimson_fence_gate", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(IN_WALL) .booleanState(OPEN) .booleanState(POWERED))); - public static final Block WARPED_FENCE_GATE = register(new Block("warped_fence_gate", builder() + public static final Block WARPED_FENCE_GATE = register(new Block("warped_fence_gate", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(IN_WALL) .booleanState(OPEN) .booleanState(POWERED))); - public static final Block CRIMSON_STAIRS = register(new Block("crimson_stairs", builder() + public static final Block CRIMSON_STAIRS = register(new Block("crimson_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block WARPED_STAIRS = register(new Block("warped_stairs", builder() + public static final Block WARPED_STAIRS = register(new Block("warped_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block CRIMSON_BUTTON = register(new Block("crimson_button", builder() + public static final Block CRIMSON_BUTTON = register(new Block("crimson_button", builder().destroyTime(0.5f) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block WARPED_BUTTON = register(new Block("warped_button", builder() + public static final Block WARPED_BUTTON = register(new Block("warped_button", builder().destroyTime(0.5f) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block CRIMSON_DOOR = register(new Block("crimson_door", builder() + public static final Block CRIMSON_DOOR = register(new Block("crimson_door", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block WARPED_DOOR = register(new Block("warped_door", builder() + public static final Block WARPED_DOOR = register(new Block("warped_door", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block CRIMSON_SIGN = register(new Block("crimson_sign", builder() + public static final Block CRIMSON_SIGN = register(new Block("crimson_sign", builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15) .booleanState(WATERLOGGED))); - public static final Block WARPED_SIGN = register(new Block("warped_sign", builder() + public static final Block WARPED_SIGN = register(new Block("warped_sign", builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15) .booleanState(WATERLOGGED))); - public static final Block CRIMSON_WALL_SIGN = register(new Block("crimson_wall_sign", builder() + public static final Block CRIMSON_WALL_SIGN = register(new Block("crimson_wall_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block WARPED_WALL_SIGN = register(new Block("warped_wall_sign", builder() + public static final Block WARPED_WALL_SIGN = register(new Block("warped_wall_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block STRUCTURE_BLOCK = register(new Block("structure_block", builder() + public static final Block STRUCTURE_BLOCK = register(new Block("structure_block", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(-1.0f) .enumState(STRUCTUREBLOCK_MODE, "save", "load", "corner", "data"))); - public static final Block JIGSAW = register(new Block("jigsaw", builder() + public static final Block JIGSAW = register(new Block("jigsaw", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(-1.0f) .enumState(ORIENTATION, "down_east", "down_north", "down_south", "down_west", "up_east", "up_north", "up_south", "up_west", "west_up", "east_up", "north_up", "south_up"))); - public static final Block COMPOSTER = register(new Block("composter", builder() + public static final Block COMPOSTER = register(new Block("composter", builder().destroyTime(0.6f) .intState(LEVEL_COMPOSTER, 0, 8))); - public static final Block TARGET = register(new Block("target", builder() + public static final Block TARGET = register(new Block("target", builder().destroyTime(0.5f) .intState(POWER, 0, 15))); - public static final Block BEE_NEST = register(new Block("bee_nest", builder() + public static final Block BEE_NEST = register(new Block("bee_nest", builder().setBlockEntity().destroyTime(0.3f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .intState(LEVEL_HONEY, 0, 5))); - public static final Block BEEHIVE = register(new Block("beehive", builder() + public static final Block BEEHIVE = register(new Block("beehive", builder().setBlockEntity().destroyTime(0.6f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .intState(LEVEL_HONEY, 0, 5))); public static final Block HONEY_BLOCK = register(new Block("honey_block", builder())); - public static final Block HONEYCOMB_BLOCK = register(new Block("honeycomb_block", builder())); - public static final Block NETHERITE_BLOCK = register(new Block("netherite_block", builder())); - public static final Block ANCIENT_DEBRIS = register(new Block("ancient_debris", builder())); - public static final Block CRYING_OBSIDIAN = register(new Block("crying_obsidian", builder())); - public static final Block RESPAWN_ANCHOR = register(new Block("respawn_anchor", builder() + public static final Block HONEYCOMB_BLOCK = register(new Block("honeycomb_block", builder().destroyTime(0.6f))); + public static final Block NETHERITE_BLOCK = register(new Block("netherite_block", builder().requiresCorrectToolForDrops().destroyTime(50.0f))); + public static final Block ANCIENT_DEBRIS = register(new Block("ancient_debris", builder().requiresCorrectToolForDrops().destroyTime(30.0f))); + public static final Block CRYING_OBSIDIAN = register(new Block("crying_obsidian", builder().requiresCorrectToolForDrops().destroyTime(50.0f))); + public static final Block RESPAWN_ANCHOR = register(new Block("respawn_anchor", builder().requiresCorrectToolForDrops().destroyTime(50.0f) .intState(RESPAWN_ANCHOR_CHARGES, 0, 4))); public static final Block POTTED_CRIMSON_FUNGUS = register(new Block("potted_crimson_fungus", builder())); public static final Block POTTED_WARPED_FUNGUS = register(new Block("potted_warped_fungus", builder())); public static final Block POTTED_CRIMSON_ROOTS = register(new Block("potted_crimson_roots", builder())); public static final Block POTTED_WARPED_ROOTS = register(new Block("potted_warped_roots", builder())); - public static final Block LODESTONE = register(new Block("lodestone", builder())); - public static final Block BLACKSTONE = register(new Block("blackstone", builder())); - public static final Block BLACKSTONE_STAIRS = register(new Block("blackstone_stairs", builder() + public static final Block LODESTONE = register(new Block("lodestone", builder().requiresCorrectToolForDrops().destroyTime(3.5f))); + public static final Block BLACKSTONE = register(new Block("blackstone", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block BLACKSTONE_STAIRS = register(new Block("blackstone_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block BLACKSTONE_WALL = register(new Block("blackstone_wall", builder() + public static final Block BLACKSTONE_WALL = register(new Block("blackstone_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(EAST_WALL, "none", "low", "tall") .enumState(NORTH_WALL, "none", "low", "tall") .enumState(SOUTH_WALL, "none", "low", "tall") .booleanState(UP) .booleanState(WATERLOGGED) .enumState(WEST_WALL, "none", "low", "tall"))); - public static final Block BLACKSTONE_SLAB = register(new Block("blackstone_slab", builder() + public static final Block BLACKSTONE_SLAB = register(new Block("blackstone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block POLISHED_BLACKSTONE = register(new Block("polished_blackstone", builder())); - public static final Block POLISHED_BLACKSTONE_BRICKS = register(new Block("polished_blackstone_bricks", builder())); - public static final Block CRACKED_POLISHED_BLACKSTONE_BRICKS = register(new Block("cracked_polished_blackstone_bricks", builder())); - public static final Block CHISELED_POLISHED_BLACKSTONE = register(new Block("chiseled_polished_blackstone", builder())); - public static final Block POLISHED_BLACKSTONE_BRICK_SLAB = register(new Block("polished_blackstone_brick_slab", builder() + public static final Block POLISHED_BLACKSTONE = register(new Block("polished_blackstone", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); + public static final Block POLISHED_BLACKSTONE_BRICKS = register(new Block("polished_blackstone_bricks", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block CRACKED_POLISHED_BLACKSTONE_BRICKS = register(new Block("cracked_polished_blackstone_bricks", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block CHISELED_POLISHED_BLACKSTONE = register(new Block("chiseled_polished_blackstone", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block POLISHED_BLACKSTONE_BRICK_SLAB = register(new Block("polished_blackstone_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block POLISHED_BLACKSTONE_BRICK_STAIRS = register(new Block("polished_blackstone_brick_stairs", builder() + public static final Block POLISHED_BLACKSTONE_BRICK_STAIRS = register(new Block("polished_blackstone_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block POLISHED_BLACKSTONE_BRICK_WALL = register(new Block("polished_blackstone_brick_wall", builder() + public static final Block POLISHED_BLACKSTONE_BRICK_WALL = register(new Block("polished_blackstone_brick_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(EAST_WALL, "none", "low", "tall") .enumState(NORTH_WALL, "none", "low", "tall") .enumState(SOUTH_WALL, "none", "low", "tall") .booleanState(UP) .booleanState(WATERLOGGED) .enumState(WEST_WALL, "none", "low", "tall"))); - public static final Block GILDED_BLACKSTONE = register(new Block("gilded_blackstone", builder())); - public static final Block POLISHED_BLACKSTONE_STAIRS = register(new Block("polished_blackstone_stairs", builder() + public static final Block GILDED_BLACKSTONE = register(new Block("gilded_blackstone", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block POLISHED_BLACKSTONE_STAIRS = register(new Block("polished_blackstone_stairs", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block POLISHED_BLACKSTONE_SLAB = register(new Block("polished_blackstone_slab", builder() + public static final Block POLISHED_BLACKSTONE_SLAB = register(new Block("polished_blackstone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block POLISHED_BLACKSTONE_PRESSURE_PLATE = register(new Block("polished_blackstone_pressure_plate", builder() + public static final Block POLISHED_BLACKSTONE_PRESSURE_PLATE = register(new Block("polished_blackstone_pressure_plate", builder().requiresCorrectToolForDrops().destroyTime(0.5f) .booleanState(POWERED))); - public static final Block POLISHED_BLACKSTONE_BUTTON = register(new Block("polished_blackstone_button", builder() + public static final Block POLISHED_BLACKSTONE_BUTTON = register(new Block("polished_blackstone_button", builder().destroyTime(0.5f) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block POLISHED_BLACKSTONE_WALL = register(new Block("polished_blackstone_wall", builder() + public static final Block POLISHED_BLACKSTONE_WALL = register(new Block("polished_blackstone_wall", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(EAST_WALL, "none", "low", "tall") .enumState(NORTH_WALL, "none", "low", "tall") .enumState(SOUTH_WALL, "none", "low", "tall") .booleanState(UP) .booleanState(WATERLOGGED) .enumState(WEST_WALL, "none", "low", "tall"))); - public static final Block CHISELED_NETHER_BRICKS = register(new Block("chiseled_nether_bricks", builder())); - public static final Block CRACKED_NETHER_BRICKS = register(new Block("cracked_nether_bricks", builder())); - public static final Block QUARTZ_BRICKS = register(new Block("quartz_bricks", builder())); - public static final Block CANDLE = register(new Block("candle", builder() + public static final Block CHISELED_NETHER_BRICKS = register(new Block("chiseled_nether_bricks", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); + public static final Block CRACKED_NETHER_BRICKS = register(new Block("cracked_nether_bricks", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); + public static final Block QUARTZ_BRICKS = register(new Block("quartz_bricks", builder().requiresCorrectToolForDrops().destroyTime(0.8f))); + public static final Block CANDLE = register(new Block("candle", builder().destroyTime(0.1f) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block WHITE_CANDLE = register(new Block("white_candle", builder() + public static final Block WHITE_CANDLE = register(new Block("white_candle", builder().destroyTime(0.1f) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block ORANGE_CANDLE = register(new Block("orange_candle", builder() + public static final Block ORANGE_CANDLE = register(new Block("orange_candle", builder().destroyTime(0.1f) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block MAGENTA_CANDLE = register(new Block("magenta_candle", builder() + public static final Block MAGENTA_CANDLE = register(new Block("magenta_candle", builder().destroyTime(0.1f) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block LIGHT_BLUE_CANDLE = register(new Block("light_blue_candle", builder() + public static final Block LIGHT_BLUE_CANDLE = register(new Block("light_blue_candle", builder().destroyTime(0.1f) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block YELLOW_CANDLE = register(new Block("yellow_candle", builder() + public static final Block YELLOW_CANDLE = register(new Block("yellow_candle", builder().destroyTime(0.1f) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block LIME_CANDLE = register(new Block("lime_candle", builder() + public static final Block LIME_CANDLE = register(new Block("lime_candle", builder().destroyTime(0.1f) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block PINK_CANDLE = register(new Block("pink_candle", builder() + public static final Block PINK_CANDLE = register(new Block("pink_candle", builder().destroyTime(0.1f) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block GRAY_CANDLE = register(new Block("gray_candle", builder() + public static final Block GRAY_CANDLE = register(new Block("gray_candle", builder().destroyTime(0.1f) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block LIGHT_GRAY_CANDLE = register(new Block("light_gray_candle", builder() + public static final Block LIGHT_GRAY_CANDLE = register(new Block("light_gray_candle", builder().destroyTime(0.1f) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block CYAN_CANDLE = register(new Block("cyan_candle", builder() + public static final Block CYAN_CANDLE = register(new Block("cyan_candle", builder().destroyTime(0.1f) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block PURPLE_CANDLE = register(new Block("purple_candle", builder() + public static final Block PURPLE_CANDLE = register(new Block("purple_candle", builder().destroyTime(0.1f) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block BLUE_CANDLE = register(new Block("blue_candle", builder() + public static final Block BLUE_CANDLE = register(new Block("blue_candle", builder().destroyTime(0.1f) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block BROWN_CANDLE = register(new Block("brown_candle", builder() + public static final Block BROWN_CANDLE = register(new Block("brown_candle", builder().destroyTime(0.1f) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block GREEN_CANDLE = register(new Block("green_candle", builder() + public static final Block GREEN_CANDLE = register(new Block("green_candle", builder().destroyTime(0.1f) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block RED_CANDLE = register(new Block("red_candle", builder() + public static final Block RED_CANDLE = register(new Block("red_candle", builder().destroyTime(0.1f) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block BLACK_CANDLE = register(new Block("black_candle", builder() + public static final Block BLACK_CANDLE = register(new Block("black_candle", builder().destroyTime(0.1f) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block CANDLE_CAKE = register(new Block("candle_cake", builder() + public static final Block CANDLE_CAKE = register(new Block("candle_cake", builder().destroyTime(0.5f) .booleanState(LIT))); - public static final Block WHITE_CANDLE_CAKE = register(new Block("white_candle_cake", builder() + public static final Block WHITE_CANDLE_CAKE = register(new Block("white_candle_cake", builder().destroyTime(0.5f) .booleanState(LIT))); - public static final Block ORANGE_CANDLE_CAKE = register(new Block("orange_candle_cake", builder() + public static final Block ORANGE_CANDLE_CAKE = register(new Block("orange_candle_cake", builder().destroyTime(0.5f) .booleanState(LIT))); - public static final Block MAGENTA_CANDLE_CAKE = register(new Block("magenta_candle_cake", builder() + public static final Block MAGENTA_CANDLE_CAKE = register(new Block("magenta_candle_cake", builder().destroyTime(0.5f) .booleanState(LIT))); - public static final Block LIGHT_BLUE_CANDLE_CAKE = register(new Block("light_blue_candle_cake", builder() + public static final Block LIGHT_BLUE_CANDLE_CAKE = register(new Block("light_blue_candle_cake", builder().destroyTime(0.5f) .booleanState(LIT))); - public static final Block YELLOW_CANDLE_CAKE = register(new Block("yellow_candle_cake", builder() + public static final Block YELLOW_CANDLE_CAKE = register(new Block("yellow_candle_cake", builder().destroyTime(0.5f) .booleanState(LIT))); - public static final Block LIME_CANDLE_CAKE = register(new Block("lime_candle_cake", builder() + public static final Block LIME_CANDLE_CAKE = register(new Block("lime_candle_cake", builder().destroyTime(0.5f) .booleanState(LIT))); - public static final Block PINK_CANDLE_CAKE = register(new Block("pink_candle_cake", builder() + public static final Block PINK_CANDLE_CAKE = register(new Block("pink_candle_cake", builder().destroyTime(0.5f) .booleanState(LIT))); - public static final Block GRAY_CANDLE_CAKE = register(new Block("gray_candle_cake", builder() + public static final Block GRAY_CANDLE_CAKE = register(new Block("gray_candle_cake", builder().destroyTime(0.5f) .booleanState(LIT))); - public static final Block LIGHT_GRAY_CANDLE_CAKE = register(new Block("light_gray_candle_cake", builder() + public static final Block LIGHT_GRAY_CANDLE_CAKE = register(new Block("light_gray_candle_cake", builder().destroyTime(0.5f) .booleanState(LIT))); - public static final Block CYAN_CANDLE_CAKE = register(new Block("cyan_candle_cake", builder() + public static final Block CYAN_CANDLE_CAKE = register(new Block("cyan_candle_cake", builder().destroyTime(0.5f) .booleanState(LIT))); - public static final Block PURPLE_CANDLE_CAKE = register(new Block("purple_candle_cake", builder() + public static final Block PURPLE_CANDLE_CAKE = register(new Block("purple_candle_cake", builder().destroyTime(0.5f) .booleanState(LIT))); - public static final Block BLUE_CANDLE_CAKE = register(new Block("blue_candle_cake", builder() + public static final Block BLUE_CANDLE_CAKE = register(new Block("blue_candle_cake", builder().destroyTime(0.5f) .booleanState(LIT))); - public static final Block BROWN_CANDLE_CAKE = register(new Block("brown_candle_cake", builder() + public static final Block BROWN_CANDLE_CAKE = register(new Block("brown_candle_cake", builder().destroyTime(0.5f) .booleanState(LIT))); - public static final Block GREEN_CANDLE_CAKE = register(new Block("green_candle_cake", builder() + public static final Block GREEN_CANDLE_CAKE = register(new Block("green_candle_cake", builder().destroyTime(0.5f) .booleanState(LIT))); - public static final Block RED_CANDLE_CAKE = register(new Block("red_candle_cake", builder() + public static final Block RED_CANDLE_CAKE = register(new Block("red_candle_cake", builder().destroyTime(0.5f) .booleanState(LIT))); - public static final Block BLACK_CANDLE_CAKE = register(new Block("black_candle_cake", builder() + public static final Block BLACK_CANDLE_CAKE = register(new Block("black_candle_cake", builder().destroyTime(0.5f) .booleanState(LIT))); - public static final Block AMETHYST_BLOCK = register(new Block("amethyst_block", builder())); - public static final Block BUDDING_AMETHYST = register(new Block("budding_amethyst", builder())); - public static final Block AMETHYST_CLUSTER = register(new Block("amethyst_cluster", builder() + public static final Block AMETHYST_BLOCK = register(new Block("amethyst_block", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block BUDDING_AMETHYST = register(new Block("budding_amethyst", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block AMETHYST_CLUSTER = register(new Block("amethyst_cluster", builder().destroyTime(1.5f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) .booleanState(WATERLOGGED))); - public static final Block LARGE_AMETHYST_BUD = register(new Block("large_amethyst_bud", builder() + public static final Block LARGE_AMETHYST_BUD = register(new Block("large_amethyst_bud", builder().destroyTime(1.5f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) .booleanState(WATERLOGGED))); - public static final Block MEDIUM_AMETHYST_BUD = register(new Block("medium_amethyst_bud", builder() + public static final Block MEDIUM_AMETHYST_BUD = register(new Block("medium_amethyst_bud", builder().destroyTime(1.5f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) .booleanState(WATERLOGGED))); - public static final Block SMALL_AMETHYST_BUD = register(new Block("small_amethyst_bud", builder() + public static final Block SMALL_AMETHYST_BUD = register(new Block("small_amethyst_bud", builder().destroyTime(1.5f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) .booleanState(WATERLOGGED))); - public static final Block TUFF = register(new Block("tuff", builder())); - public static final Block TUFF_SLAB = register(new Block("tuff_slab", builder() + public static final Block TUFF = register(new Block("tuff", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block TUFF_SLAB = register(new Block("tuff_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block TUFF_STAIRS = register(new Block("tuff_stairs", builder() + public static final Block TUFF_STAIRS = register(new Block("tuff_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block TUFF_WALL = register(new Block("tuff_wall", builder() + public static final Block TUFF_WALL = register(new Block("tuff_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(EAST_WALL, "none", "low", "tall") .enumState(NORTH_WALL, "none", "low", "tall") .enumState(SOUTH_WALL, "none", "low", "tall") .booleanState(UP) .booleanState(WATERLOGGED) .enumState(WEST_WALL, "none", "low", "tall"))); - public static final Block POLISHED_TUFF = register(new Block("polished_tuff", builder())); - public static final Block POLISHED_TUFF_SLAB = register(new Block("polished_tuff_slab", builder() + public static final Block POLISHED_TUFF = register(new Block("polished_tuff", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block POLISHED_TUFF_SLAB = register(new Block("polished_tuff_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block POLISHED_TUFF_STAIRS = register(new Block("polished_tuff_stairs", builder() + public static final Block POLISHED_TUFF_STAIRS = register(new Block("polished_tuff_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block POLISHED_TUFF_WALL = register(new Block("polished_tuff_wall", builder() + public static final Block POLISHED_TUFF_WALL = register(new Block("polished_tuff_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(EAST_WALL, "none", "low", "tall") .enumState(NORTH_WALL, "none", "low", "tall") .enumState(SOUTH_WALL, "none", "low", "tall") .booleanState(UP) .booleanState(WATERLOGGED) .enumState(WEST_WALL, "none", "low", "tall"))); - public static final Block CHISELED_TUFF = register(new Block("chiseled_tuff", builder())); - public static final Block TUFF_BRICKS = register(new Block("tuff_bricks", builder())); - public static final Block TUFF_BRICK_SLAB = register(new Block("tuff_brick_slab", builder() + public static final Block CHISELED_TUFF = register(new Block("chiseled_tuff", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block TUFF_BRICKS = register(new Block("tuff_bricks", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block TUFF_BRICK_SLAB = register(new Block("tuff_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block TUFF_BRICK_STAIRS = register(new Block("tuff_brick_stairs", builder() + public static final Block TUFF_BRICK_STAIRS = register(new Block("tuff_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block TUFF_BRICK_WALL = register(new Block("tuff_brick_wall", builder() + public static final Block TUFF_BRICK_WALL = register(new Block("tuff_brick_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(EAST_WALL, "none", "low", "tall") .enumState(NORTH_WALL, "none", "low", "tall") .enumState(SOUTH_WALL, "none", "low", "tall") .booleanState(UP) .booleanState(WATERLOGGED) .enumState(WEST_WALL, "none", "low", "tall"))); - public static final Block CHISELED_TUFF_BRICKS = register(new Block("chiseled_tuff_bricks", builder())); - public static final Block CALCITE = register(new Block("calcite", builder())); - public static final Block TINTED_GLASS = register(new Block("tinted_glass", builder())); - public static final Block POWDER_SNOW = register(new Block("powder_snow", builder())); - public static final Block SCULK_SENSOR = register(new Block("sculk_sensor", builder() + public static final Block CHISELED_TUFF_BRICKS = register(new Block("chiseled_tuff_bricks", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); + public static final Block CALCITE = register(new Block("calcite", builder().requiresCorrectToolForDrops().destroyTime(0.75f))); + public static final Block TINTED_GLASS = register(new Block("tinted_glass", builder().destroyTime(0.3f))); + public static final Block POWDER_SNOW = register(new Block("powder_snow", builder().destroyTime(0.25f))); + public static final Block SCULK_SENSOR = register(new Block("sculk_sensor", builder().setBlockEntity().destroyTime(1.5f) .intState(POWER, 0, 15) .enumState(SCULK_SENSOR_PHASE, "inactive", "active", "cooldown") .booleanState(WATERLOGGED))); - public static final Block CALIBRATED_SCULK_SENSOR = register(new Block("calibrated_sculk_sensor", builder() + public static final Block CALIBRATED_SCULK_SENSOR = register(new Block("calibrated_sculk_sensor", builder().setBlockEntity().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .intState(POWER, 0, 15) .enumState(SCULK_SENSOR_PHASE, "inactive", "active", "cooldown") .booleanState(WATERLOGGED))); - public static final Block SCULK = register(new Block("sculk", builder())); - public static final Block SCULK_VEIN = register(new Block("sculk_vein", builder() + public static final Block SCULK = register(new Block("sculk", builder().destroyTime(0.2f))); + public static final Block SCULK_VEIN = register(new Block("sculk_vein", builder().destroyTime(0.2f) .booleanState(DOWN) .booleanState(EAST) .booleanState(NORTH) @@ -2438,247 +2438,247 @@ public final class Blocks { .booleanState(UP) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block SCULK_CATALYST = register(new Block("sculk_catalyst", builder() + public static final Block SCULK_CATALYST = register(new Block("sculk_catalyst", builder().setBlockEntity().destroyTime(3.0f) .booleanState(BLOOM))); - public static final Block SCULK_SHRIEKER = register(new Block("sculk_shrieker", builder() + public static final Block SCULK_SHRIEKER = register(new Block("sculk_shrieker", builder().setBlockEntity().destroyTime(3.0f) .booleanState(CAN_SUMMON) .booleanState(SHRIEKING) .booleanState(WATERLOGGED))); - public static final Block COPPER_BLOCK = register(new Block("copper_block", builder())); - public static final Block EXPOSED_COPPER = register(new Block("exposed_copper", builder())); - public static final Block WEATHERED_COPPER = register(new Block("weathered_copper", builder())); - public static final Block OXIDIZED_COPPER = register(new Block("oxidized_copper", builder())); - public static final Block COPPER_ORE = register(new Block("copper_ore", builder())); - public static final Block DEEPSLATE_COPPER_ORE = register(new Block("deepslate_copper_ore", builder())); - public static final Block OXIDIZED_CUT_COPPER = register(new Block("oxidized_cut_copper", builder())); - public static final Block WEATHERED_CUT_COPPER = register(new Block("weathered_cut_copper", builder())); - public static final Block EXPOSED_CUT_COPPER = register(new Block("exposed_cut_copper", builder())); - public static final Block CUT_COPPER = register(new Block("cut_copper", builder())); - public static final Block OXIDIZED_CHISELED_COPPER = register(new Block("oxidized_chiseled_copper", builder())); - public static final Block WEATHERED_CHISELED_COPPER = register(new Block("weathered_chiseled_copper", builder())); - public static final Block EXPOSED_CHISELED_COPPER = register(new Block("exposed_chiseled_copper", builder())); - public static final Block CHISELED_COPPER = register(new Block("chiseled_copper", builder())); - public static final Block WAXED_OXIDIZED_CHISELED_COPPER = register(new Block("waxed_oxidized_chiseled_copper", builder())); - public static final Block WAXED_WEATHERED_CHISELED_COPPER = register(new Block("waxed_weathered_chiseled_copper", builder())); - public static final Block WAXED_EXPOSED_CHISELED_COPPER = register(new Block("waxed_exposed_chiseled_copper", builder())); - public static final Block WAXED_CHISELED_COPPER = register(new Block("waxed_chiseled_copper", builder())); - public static final Block OXIDIZED_CUT_COPPER_STAIRS = register(new Block("oxidized_cut_copper_stairs", builder() + public static final Block COPPER_BLOCK = register(new Block("copper_block", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block EXPOSED_COPPER = register(new Block("exposed_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block WEATHERED_COPPER = register(new Block("weathered_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block OXIDIZED_COPPER = register(new Block("oxidized_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block COPPER_ORE = register(new Block("copper_ore", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block DEEPSLATE_COPPER_ORE = register(new Block("deepslate_copper_ore", builder().requiresCorrectToolForDrops().destroyTime(4.5f))); + public static final Block OXIDIZED_CUT_COPPER = register(new Block("oxidized_cut_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block WEATHERED_CUT_COPPER = register(new Block("weathered_cut_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block EXPOSED_CUT_COPPER = register(new Block("exposed_cut_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block CUT_COPPER = register(new Block("cut_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block OXIDIZED_CHISELED_COPPER = register(new Block("oxidized_chiseled_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block WEATHERED_CHISELED_COPPER = register(new Block("weathered_chiseled_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block EXPOSED_CHISELED_COPPER = register(new Block("exposed_chiseled_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block CHISELED_COPPER = register(new Block("chiseled_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block WAXED_OXIDIZED_CHISELED_COPPER = register(new Block("waxed_oxidized_chiseled_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block WAXED_WEATHERED_CHISELED_COPPER = register(new Block("waxed_weathered_chiseled_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block WAXED_EXPOSED_CHISELED_COPPER = register(new Block("waxed_exposed_chiseled_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block WAXED_CHISELED_COPPER = register(new Block("waxed_chiseled_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block OXIDIZED_CUT_COPPER_STAIRS = register(new Block("oxidized_cut_copper_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block WEATHERED_CUT_COPPER_STAIRS = register(new Block("weathered_cut_copper_stairs", builder() + public static final Block WEATHERED_CUT_COPPER_STAIRS = register(new Block("weathered_cut_copper_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block EXPOSED_CUT_COPPER_STAIRS = register(new Block("exposed_cut_copper_stairs", builder() + public static final Block EXPOSED_CUT_COPPER_STAIRS = register(new Block("exposed_cut_copper_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block CUT_COPPER_STAIRS = register(new Block("cut_copper_stairs", builder() + public static final Block CUT_COPPER_STAIRS = register(new Block("cut_copper_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block OXIDIZED_CUT_COPPER_SLAB = register(new Block("oxidized_cut_copper_slab", builder() + public static final Block OXIDIZED_CUT_COPPER_SLAB = register(new Block("oxidized_cut_copper_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block WEATHERED_CUT_COPPER_SLAB = register(new Block("weathered_cut_copper_slab", builder() + public static final Block WEATHERED_CUT_COPPER_SLAB = register(new Block("weathered_cut_copper_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block EXPOSED_CUT_COPPER_SLAB = register(new Block("exposed_cut_copper_slab", builder() + public static final Block EXPOSED_CUT_COPPER_SLAB = register(new Block("exposed_cut_copper_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block CUT_COPPER_SLAB = register(new Block("cut_copper_slab", builder() + public static final Block CUT_COPPER_SLAB = register(new Block("cut_copper_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block WAXED_COPPER_BLOCK = register(new Block("waxed_copper_block", builder())); - public static final Block WAXED_WEATHERED_COPPER = register(new Block("waxed_weathered_copper", builder())); - public static final Block WAXED_EXPOSED_COPPER = register(new Block("waxed_exposed_copper", builder())); - public static final Block WAXED_OXIDIZED_COPPER = register(new Block("waxed_oxidized_copper", builder())); - public static final Block WAXED_OXIDIZED_CUT_COPPER = register(new Block("waxed_oxidized_cut_copper", builder())); - public static final Block WAXED_WEATHERED_CUT_COPPER = register(new Block("waxed_weathered_cut_copper", builder())); - public static final Block WAXED_EXPOSED_CUT_COPPER = register(new Block("waxed_exposed_cut_copper", builder())); - public static final Block WAXED_CUT_COPPER = register(new Block("waxed_cut_copper", builder())); - public static final Block WAXED_OXIDIZED_CUT_COPPER_STAIRS = register(new Block("waxed_oxidized_cut_copper_stairs", builder() + public static final Block WAXED_COPPER_BLOCK = register(new Block("waxed_copper_block", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block WAXED_WEATHERED_COPPER = register(new Block("waxed_weathered_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block WAXED_EXPOSED_COPPER = register(new Block("waxed_exposed_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block WAXED_OXIDIZED_COPPER = register(new Block("waxed_oxidized_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block WAXED_OXIDIZED_CUT_COPPER = register(new Block("waxed_oxidized_cut_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block WAXED_WEATHERED_CUT_COPPER = register(new Block("waxed_weathered_cut_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block WAXED_EXPOSED_CUT_COPPER = register(new Block("waxed_exposed_cut_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block WAXED_CUT_COPPER = register(new Block("waxed_cut_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); + public static final Block WAXED_OXIDIZED_CUT_COPPER_STAIRS = register(new Block("waxed_oxidized_cut_copper_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block WAXED_WEATHERED_CUT_COPPER_STAIRS = register(new Block("waxed_weathered_cut_copper_stairs", builder() + public static final Block WAXED_WEATHERED_CUT_COPPER_STAIRS = register(new Block("waxed_weathered_cut_copper_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block WAXED_EXPOSED_CUT_COPPER_STAIRS = register(new Block("waxed_exposed_cut_copper_stairs", builder() + public static final Block WAXED_EXPOSED_CUT_COPPER_STAIRS = register(new Block("waxed_exposed_cut_copper_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block WAXED_CUT_COPPER_STAIRS = register(new Block("waxed_cut_copper_stairs", builder() + public static final Block WAXED_CUT_COPPER_STAIRS = register(new Block("waxed_cut_copper_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block WAXED_OXIDIZED_CUT_COPPER_SLAB = register(new Block("waxed_oxidized_cut_copper_slab", builder() + public static final Block WAXED_OXIDIZED_CUT_COPPER_SLAB = register(new Block("waxed_oxidized_cut_copper_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block WAXED_WEATHERED_CUT_COPPER_SLAB = register(new Block("waxed_weathered_cut_copper_slab", builder() + public static final Block WAXED_WEATHERED_CUT_COPPER_SLAB = register(new Block("waxed_weathered_cut_copper_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block WAXED_EXPOSED_CUT_COPPER_SLAB = register(new Block("waxed_exposed_cut_copper_slab", builder() + public static final Block WAXED_EXPOSED_CUT_COPPER_SLAB = register(new Block("waxed_exposed_cut_copper_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block WAXED_CUT_COPPER_SLAB = register(new Block("waxed_cut_copper_slab", builder() + public static final Block WAXED_CUT_COPPER_SLAB = register(new Block("waxed_cut_copper_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block COPPER_DOOR = register(new Block("copper_door", builder() + public static final Block COPPER_DOOR = register(new Block("copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block EXPOSED_COPPER_DOOR = register(new Block("exposed_copper_door", builder() + public static final Block EXPOSED_COPPER_DOOR = register(new Block("exposed_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block OXIDIZED_COPPER_DOOR = register(new Block("oxidized_copper_door", builder() + public static final Block OXIDIZED_COPPER_DOOR = register(new Block("oxidized_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block WEATHERED_COPPER_DOOR = register(new Block("weathered_copper_door", builder() + public static final Block WEATHERED_COPPER_DOOR = register(new Block("weathered_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block WAXED_COPPER_DOOR = register(new Block("waxed_copper_door", builder() + public static final Block WAXED_COPPER_DOOR = register(new Block("waxed_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block WAXED_EXPOSED_COPPER_DOOR = register(new Block("waxed_exposed_copper_door", builder() + public static final Block WAXED_EXPOSED_COPPER_DOOR = register(new Block("waxed_exposed_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block WAXED_OXIDIZED_COPPER_DOOR = register(new Block("waxed_oxidized_copper_door", builder() + public static final Block WAXED_OXIDIZED_COPPER_DOOR = register(new Block("waxed_oxidized_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block WAXED_WEATHERED_COPPER_DOOR = register(new Block("waxed_weathered_copper_door", builder() + public static final Block WAXED_WEATHERED_COPPER_DOOR = register(new Block("waxed_weathered_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block COPPER_TRAPDOOR = register(new Block("copper_trapdoor", builder() + public static final Block COPPER_TRAPDOOR = register(new Block("copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block EXPOSED_COPPER_TRAPDOOR = register(new Block("exposed_copper_trapdoor", builder() + public static final Block EXPOSED_COPPER_TRAPDOOR = register(new Block("exposed_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block OXIDIZED_COPPER_TRAPDOOR = register(new Block("oxidized_copper_trapdoor", builder() + public static final Block OXIDIZED_COPPER_TRAPDOOR = register(new Block("oxidized_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block WEATHERED_COPPER_TRAPDOOR = register(new Block("weathered_copper_trapdoor", builder() + public static final Block WEATHERED_COPPER_TRAPDOOR = register(new Block("weathered_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block WAXED_COPPER_TRAPDOOR = register(new Block("waxed_copper_trapdoor", builder() + public static final Block WAXED_COPPER_TRAPDOOR = register(new Block("waxed_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block WAXED_EXPOSED_COPPER_TRAPDOOR = register(new Block("waxed_exposed_copper_trapdoor", builder() + public static final Block WAXED_EXPOSED_COPPER_TRAPDOOR = register(new Block("waxed_exposed_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block WAXED_OXIDIZED_COPPER_TRAPDOOR = register(new Block("waxed_oxidized_copper_trapdoor", builder() + public static final Block WAXED_OXIDIZED_COPPER_TRAPDOOR = register(new Block("waxed_oxidized_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block WAXED_WEATHERED_COPPER_TRAPDOOR = register(new Block("waxed_weathered_copper_trapdoor", builder() + public static final Block WAXED_WEATHERED_COPPER_TRAPDOOR = register(new Block("waxed_weathered_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block COPPER_GRATE = register(new Block("copper_grate", builder() + public static final Block COPPER_GRATE = register(new Block("copper_grate", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .booleanState(WATERLOGGED))); - public static final Block EXPOSED_COPPER_GRATE = register(new Block("exposed_copper_grate", builder() + public static final Block EXPOSED_COPPER_GRATE = register(new Block("exposed_copper_grate", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .booleanState(WATERLOGGED))); - public static final Block WEATHERED_COPPER_GRATE = register(new Block("weathered_copper_grate", builder() + public static final Block WEATHERED_COPPER_GRATE = register(new Block("weathered_copper_grate", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .booleanState(WATERLOGGED))); - public static final Block OXIDIZED_COPPER_GRATE = register(new Block("oxidized_copper_grate", builder() + public static final Block OXIDIZED_COPPER_GRATE = register(new Block("oxidized_copper_grate", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .booleanState(WATERLOGGED))); - public static final Block WAXED_COPPER_GRATE = register(new Block("waxed_copper_grate", builder() + public static final Block WAXED_COPPER_GRATE = register(new Block("waxed_copper_grate", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .booleanState(WATERLOGGED))); - public static final Block WAXED_EXPOSED_COPPER_GRATE = register(new Block("waxed_exposed_copper_grate", builder() + public static final Block WAXED_EXPOSED_COPPER_GRATE = register(new Block("waxed_exposed_copper_grate", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .booleanState(WATERLOGGED))); - public static final Block WAXED_WEATHERED_COPPER_GRATE = register(new Block("waxed_weathered_copper_grate", builder() + public static final Block WAXED_WEATHERED_COPPER_GRATE = register(new Block("waxed_weathered_copper_grate", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .booleanState(WATERLOGGED))); - public static final Block WAXED_OXIDIZED_COPPER_GRATE = register(new Block("waxed_oxidized_copper_grate", builder() + public static final Block WAXED_OXIDIZED_COPPER_GRATE = register(new Block("waxed_oxidized_copper_grate", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .booleanState(WATERLOGGED))); - public static final Block COPPER_BULB = register(new Block("copper_bulb", builder() + public static final Block COPPER_BULB = register(new Block("copper_bulb", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .booleanState(LIT) .booleanState(POWERED))); - public static final Block EXPOSED_COPPER_BULB = register(new Block("exposed_copper_bulb", builder() + public static final Block EXPOSED_COPPER_BULB = register(new Block("exposed_copper_bulb", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .booleanState(LIT) .booleanState(POWERED))); - public static final Block WEATHERED_COPPER_BULB = register(new Block("weathered_copper_bulb", builder() + public static final Block WEATHERED_COPPER_BULB = register(new Block("weathered_copper_bulb", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .booleanState(LIT) .booleanState(POWERED))); - public static final Block OXIDIZED_COPPER_BULB = register(new Block("oxidized_copper_bulb", builder() + public static final Block OXIDIZED_COPPER_BULB = register(new Block("oxidized_copper_bulb", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .booleanState(LIT) .booleanState(POWERED))); - public static final Block WAXED_COPPER_BULB = register(new Block("waxed_copper_bulb", builder() + public static final Block WAXED_COPPER_BULB = register(new Block("waxed_copper_bulb", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .booleanState(LIT) .booleanState(POWERED))); - public static final Block WAXED_EXPOSED_COPPER_BULB = register(new Block("waxed_exposed_copper_bulb", builder() + public static final Block WAXED_EXPOSED_COPPER_BULB = register(new Block("waxed_exposed_copper_bulb", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .booleanState(LIT) .booleanState(POWERED))); - public static final Block WAXED_WEATHERED_COPPER_BULB = register(new Block("waxed_weathered_copper_bulb", builder() + public static final Block WAXED_WEATHERED_COPPER_BULB = register(new Block("waxed_weathered_copper_bulb", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .booleanState(LIT) .booleanState(POWERED))); - public static final Block WAXED_OXIDIZED_COPPER_BULB = register(new Block("waxed_oxidized_copper_bulb", builder() + public static final Block WAXED_OXIDIZED_COPPER_BULB = register(new Block("waxed_oxidized_copper_bulb", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .booleanState(LIT) .booleanState(POWERED))); - public static final Block LIGHTNING_ROD = register(new Block("lightning_rod", builder() + public static final Block LIGHTNING_ROD = register(new Block("lightning_rod", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block POINTED_DRIPSTONE = register(new Block("pointed_dripstone", builder() + public static final Block POINTED_DRIPSTONE = register(new Block("pointed_dripstone", builder().destroyTime(1.5f) .enumState(DRIPSTONE_THICKNESS, "tip_merge", "tip", "frustum", "middle", "base") .enumState(VERTICAL_DIRECTION, Direction.UP, Direction.DOWN) .booleanState(WATERLOGGED))); - public static final Block DRIPSTONE_BLOCK = register(new Block("dripstone_block", builder())); + public static final Block DRIPSTONE_BLOCK = register(new Block("dripstone_block", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block CAVE_VINES = register(new Block("cave_vines", builder() .intState(AGE_25, 0, 25) .booleanState(BERRIES))); @@ -2687,16 +2687,16 @@ public final class Blocks { public static final Block SPORE_BLOSSOM = register(new Block("spore_blossom", builder())); public static final Block AZALEA = register(new Block("azalea", builder())); public static final Block FLOWERING_AZALEA = register(new Block("flowering_azalea", builder())); - public static final Block MOSS_CARPET = register(new Block("moss_carpet", builder())); + public static final Block MOSS_CARPET = register(new Block("moss_carpet", builder().destroyTime(0.1f))); public static final Block PINK_PETALS = register(new Block("pink_petals", builder() .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .intState(FLOWER_AMOUNT, 1, 4))); - public static final Block MOSS_BLOCK = register(new Block("moss_block", builder())); - public static final Block BIG_DRIPLEAF = register(new Block("big_dripleaf", builder() + public static final Block MOSS_BLOCK = register(new Block("moss_block", builder().destroyTime(0.1f))); + public static final Block BIG_DRIPLEAF = register(new Block("big_dripleaf", builder().destroyTime(0.1f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(TILT, "none", "unstable", "partial", "full") .booleanState(WATERLOGGED))); - public static final Block BIG_DRIPLEAF_STEM = register(new Block("big_dripleaf_stem", builder() + public static final Block BIG_DRIPLEAF_STEM = register(new Block("big_dripleaf_stem", builder().destroyTime(0.1f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); public static final Block SMALL_DRIPLEAF = register(new Block("small_dripleaf", builder() @@ -2705,109 +2705,109 @@ public final class Blocks { .booleanState(WATERLOGGED))); public static final Block HANGING_ROOTS = register(new Block("hanging_roots", builder() .booleanState(WATERLOGGED))); - public static final Block ROOTED_DIRT = register(new Block("rooted_dirt", builder())); - public static final Block MUD = register(new Block("mud", builder())); - public static final Block DEEPSLATE = register(new Block("deepslate", builder() + public static final Block ROOTED_DIRT = register(new Block("rooted_dirt", builder().destroyTime(0.5f))); + public static final Block MUD = register(new Block("mud", builder().destroyTime(0.5f))); + public static final Block DEEPSLATE = register(new Block("deepslate", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block COBBLED_DEEPSLATE = register(new Block("cobbled_deepslate", builder())); - public static final Block COBBLED_DEEPSLATE_STAIRS = register(new Block("cobbled_deepslate_stairs", builder() + public static final Block COBBLED_DEEPSLATE = register(new Block("cobbled_deepslate", builder().requiresCorrectToolForDrops().destroyTime(3.5f))); + public static final Block COBBLED_DEEPSLATE_STAIRS = register(new Block("cobbled_deepslate_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block COBBLED_DEEPSLATE_SLAB = register(new Block("cobbled_deepslate_slab", builder() + public static final Block COBBLED_DEEPSLATE_SLAB = register(new Block("cobbled_deepslate_slab", builder().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block COBBLED_DEEPSLATE_WALL = register(new Block("cobbled_deepslate_wall", builder() + public static final Block COBBLED_DEEPSLATE_WALL = register(new Block("cobbled_deepslate_wall", builder().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(EAST_WALL, "none", "low", "tall") .enumState(NORTH_WALL, "none", "low", "tall") .enumState(SOUTH_WALL, "none", "low", "tall") .booleanState(UP) .booleanState(WATERLOGGED) .enumState(WEST_WALL, "none", "low", "tall"))); - public static final Block POLISHED_DEEPSLATE = register(new Block("polished_deepslate", builder())); - public static final Block POLISHED_DEEPSLATE_STAIRS = register(new Block("polished_deepslate_stairs", builder() + public static final Block POLISHED_DEEPSLATE = register(new Block("polished_deepslate", builder().requiresCorrectToolForDrops().destroyTime(3.5f))); + public static final Block POLISHED_DEEPSLATE_STAIRS = register(new Block("polished_deepslate_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block POLISHED_DEEPSLATE_SLAB = register(new Block("polished_deepslate_slab", builder() + public static final Block POLISHED_DEEPSLATE_SLAB = register(new Block("polished_deepslate_slab", builder().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block POLISHED_DEEPSLATE_WALL = register(new Block("polished_deepslate_wall", builder() + public static final Block POLISHED_DEEPSLATE_WALL = register(new Block("polished_deepslate_wall", builder().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(EAST_WALL, "none", "low", "tall") .enumState(NORTH_WALL, "none", "low", "tall") .enumState(SOUTH_WALL, "none", "low", "tall") .booleanState(UP) .booleanState(WATERLOGGED) .enumState(WEST_WALL, "none", "low", "tall"))); - public static final Block DEEPSLATE_TILES = register(new Block("deepslate_tiles", builder())); - public static final Block DEEPSLATE_TILE_STAIRS = register(new Block("deepslate_tile_stairs", builder() + public static final Block DEEPSLATE_TILES = register(new Block("deepslate_tiles", builder().requiresCorrectToolForDrops().destroyTime(3.5f))); + public static final Block DEEPSLATE_TILE_STAIRS = register(new Block("deepslate_tile_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block DEEPSLATE_TILE_SLAB = register(new Block("deepslate_tile_slab", builder() + public static final Block DEEPSLATE_TILE_SLAB = register(new Block("deepslate_tile_slab", builder().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block DEEPSLATE_TILE_WALL = register(new Block("deepslate_tile_wall", builder() + public static final Block DEEPSLATE_TILE_WALL = register(new Block("deepslate_tile_wall", builder().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(EAST_WALL, "none", "low", "tall") .enumState(NORTH_WALL, "none", "low", "tall") .enumState(SOUTH_WALL, "none", "low", "tall") .booleanState(UP) .booleanState(WATERLOGGED) .enumState(WEST_WALL, "none", "low", "tall"))); - public static final Block DEEPSLATE_BRICKS = register(new Block("deepslate_bricks", builder())); - public static final Block DEEPSLATE_BRICK_STAIRS = register(new Block("deepslate_brick_stairs", builder() + public static final Block DEEPSLATE_BRICKS = register(new Block("deepslate_bricks", builder().requiresCorrectToolForDrops().destroyTime(3.5f))); + public static final Block DEEPSLATE_BRICK_STAIRS = register(new Block("deepslate_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block DEEPSLATE_BRICK_SLAB = register(new Block("deepslate_brick_slab", builder() + public static final Block DEEPSLATE_BRICK_SLAB = register(new Block("deepslate_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block DEEPSLATE_BRICK_WALL = register(new Block("deepslate_brick_wall", builder() + public static final Block DEEPSLATE_BRICK_WALL = register(new Block("deepslate_brick_wall", builder().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(EAST_WALL, "none", "low", "tall") .enumState(NORTH_WALL, "none", "low", "tall") .enumState(SOUTH_WALL, "none", "low", "tall") .booleanState(UP) .booleanState(WATERLOGGED) .enumState(WEST_WALL, "none", "low", "tall"))); - public static final Block CHISELED_DEEPSLATE = register(new Block("chiseled_deepslate", builder())); - public static final Block CRACKED_DEEPSLATE_BRICKS = register(new Block("cracked_deepslate_bricks", builder())); - public static final Block CRACKED_DEEPSLATE_TILES = register(new Block("cracked_deepslate_tiles", builder())); - public static final Block INFESTED_DEEPSLATE = register(new Block("infested_deepslate", builder() + public static final Block CHISELED_DEEPSLATE = register(new Block("chiseled_deepslate", builder().requiresCorrectToolForDrops().destroyTime(3.5f))); + public static final Block CRACKED_DEEPSLATE_BRICKS = register(new Block("cracked_deepslate_bricks", builder().requiresCorrectToolForDrops().destroyTime(3.5f))); + public static final Block CRACKED_DEEPSLATE_TILES = register(new Block("cracked_deepslate_tiles", builder().requiresCorrectToolForDrops().destroyTime(3.5f))); + public static final Block INFESTED_DEEPSLATE = register(new Block("infested_deepslate", builder().destroyTime(1.5f) .enumState(AXIS, Axis.VALUES))); - public static final Block SMOOTH_BASALT = register(new Block("smooth_basalt", builder())); - public static final Block RAW_IRON_BLOCK = register(new Block("raw_iron_block", builder())); - public static final Block RAW_COPPER_BLOCK = register(new Block("raw_copper_block", builder())); - public static final Block RAW_GOLD_BLOCK = register(new Block("raw_gold_block", builder())); + public static final Block SMOOTH_BASALT = register(new Block("smooth_basalt", builder().requiresCorrectToolForDrops().destroyTime(1.25f))); + public static final Block RAW_IRON_BLOCK = register(new Block("raw_iron_block", builder().requiresCorrectToolForDrops().destroyTime(5.0f))); + public static final Block RAW_COPPER_BLOCK = register(new Block("raw_copper_block", builder().requiresCorrectToolForDrops().destroyTime(5.0f))); + public static final Block RAW_GOLD_BLOCK = register(new Block("raw_gold_block", builder().requiresCorrectToolForDrops().destroyTime(5.0f))); public static final Block POTTED_AZALEA_BUSH = register(new Block("potted_azalea_bush", builder())); public static final Block POTTED_FLOWERING_AZALEA_BUSH = register(new Block("potted_flowering_azalea_bush", builder())); - public static final Block OCHRE_FROGLIGHT = register(new Block("ochre_froglight", builder() + public static final Block OCHRE_FROGLIGHT = register(new Block("ochre_froglight", builder().destroyTime(0.3f) .enumState(AXIS, Axis.VALUES))); - public static final Block VERDANT_FROGLIGHT = register(new Block("verdant_froglight", builder() + public static final Block VERDANT_FROGLIGHT = register(new Block("verdant_froglight", builder().destroyTime(0.3f) .enumState(AXIS, Axis.VALUES))); - public static final Block PEARLESCENT_FROGLIGHT = register(new Block("pearlescent_froglight", builder() + public static final Block PEARLESCENT_FROGLIGHT = register(new Block("pearlescent_froglight", builder().destroyTime(0.3f) .enumState(AXIS, Axis.VALUES))); public static final Block FROGSPAWN = register(new Block("frogspawn", builder())); - public static final Block REINFORCED_DEEPSLATE = register(new Block("reinforced_deepslate", builder())); - public static final Block DECORATED_POT = register(new Block("decorated_pot", builder() + public static final Block REINFORCED_DEEPSLATE = register(new Block("reinforced_deepslate", builder().destroyTime(55.0f))); + public static final Block DECORATED_POT = register(new Block("decorated_pot", builder().setBlockEntity() .booleanState(CRACKED) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block CRAFTER = register(new Block("crafter", builder() + public static final Block CRAFTER = register(new Block("crafter", builder().setBlockEntity().destroyTime(1.5f) .booleanState(CRAFTING) .enumState(ORIENTATION, "down_east", "down_north", "down_south", "down_west", "up_east", "up_north", "up_south", "up_west", "west_up", "east_up", "north_up", "south_up") .booleanState(TRIGGERED))); - public static final Block TRIAL_SPAWNER = register(new Block("trial_spawner", builder() + public static final Block TRIAL_SPAWNER = register(new Block("trial_spawner", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(50.0f) .booleanState(OMINOUS) .enumState(TRIAL_SPAWNER_STATE, "inactive", "waiting_for_players", "active", "waiting_for_reward_ejection", "ejecting_reward", "cooldown"))); - public static final Block VAULT = register(new Block("vault", builder() + public static final Block VAULT = register(new Block("vault", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(50.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OMINOUS) .enumState(VAULT_STATE, "inactive", "active", "unlocking", "ejecting"))); - public static final Block HEAVY_CORE = register(new Block("heavy_core", builder() + public static final Block HEAVY_CORE = register(new Block("heavy_core", builder().destroyTime(10.0f) .booleanState(WATERLOGGED))); private static T register(T block) { diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java b/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java index 459f4a5af..84822ca16 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java @@ -41,10 +41,16 @@ public class Block { public static final int JAVA_AIR_ID = 0; private final String javaIdentifier; + private final boolean requiresCorrectToolForDrops; + private final boolean hasBlockEntity; + private final float destroyTime; private int javaId = -1; public Block(String javaIdentifier, Builder builder) { this.javaIdentifier = Identifier.formalize(javaIdentifier).intern(); + this.requiresCorrectToolForDrops = builder.requiresCorrectToolForDrops; + this.hasBlockEntity = builder.hasBlockEntity; + this.destroyTime = builder.destroyTime; builder.build(this); } @@ -52,6 +58,18 @@ public class Block { return javaIdentifier; } + public boolean requiresCorrectToolForDrops() { + return requiresCorrectToolForDrops; + } + + public boolean hasBlockEntity() { + return hasBlockEntity; + } + + public float destroyTime() { + return destroyTime; + } + public int javaId() { return javaId; } @@ -77,6 +95,9 @@ public class Block { public static final class Builder { private final Map, List>> states = new LinkedHashMap<>(); + private boolean requiresCorrectToolForDrops = false; + private boolean hasBlockEntity = false; + private float destroyTime; /** * For states that we're just tracking for mirroring Java states. @@ -107,6 +128,21 @@ public class Block { return this; } + public Builder requiresCorrectToolForDrops() { + this.requiresCorrectToolForDrops = true; + return this; + } + + public Builder setBlockEntity() { + this.hasBlockEntity = true; + return this; + } + + public Builder destroyTime(float destroyTime) { + this.destroyTime = destroyTime; + return this; + } + private void build(Block block) { if (states.isEmpty()) { BlockRegistries.BLOCK_STATES.get().add(new BlockState(block, BlockRegistries.BLOCK_STATES.get().size())); diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java index ace110f78..b623bc043 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java @@ -51,6 +51,7 @@ import org.geysermc.geyser.api.block.custom.CustomBlockData; import org.geysermc.geyser.api.block.custom.CustomBlockState; import org.geysermc.geyser.api.block.custom.nonvanilla.JavaBlockState; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.level.physics.PistonBehavior; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.type.BlockMapping; @@ -565,6 +566,15 @@ public final class BlockRegistryPopulator { .isBlockEntity(javaBlockState.hasBlockEntity()) .build(); + Block.Builder builder = Block.builder() + .destroyTime(javaBlockState.blockHardness()); + if (!javaBlockState.canBreakWithHand()) { + builder.requiresCorrectToolForDrops(); + } + if (javaBlockState.hasBlockEntity()) { + builder.setBlockEntity(); + } + String cleanJavaIdentifier = BlockUtils.getCleanIdentifier(javaBlockState.identifier()); String bedrockIdentifier = customBlockState.block().identifier(); diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java index 38ac32214..6da354646 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java @@ -25,15 +25,16 @@ package org.geysermc.geyser.session.cache; -import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundUpdateTagsPacket; import it.unimi.dsi.fastutil.ints.IntList; import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.type.Item; +import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.registry.type.BlockMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.BlockTag; import org.geysermc.geyser.session.cache.tags.ItemTag; +import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundUpdateTagsPacket; import javax.annotation.ParametersAreNonnullByDefault; import java.util.EnumMap; @@ -95,6 +96,17 @@ public final class TagCache { } } + /** + * @return true if the block tag is present and contains this block mapping's Java ID. + */ + public boolean is(BlockTag tag, Block block) { + IntList values = this.blocks.get(tag); + if (values != null) { + return values.contains(block.javaId()); + } + return false; + } + /** * @return true if the block tag is present and contains this block mapping's Java ID. */ diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java index 690fdb371..861f55731 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java @@ -40,6 +40,7 @@ import org.geysermc.geyser.entity.type.player.SessionPlayerEntity; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.type.Block; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.type.BlockMapping; @@ -160,7 +161,7 @@ public class BedrockActionTranslator extends PacketTranslator { @@ -42,7 +43,7 @@ public class JavaBlockDestructionTranslator extends PacketTranslator session.getTagCache().is(BlockTag.AXE_EFFECTIVE, blockMapping); - case "hoe" -> session.getTagCache().is(BlockTag.HOE_EFFECTIVE, blockMapping); - case "pickaxe" -> session.getTagCache().is(BlockTag.PICKAXE_EFFECTIVE, blockMapping); - case "shears" -> session.getTagCache().is(BlockTag.LEAVES, blockMapping) || session.getTagCache().is(BlockTag.WOOL, blockMapping); - case "shovel" -> session.getTagCache().is(BlockTag.SHOVEL_EFFECTIVE, blockMapping); - case "sword" -> blockMapping.getJavaBlockId() == BlockStateValues.JAVA_COBWEB_ID; + case "axe" -> session.getTagCache().is(BlockTag.AXE_EFFECTIVE, block); + case "hoe" -> session.getTagCache().is(BlockTag.HOE_EFFECTIVE, block); + case "pickaxe" -> session.getTagCache().is(BlockTag.PICKAXE_EFFECTIVE, block); + case "shears" -> session.getTagCache().is(BlockTag.LEAVES, block) || session.getTagCache().is(BlockTag.WOOL, block); + case "shovel" -> session.getTagCache().is(BlockTag.SHOVEL_EFFECTIVE, block); + case "sword" -> block == Blocks.COBWEB; default -> { session.getGeyser().getLogger().warning("Unknown tool type: " + itemToolType); yield false; @@ -71,7 +71,7 @@ public final class BlockUtils { }; } - private static boolean canToolTierBreakBlock(GeyserSession session, BlockMapping blockMapping, String toolTier) { + private static boolean canToolTierBreakBlock(GeyserSession session, Block block, String toolTier) { if (toolTier.equals("netherite") || toolTier.equals("diamond")) { // As of 1.17, these tiers can mine everything that is mineable return true; @@ -80,15 +80,15 @@ public final class BlockUtils { switch (toolTier) { // Use intentional fall-throughs to check each tier with this block default: - if (session.getTagCache().is(BlockTag.NEEDS_STONE_TOOL, blockMapping)) { + if (session.getTagCache().is(BlockTag.NEEDS_STONE_TOOL, block)) { return false; } case "stone": - if (session.getTagCache().is(BlockTag.NEEDS_IRON_TOOL, blockMapping)) { + if (session.getTagCache().is(BlockTag.NEEDS_IRON_TOOL, block)) { return false; } case "iron": - if (session.getTagCache().is(BlockTag.NEEDS_DIAMOND_TOOL, blockMapping)) { + if (session.getTagCache().is(BlockTag.NEEDS_DIAMOND_TOOL, block)) { return false; } } @@ -131,9 +131,9 @@ public final class BlockUtils { return 1.0 / speed; } - public static double getBreakTime(GeyserSession session, BlockMapping blockMapping, ItemMapping item, @Nullable DataComponents components, boolean isSessionPlayer) { - boolean isShearsEffective = session.getTagCache().is(BlockTag.LEAVES, blockMapping) || session.getTagCache().is(BlockTag.WOOL, blockMapping); //TODO called twice - boolean canHarvestWithHand = blockMapping.isCanBreakWithHand(); + public static double getBreakTime(GeyserSession session, Block block, ItemMapping item, @Nullable DataComponents components, boolean isSessionPlayer) { + boolean isShearsEffective = session.getTagCache().is(BlockTag.LEAVES, block) || session.getTagCache().is(BlockTag.WOOL, block); //TODO called twice + boolean canHarvestWithHand = !block.requiresCorrectToolForDrops(); String toolType = ""; String toolTier = ""; boolean correctTool = false; @@ -141,8 +141,8 @@ public final class BlockUtils { if (item.isTool()) { toolType = item.getToolType(); toolTier = item.getToolTier(); - correctTool = correctTool(session, blockMapping, toolType); - toolCanBreak = canToolTierBreakBlock(session, blockMapping, toolTier); + correctTool = correctTool(session, block, toolType); + toolCanBreak = canToolTierBreakBlock(session, block, toolTier); } int toolEfficiencyLevel = ItemUtils.getEnchantmentLevel(components, Enchantment.JavaEnchantment.EFFICIENCY); @@ -151,7 +151,7 @@ public final class BlockUtils { if (!isSessionPlayer) { // Another entity is currently mining; we have all the information we know - return calculateBreakTime(blockMapping.getHardness(), toolTier, canHarvestWithHand, correctTool, toolCanBreak, toolType, isShearsEffective, + return calculateBreakTime(block.destroyTime(), toolTier, canHarvestWithHand, correctTool, toolCanBreak, toolType, isShearsEffective, toolEfficiencyLevel, hasteLevel, miningFatigueLevel, false, true); } @@ -162,11 +162,11 @@ public final class BlockUtils { boolean insideOfWaterWithoutAquaAffinity = waterInEyes && ItemUtils.getEnchantmentLevel(session.getPlayerInventory().getItem(5).getComponents(), Enchantment.JavaEnchantment.AQUA_AFFINITY) < 1; - return calculateBreakTime(blockMapping.getHardness(), toolTier, canHarvestWithHand, correctTool, toolCanBreak, toolType, isShearsEffective, + return calculateBreakTime(block.destroyTime(), toolTier, canHarvestWithHand, correctTool, toolCanBreak, toolType, isShearsEffective, toolEfficiencyLevel, hasteLevel, miningFatigueLevel, insideOfWaterWithoutAquaAffinity, session.getPlayerEntity().isOnGround()); } - public static double getSessionBreakTime(GeyserSession session, BlockMapping blockMapping) { + public static double getSessionBreakTime(GeyserSession session, Block block) { PlayerInventory inventory = session.getPlayerInventory(); GeyserItemStack item = inventory.getItemInHand(); ItemMapping mapping = ItemMapping.AIR; @@ -175,7 +175,7 @@ public final class BlockUtils { mapping = item.getMapping(session); components = item.getComponents(); } - return getBreakTime(session, blockMapping, mapping, components, true); + return getBreakTime(session, block, mapping, components, true); } /** From 1cd0aad79fdb889ee989084cd1b0c05b1251e387 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Fri, 17 May 2024 15:02:12 -0400 Subject: [PATCH 168/272] Comment out snow collision Seems to be unnecessary as of 1.20.30. Will be deleted later if no problems are found! --- .../org/geysermc/geyser/translator/collision/SnowCollision.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/collision/SnowCollision.java b/core/src/main/java/org/geysermc/geyser/translator/collision/SnowCollision.java index fb83e357d..af2bcb7ea 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/collision/SnowCollision.java +++ b/core/src/main/java/org/geysermc/geyser/translator/collision/SnowCollision.java @@ -30,7 +30,7 @@ import org.geysermc.geyser.level.physics.BoundingBox; import org.geysermc.geyser.session.GeyserSession; @EqualsAndHashCode(callSuper = true) -@CollisionRemapper(regex = "^snow$", passDefaultBoxes = true, usesParams = true) +//@CollisionRemapper(regex = "^snow$", passDefaultBoxes = true, usesParams = true) TODO remove if no bugs are found. Seems fine with Bedrock 1.20.80 and 1.20.5 public class SnowCollision extends BlockCollision { private final int layers; From b010c500d84e59ee30c58c766b954a6dc2a45423 Mon Sep 17 00:00:00 2001 From: chris Date: Fri, 17 May 2024 22:21:01 +0200 Subject: [PATCH 169/272] Various entity fixes: Ensure TNT doesn't bug into the ground, reset player entity flags properly (#4670) * Various entity fixes * actually update the tnt entity position * revert bad diff --- .../geyser/entity/EntityDefinitions.java | 3 ++- .../geysermc/geyser/entity/type/Entity.java | 5 +++- .../geyser/entity/type/ExpOrbEntity.java | 7 +++++ .../geyser/entity/type/TNTEntity.java | 12 ++++++++- .../entity/type/player/PlayerEntity.java | 26 +++++++++++++++++++ .../type/player/SessionPlayerEntity.java | 10 ++----- 6 files changed, 52 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index 991b95571..21cc526dd 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -235,7 +235,7 @@ public final class EntityDefinitions { .addTranslator(MetadataType.BOOLEAN, (enderCrystalEntity, entityMetadata) -> enderCrystalEntity.setFlag(EntityFlag.SHOW_BOTTOM, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue())) // There is a base located on the ender crystal .build(); - EXPERIENCE_ORB = EntityDefinition.inherited(null, entityBase) + EXPERIENCE_ORB = EntityDefinition.inherited(ExpOrbEntity::new, entityBase) .type(EntityType.EXPERIENCE_ORB) .identifier("minecraft:xp_orb") .build(); @@ -297,6 +297,7 @@ public final class EntityDefinitions { TNT = EntityDefinition.inherited(TNTEntity::new, entityBase) .type(EntityType.TNT) .heightAndWidth(0.98f) + .offset(0.49f) .addTranslator(MetadataType.INT, TNTEntity::setFuseLength) .build(); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java index fecd72f67..a3f16875d 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java @@ -59,6 +59,9 @@ import java.util.*; @Getter @Setter public class Entity implements GeyserEntity { + + private static final boolean PRINT_ENTITY_SPAWN_DEBUG = Boolean.parseBoolean(System.getProperty("Geyser.PrintEntitySpawnDebug", "false")); + protected final GeyserSession session; protected int entityId; @@ -181,7 +184,7 @@ public class Entity implements GeyserEntity { flagsDirty = false; - if (session.getGeyser().getConfig().isDebugMode()) { + if (session.getGeyser().getConfig().isDebugMode() && PRINT_ENTITY_SPAWN_DEBUG) { EntityType type = definition.entityType(); String name = type != null ? type.name() : getClass().getSimpleName(); session.getGeyser().getLogger().debug("Spawned entity " + name + " at location " + position + " with id " + geyserId + " (java id " + entityId + ")"); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ExpOrbEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ExpOrbEntity.java index 5a79a98b3..9f61bc961 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ExpOrbEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ExpOrbEntity.java @@ -27,11 +27,18 @@ package org.geysermc.geyser.entity.type; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; +import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.session.GeyserSession; +import java.util.UUID; + public class ExpOrbEntity extends Entity { + public ExpOrbEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition entityDefinition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { + this(session, 1, entityId, geyserId, position); + } + public ExpOrbEntity(GeyserSession session, int amount, int entityId, long geyserId, Vector3f position) { super(session, entityId, geyserId, null, EntityDefinitions.EXPERIENCE_ORB, position, Vector3f.ZERO, 0, 0, 0); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/TNTEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/TNTEntity.java index dca36cda0..47d97b8f7 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/TNTEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/TNTEntity.java @@ -39,7 +39,17 @@ public class TNTEntity extends Entity implements Tickable { private int currentTick; public TNTEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { - super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); + super(session, entityId, geyserId, uuid, definition, position.add(0, definition.offset(), 0), motion, yaw, pitch, headYaw); + } + + @Override + public void moveRelative(double relX, double relY, double relZ, float yaw, float pitch, boolean isOnGround) { + super.moveRelative(relX, relY + definition.offset(), relZ, yaw, pitch, isOnGround); + } + + @Override + public void moveAbsolute(Vector3f position, float yaw, float pitch, float headYaw, boolean isOnGround, boolean teleported) { + super.moveAbsolute(position.add(Vector3f.from(0, definition.offset(), 0)), yaw, pitch, headYaw, isOnGround, teleported); } public void setFuseLength(IntEntityMetadata entityMetadata) { diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java index 25040063e..4c67b882f 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java @@ -41,6 +41,7 @@ import org.cloudburstmc.protocol.bedrock.data.command.CommandPermission; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData; +import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.packet.*; import org.geysermc.geyser.api.entity.type.player.GeyserPlayerEntity; import org.geysermc.geyser.entity.EntityDefinitions; @@ -166,6 +167,31 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity { session.sendUpstreamPacket(addPlayerPacket); } + @Override + public void despawnEntity() { + super.despawnEntity(); + + // Since we re-use player entities: Clear flags, held item, etc + this.resetMetadata(); + this.hand = ItemData.AIR; + this.offhand = ItemData.AIR; + this.boots = ItemData.AIR; + this.leggings = ItemData.AIR; + this.chestplate = ItemData.AIR; + this.helmet = ItemData.AIR; + } + + public void resetMetadata() { + // Reset all metadata to their default values + // This is used when a player respawns + this.flags.clear(); + this.initializeMetadata(); + + // Explicitly reset all metadata not handled by initializeMetadata + setParrot(null, true); + setParrot(null, false); + } + public void sendPlayer() { if (session.getEntityCache().getPlayerEntity(uuid) == null) return; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java index e10adb134..533ca3c59 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java @@ -264,19 +264,13 @@ public class SessionPlayerEntity extends PlayerEntity { super.setAbsorptionHearts(entityMetadata); } + @Override public void resetMetadata() { - // Reset all metadata to their default values - // This is used when a player respawns - this.flags.clear(); - this.initializeMetadata(); + super.resetMetadata(); // Reset air this.resetAir(); - // Explicitly reset all metadata not handled by initializeMetadata - setParrot(null, true); - setParrot(null, false); - // Absorption is metadata in java edition attributes.remove(GeyserAttributeType.ABSORPTION); UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket(); From 5ebb6ef0d66ca5871c8c42adb245a2a3f48113d2 Mon Sep 17 00:00:00 2001 From: chris Date: Fri, 17 May 2024 22:48:46 +0200 Subject: [PATCH 170/272] Fix: using curly brackets in custom Minecraft locale overrides --- .../geyser/text/MinecraftTranslationRegistry.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/text/MinecraftTranslationRegistry.java b/core/src/main/java/org/geysermc/geyser/text/MinecraftTranslationRegistry.java index b59b4db8e..67654360d 100644 --- a/core/src/main/java/org/geysermc/geyser/text/MinecraftTranslationRegistry.java +++ b/core/src/main/java/org/geysermc/geyser/text/MinecraftTranslationRegistry.java @@ -63,6 +63,13 @@ public class MinecraftTranslationRegistry extends TranslatableComponentRenderer< } } + // replace single quote instances which get lost in MessageFormat otherwise + localeString = localeString.replace("'", "''"); + + // Wrap all curly brackets with single quote inserts - fixes https://github.com/GeyserMC/Geyser/issues/4662 + localeString = localeString.replace("{", "'{") + .replace("}", "'}"); + // Replace the `%s` with numbered inserts `{0}` Pattern p = stringReplacement; Matcher m = p.matcher(localeString); @@ -83,8 +90,7 @@ public class MinecraftTranslationRegistry extends TranslatableComponentRenderer< } m.appendTail(sb); - // replace single quote instances which get lost in MessageFormat otherwise // Locale shouldn't need to be specific - dates for example will not be handled - return new MessageFormat(sb.toString().replace("'", "''"), Locale.ROOT); + return new MessageFormat(sb.toString(), Locale.ROOT); } } From 06dc0d1ca83f820ec9fed233a7998eeead888363 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Fri, 17 May 2024 17:52:19 -0400 Subject: [PATCH 171/272] Collisions without BlockMapping --- .../java/org/geysermc/geyser/GeyserImpl.java | 2 - .../geyser/level/block/BlockStateValues.java | 3 - .../geyser/registry/BlockRegistries.java | 12 +-- .../geyser/registry/ListRegistry.java | 15 +++- .../loader/CollisionRegistryLoader.java | 76 +++++++++---------- .../populator/BlockRegistryPopulator.java | 11 +-- .../collision/CollisionRemapper.java | 6 -- .../collision/DirtPathCollision.java | 3 +- .../translator/collision/DoorCollision.java | 22 +++--- .../GlassPaneAndIronBarsCollision.java | 21 ++--- .../collision/ScaffoldingCollision.java | 3 +- .../translator/collision/SolidCollision.java | 3 +- .../collision/TrapdoorCollision.java | 47 ++++-------- core/src/main/resources/mappings | 2 +- 14 files changed, 100 insertions(+), 126 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java index 4f572ef63..e7237e8bf 100644 --- a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java +++ b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java @@ -69,7 +69,6 @@ import org.geysermc.geyser.event.GeyserEventBus; import org.geysermc.geyser.extension.GeyserExtensionManager; import org.geysermc.geyser.impl.MinecraftVersionImpl; import org.geysermc.geyser.level.WorldManager; -import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.network.netty.GeyserServer; import org.geysermc.geyser.registry.BlockRegistries; @@ -258,7 +257,6 @@ public class GeyserImpl implements GeyserApi { VersionCheckUtils.checkForOutdatedJava(logger); - Blocks.VAULT.javaId(); for (int i = 0; i < BlockRegistries.JAVA_BLOCKS.get().length; i++) { String cleanIdentifier = BlockRegistries.JAVA_BLOCKS.get(i).getCleanJavaIdentifier(); String newIdentifier = BlockRegistries.BLOCK_STATES.get(i).block().javaIdentifier(); diff --git a/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java b/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java index 205486ced..e2a2cb5eb 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java @@ -69,9 +69,6 @@ public final class BlockStateValues { private static final Int2IntMap WATER_LEVEL = new Int2IntOpenHashMap(); private static final IntSet UPPER_DOORS = new IntOpenHashSet(); - public static final int JAVA_AIR_ID = 0; - - public static int JAVA_COBWEB_ID; public static int JAVA_FURNACE_ID; public static int JAVA_FURNACE_LIT_ID; public static int JAVA_HONEY_BLOCK_ID; diff --git a/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java b/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java index 54a36dc12..416ab7793 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java +++ b/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java @@ -34,6 +34,7 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import org.geysermc.geyser.api.block.custom.CustomBlockData; import org.geysermc.geyser.api.block.custom.CustomBlockState; import org.geysermc.geyser.api.block.custom.nonvanilla.JavaBlockState; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.registry.loader.CollisionRegistryLoader; @@ -82,19 +83,13 @@ public class BlockRegistries { /** * A mapped registry containing which holds block IDs to its {@link BlockCollision}. */ - public static final IntMappedRegistry COLLISIONS; + public static final ListRegistry COLLISIONS; /** * A mapped registry containing the Java identifiers to IDs. */ public static final MappedRegistry> JAVA_IDENTIFIER_TO_ID = MappedRegistry.create(RegistryLoaders.empty(Object2IntOpenHashMap::new)); - /** - * A registry which stores unique Java IDs to its clean identifier - * This is used in the statistics form. - */ - public static final ArrayRegistry CLEAN_JAVA_IDENTIFIERS = ArrayRegistry.create(RegistryLoaders.uninitialized()); - /** * A registry containing all the waterlogged blockstates. */ @@ -141,12 +136,13 @@ public class BlockRegistries { public static final SimpleMappedRegistry CUSTOM_SKULLS = SimpleMappedRegistry.create(RegistryLoaders.empty(Object2ObjectOpenHashMap::new)); static { + Blocks.VAULT.javaId(); // FIXME CustomSkullRegistryPopulator.populate(); BlockRegistryPopulator.populate(BlockRegistryPopulator.Stage.PRE_INIT); CustomBlockRegistryPopulator.populate(CustomBlockRegistryPopulator.Stage.DEFINITION); CustomBlockRegistryPopulator.populate(CustomBlockRegistryPopulator.Stage.NON_VANILLA_REGISTRATION); BlockRegistryPopulator.populate(BlockRegistryPopulator.Stage.INIT_JAVA); - COLLISIONS = IntMappedRegistry.create(Pair.of("org.geysermc.geyser.translator.collision.CollisionRemapper", "mappings/collision.json"), CollisionRegistryLoader::new); + COLLISIONS = ListRegistry.create(Pair.of("org.geysermc.geyser.translator.collision.CollisionRemapper", "mappings/collisions.nbt"), CollisionRegistryLoader::new); CustomBlockRegistryPopulator.populate(CustomBlockRegistryPopulator.Stage.VANILLA_REGISTRATION); CustomBlockRegistryPopulator.populate(CustomBlockRegistryPopulator.Stage.CUSTOM_REGISTRATION); BlockRegistryPopulator.populate(BlockRegistryPopulator.Stage.INIT_BEDROCK); diff --git a/core/src/main/java/org/geysermc/geyser/registry/ListRegistry.java b/core/src/main/java/org/geysermc/geyser/registry/ListRegistry.java index bb5d2538c..d13c47ba8 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/ListRegistry.java +++ b/core/src/main/java/org/geysermc/geyser/registry/ListRegistry.java @@ -29,6 +29,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.registry.loader.RegistryLoader; import java.util.List; +import java.util.function.Supplier; public class ListRegistry extends Registry> { /** @@ -98,6 +99,18 @@ public class ListRegistry extends Registry> { * @return a new registry with the given RegistryLoader supplier */ public static ListRegistry create(RegistryLoader> registryLoader) { - return new ListRegistry(null, registryLoader); + return new ListRegistry<>(null, registryLoader); + } + + /** + * Creates a new integer mapped registry with the given {@link RegistryLoader} and input. + * + * @param registryLoader the registry loader + * @param the input + * @param the type value + * @return a new registry with the given RegistryLoader supplier + */ + public static ListRegistry create(I input, Supplier>> registryLoader) { + return new ListRegistry<>(input, registryLoader.get()); } } diff --git a/core/src/main/java/org/geysermc/geyser/registry/loader/CollisionRegistryLoader.java b/core/src/main/java/org/geysermc/geyser/registry/loader/CollisionRegistryLoader.java index 95e8bd2c1..7cf39b6d7 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/loader/CollisionRegistryLoader.java +++ b/core/src/main/java/org/geysermc/geyser/registry/loader/CollisionRegistryLoader.java @@ -25,18 +25,19 @@ package org.geysermc.geyser.registry.loader; -import com.fasterxml.jackson.databind.node.ArrayNode; import it.unimi.dsi.fastutil.Pair; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import lombok.AllArgsConstructor; import org.checkerframework.checker.nullness.qual.Nullable; +import org.cloudburstmc.nbt.NbtList; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtType; +import org.cloudburstmc.nbt.NbtUtils; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.level.physics.BoundingBox; import org.geysermc.geyser.registry.BlockRegistries; -import org.geysermc.geyser.registry.type.BlockMapping; import org.geysermc.geyser.translator.collision.BlockCollision; import org.geysermc.geyser.translator.collision.CollisionRemapper; import org.geysermc.geyser.translator.collision.OtherCollision; @@ -51,41 +52,43 @@ import java.util.regex.Pattern; /** * Loads collision data from the given resource path. */ -public class CollisionRegistryLoader extends MultiResourceRegistryLoader> { +public class CollisionRegistryLoader extends MultiResourceRegistryLoader> { @Override - public Int2ObjectMap load(Pair input) { - Int2ObjectMap collisions = new Int2ObjectOpenHashMap<>(); - + public List load(Pair input) { Map, CollisionInfo> annotationMap = new IdentityHashMap<>(); for (Class clazz : FileUtils.getGeneratedClassesForAnnotation(CollisionRemapper.class.getName())) { GeyserImpl.getInstance().getLogger().debug("Found annotated collision translator: " + clazz.getCanonicalName()); CollisionRemapper collisionRemapper = clazz.getAnnotation(CollisionRemapper.class); - annotationMap.put(clazz, new CollisionInfo(collisionRemapper, Pattern.compile(collisionRemapper.regex()), Pattern.compile(collisionRemapper.paramRegex()))); + annotationMap.put(clazz, new CollisionInfo(collisionRemapper, Pattern.compile(collisionRemapper.regex()))); } // Load collision mappings file + int[] indices; List collisionList; try (InputStream stream = GeyserImpl.getInstance().getBootstrap().getResourceOrThrow(input.value())) { - ArrayNode collisionNode = (ArrayNode) GeyserImpl.JSON_MAPPER.readTree(stream); - collisionList = loadBoundingBoxes(collisionNode); + NbtMap collisionData = (NbtMap) NbtUtils.createGZIPReader(stream).readTag(); + indices = collisionData.getIntArray("indices"); + //SuppressWarnings unchecked + collisionList = loadBoundingBoxes(collisionData.getList("collisions", NbtType.LIST)); } catch (Exception e) { throw new AssertionError("Unable to load collision data", e); } - BlockMapping[] blockMappings = BlockRegistries.JAVA_BLOCKS.get(); + List blockStates = BlockRegistries.BLOCK_STATES.get(); + List collisions = new ObjectArrayList<>(blockStates.size()); // Map of unique collisions to its instance Map collisionInstances = new Object2ObjectOpenHashMap<>(); - for (int i = 0; i < blockMappings.length; i++) { - BlockMapping blockMapping = blockMappings[i]; - if (blockMapping == null) { - GeyserImpl.getInstance().getLogger().warning("Missing block mapping for Java block " + i); + for (int i = 0; i < blockStates.size(); i++) { + BlockState state = blockStates.get(i); + if (state == null) { + GeyserImpl.getInstance().getLogger().warning("Missing block state for Java block " + i); continue; } - BlockCollision newCollision = instantiateCollision(blockMapping, annotationMap, collisionList); + BlockCollision newCollision = instantiateCollision(state, annotationMap, indices[i], collisionList); if (newCollision != null) { // If there's an existing instance equal to this one, use that instead @@ -97,33 +100,27 @@ public class CollisionRegistryLoader extends MultiResourceRegistryLoader, CollisionInfo> annotationMap, List collisionList) { - String[] blockIdParts = mapping.getJavaIdentifier().split("\\["); - String blockName = blockIdParts[0].replace("minecraft:", ""); - String params = ""; - if (blockIdParts.length == 2) { - params = "[" + blockIdParts[1]; - } - int collisionIndex = mapping.getCollisionIndex(); + private @Nullable BlockCollision instantiateCollision(BlockState state, Map, CollisionInfo> annotationMap, int collisionIndex, List collisionList) { + String blockName = state.block().javaIdentifier().substring("minecraft:".length()); for (Map.Entry, CollisionInfo> collisionRemappers : annotationMap.entrySet()) { Class type = collisionRemappers.getKey(); CollisionInfo collisionInfo = collisionRemappers.getValue(); CollisionRemapper annotation = collisionInfo.collisionRemapper; - if (collisionInfo.pattern.matcher(blockName).find() && collisionInfo.paramsPattern.matcher(params).find()) { + if (collisionInfo.pattern.matcher(blockName).find()) { try { if (annotation.passDefaultBoxes()) { // Create an OtherCollision instance and get the bounding boxes BoundingBox[] defaultBoxes = collisionList.get(collisionIndex); - return (BlockCollision) type.getDeclaredConstructor(String.class, BoundingBox[].class).newInstance(params, defaultBoxes); + return (BlockCollision) type.getDeclaredConstructor(BlockState.class, BoundingBox[].class).newInstance(state, defaultBoxes); } else { - return (BlockCollision) type.getDeclaredConstructor(String.class).newInstance(params); + return (BlockCollision) type.getDeclaredConstructor(BlockState.class).newInstance(state); } } catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) { throw new RuntimeException(e); @@ -138,25 +135,25 @@ public class CollisionRegistryLoader extends MultiResourceRegistryLoader loadBoundingBoxes(ArrayNode collisionNode) { + private List loadBoundingBoxes(List collisionNode) { List collisions = new ObjectArrayList<>(); for (int collisionIndex = 0; collisionIndex < collisionNode.size(); collisionIndex++) { - ArrayNode boundingBoxArray = (ArrayNode) collisionNode.get(collisionIndex); + @SuppressWarnings("unchecked") NbtList> boundingBoxArray = (NbtList>) collisionNode.get(collisionIndex); BoundingBox[] boundingBoxes = new BoundingBox[boundingBoxArray.size()]; for (int i = 0; i < boundingBoxArray.size(); i++) { - ArrayNode boxProperties = (ArrayNode) boundingBoxArray.get(i); - boundingBoxes[i] = new BoundingBox(boxProperties.get(0).asDouble(), - boxProperties.get(1).asDouble(), - boxProperties.get(2).asDouble(), - boxProperties.get(3).asDouble(), - boxProperties.get(4).asDouble(), - boxProperties.get(5).asDouble()); + NbtList boxProperties = boundingBoxArray.get(i); + boundingBoxes[i] = new BoundingBox(boxProperties.get(0), + boxProperties.get(1), + boxProperties.get(2), + boxProperties.get(3), + boxProperties.get(4), + boxProperties.get(5)); } // Sorting by lowest Y first fixes some bugs @@ -173,6 +170,5 @@ public class CollisionRegistryLoader extends MultiResourceRegistryLoader cleanIdentifiers = new ArrayDeque<>(); int javaRuntimeId = -1; - int cobwebBlockId = -1; int furnaceRuntimeId = -1; int furnaceLitRuntimeId = -1; int honeyBlockRuntimeId = -1; @@ -485,10 +484,7 @@ public final class BlockRegistryPopulator { // It's possible to only have this store differences in names, but the key set of all Java names is used in sending command suggestions BlockRegistries.JAVA_TO_BEDROCK_IDENTIFIERS.register(cleanJavaIdentifier.intern(), bedrockIdentifier.intern()); - if (javaId.contains("cobweb")) { - cobwebBlockId = uniqueJavaId; - - } else if (javaId.startsWith("minecraft:furnace[facing=north")) { + if (javaId.startsWith("minecraft:furnace[facing=north")) { if (javaId.contains("lit=true")) { furnaceLitRuntimeId = javaRuntimeId; } else { @@ -507,11 +503,6 @@ public final class BlockRegistryPopulator { } } - if (cobwebBlockId == -1) { - throw new AssertionError("Unable to find cobwebs in palette"); - } - BlockStateValues.JAVA_COBWEB_ID = cobwebBlockId; - if (furnaceRuntimeId == -1) { throw new AssertionError("Unable to find furnace in palette"); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/collision/CollisionRemapper.java b/core/src/main/java/org/geysermc/geyser/translator/collision/CollisionRemapper.java index 6980968ab..fb93a14d5 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/collision/CollisionRemapper.java +++ b/core/src/main/java/org/geysermc/geyser/translator/collision/CollisionRemapper.java @@ -37,12 +37,6 @@ public @interface CollisionRemapper { */ String regex(); - /** - * Regex of block state parameters to apply this collision to - * Defaults to matching any value - */ - String paramRegex() default ".*"; - /** * Signals if a new instance needs to created for every block state */ diff --git a/core/src/main/java/org/geysermc/geyser/translator/collision/DirtPathCollision.java b/core/src/main/java/org/geysermc/geyser/translator/collision/DirtPathCollision.java index dcbad4758..d44187a0c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/collision/DirtPathCollision.java +++ b/core/src/main/java/org/geysermc/geyser/translator/collision/DirtPathCollision.java @@ -26,13 +26,14 @@ package org.geysermc.geyser.translator.collision; import lombok.EqualsAndHashCode; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.level.physics.BoundingBox; import org.geysermc.geyser.level.physics.CollisionManager; @EqualsAndHashCode(callSuper = true) @CollisionRemapper(regex = "^dirt_path$", passDefaultBoxes = true) public class DirtPathCollision extends BlockCollision { - public DirtPathCollision(String params, BoundingBox[] defaultBoxes) { + public DirtPathCollision(BlockState state, BoundingBox[] defaultBoxes) { super(defaultBoxes); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/collision/DoorCollision.java b/core/src/main/java/org/geysermc/geyser/translator/collision/DoorCollision.java index b47b187c4..33c85ce07 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/collision/DoorCollision.java +++ b/core/src/main/java/org/geysermc/geyser/translator/collision/DoorCollision.java @@ -26,6 +26,8 @@ package org.geysermc.geyser.translator.collision; import lombok.EqualsAndHashCode; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.level.physics.BoundingBox; import org.geysermc.geyser.session.GeyserSession; @@ -40,20 +42,18 @@ public class DoorCollision extends BlockCollision { */ private int facing; - public DoorCollision(String params, BoundingBox[] defaultBoxes) { + public DoorCollision(BlockState state, BoundingBox[] defaultBoxes) { super(defaultBoxes); - if (params.contains("facing=north")) { - facing = 1; - } else if (params.contains("facing=east")) { - facing = 2; - } else if (params.contains("facing=south")) { - facing = 3; - } else if (params.contains("facing=west")) { - facing = 4; - } + facing = switch (state.getValue(Properties.HORIZONTAL_FACING)) { + case NORTH -> 1; + case EAST -> 2; + case SOUTH -> 3; + case WEST -> 4; + default -> throw new IllegalStateException(); + }; // If the door is open it changes direction - if (params.contains("open=true")) { + if (state.getValue(Properties.OPEN)) { facing = facing % 2 + 1; } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/collision/GlassPaneAndIronBarsCollision.java b/core/src/main/java/org/geysermc/geyser/translator/collision/GlassPaneAndIronBarsCollision.java index 14439645a..35874348c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/collision/GlassPaneAndIronBarsCollision.java +++ b/core/src/main/java/org/geysermc/geyser/translator/collision/GlassPaneAndIronBarsCollision.java @@ -26,6 +26,8 @@ package org.geysermc.geyser.translator.collision; import lombok.EqualsAndHashCode; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.level.physics.BoundingBox; import org.geysermc.geyser.session.GeyserSession; @@ -44,24 +46,23 @@ public class GlassPaneAndIronBarsCollision extends BlockCollision { */ private int facing; - public GlassPaneAndIronBarsCollision(String params, BoundingBox[] defaultBoxes) { + public GlassPaneAndIronBarsCollision(BlockState state, BoundingBox[] defaultBoxes) { super(defaultBoxes); - //east=true,north=true,south=true,west=true - if (params.contains("north=true") && params.contains("east=true")) { + if (state.getValue(Properties.NORTH) && state.getValue(Properties.EAST)) { facing = 5; - } else if (params.contains("east=true") && params.contains("south=true")) { + } else if (state.getValue(Properties.EAST) && state.getValue(Properties.SOUTH)) { facing = 6; - } else if (params.contains("south=true") && params.contains("west=true")) { + } else if (state.getValue(Properties.SOUTH) && state.getValue(Properties.WEST)) { facing = 7; - } else if (params.contains("west=true") && params.contains("north=true")) { + } else if (state.getValue(Properties.WEST) && state.getValue(Properties.NORTH)) { facing = 8; - } else if (params.contains("north=true")) { + } else if (state.getValue(Properties.NORTH)) { facing = 1; - } else if (params.contains("east=true")) { + } else if (state.getValue(Properties.EAST)) { facing = 2; - } else if (params.contains("south=true")) { + } else if (state.getValue(Properties.SOUTH)) { facing = 3; - } else if (params.contains("west=true")) { + } else if (state.getValue(Properties.WEST)) { facing = 4; } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/collision/ScaffoldingCollision.java b/core/src/main/java/org/geysermc/geyser/translator/collision/ScaffoldingCollision.java index dfbd1c8b8..7449987c6 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/collision/ScaffoldingCollision.java +++ b/core/src/main/java/org/geysermc/geyser/translator/collision/ScaffoldingCollision.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.translator.collision; import lombok.EqualsAndHashCode; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.level.physics.BoundingBox; import org.geysermc.geyser.session.GeyserSession; @@ -35,7 +36,7 @@ import org.geysermc.geyser.session.GeyserSession; @EqualsAndHashCode(callSuper = true) @CollisionRemapper(regex = "^scaffolding$", usesParams = true, passDefaultBoxes = true) public class ScaffoldingCollision extends BlockCollision { - public ScaffoldingCollision(String params, BoundingBox[] defaultBoxes) { + public ScaffoldingCollision(BlockState state, BoundingBox[] defaultBoxes) { super(defaultBoxes); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/collision/SolidCollision.java b/core/src/main/java/org/geysermc/geyser/translator/collision/SolidCollision.java index 822202ff2..51d1038c0 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/collision/SolidCollision.java +++ b/core/src/main/java/org/geysermc/geyser/translator/collision/SolidCollision.java @@ -26,12 +26,13 @@ package org.geysermc.geyser.translator.collision; import lombok.EqualsAndHashCode; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.level.physics.BoundingBox; @EqualsAndHashCode(callSuper = true) @CollisionRemapper(regex = "shulker_box$") // These have no collision in the mappings as it depends on the NBT data public class SolidCollision extends BlockCollision { - public SolidCollision(String params) { + public SolidCollision(BlockState state) { super(new BoundingBox[] { new BoundingBox(0.5, 0.5, 0.5, 1, 1, 1) }); diff --git a/core/src/main/java/org/geysermc/geyser/translator/collision/TrapdoorCollision.java b/core/src/main/java/org/geysermc/geyser/translator/collision/TrapdoorCollision.java index 836c05711..909761166 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/collision/TrapdoorCollision.java +++ b/core/src/main/java/org/geysermc/geyser/translator/collision/TrapdoorCollision.java @@ -26,42 +26,27 @@ package org.geysermc.geyser.translator.collision; import lombok.EqualsAndHashCode; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.level.physics.BoundingBox; import org.geysermc.geyser.level.physics.CollisionManager; +import org.geysermc.geyser.level.physics.Direction; import org.geysermc.geyser.session.GeyserSession; @EqualsAndHashCode(callSuper = true) @CollisionRemapper(regex = "_trapdoor$", usesParams = true, passDefaultBoxes = true) public class TrapdoorCollision extends BlockCollision { - /** - * 1 = north - * 2 = east - * 3 = south - * 4 = west - * 5 = up - * 6 = down - */ - private int facing; + private final Direction facing; - public TrapdoorCollision(String params, BoundingBox[] defaultBoxes) { + public TrapdoorCollision(BlockState state, BoundingBox[] defaultBoxes) { super(defaultBoxes); - if (params.contains("open=true")) { - if (params.contains("facing=north")) { - facing = 1; - } else if (params.contains("facing=east")) { - facing = 2; - } else if (params.contains("facing=south")) { - facing = 3; - } else if (params.contains("facing=west")) { - facing = 4; - } + if (state.getValue(Properties.OPEN)) { + facing = state.getValue(Properties.HORIZONTAL_FACING); } else { - if (params.contains("half=bottom")) { - // Up - facing = 5; + if (state.getValue(Properties.HALF).equals("bottom")) { + facing = Direction.UP; } else { - // Down - facing = 6; + facing = Direction.DOWN; } } } @@ -72,22 +57,22 @@ public class TrapdoorCollision extends BlockCollision { // Check for door bug (doors are 0.1875 blocks thick on Java but 0.1825 blocks thick on Bedrock) if (this.checkIntersection(x, y, z, playerCollision)) { switch (facing) { - case 1: // North + case NORTH: playerCollision.setMiddleZ(z + 0.5125); break; - case 2: // East + case EAST: playerCollision.setMiddleX(x + 0.5125); break; - case 3: // South + case SOUTH: playerCollision.setMiddleZ(z + 0.4875); break; - case 4: // West + case WEST: playerCollision.setMiddleX(x + 0.4875); break; - case 5: + case UP: // Up-facing trapdoors are handled by the step-up check break; - case 6: // Down + case DOWN: // (top y of trap door) - (trap door thickness) = top y of player playerCollision.setMiddleY(y + 1 - (3.0 / 16.0) - playerCollision.getSizeY() / 2.0 - CollisionManager.COLLISION_TOLERANCE); break; diff --git a/core/src/main/resources/mappings b/core/src/main/resources/mappings index 7c01501ed..6b661f0d5 160000 --- a/core/src/main/resources/mappings +++ b/core/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 7c01501ed6a0ee8848a66d729000539f2661f785 +Subproject commit 6b661f0d517d895aebc1f55a25d2c86f033beb1d From beef01f3fc96befb0558b070c34dd04400fb4eec Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Fri, 17 May 2024 20:55:34 -0400 Subject: [PATCH 172/272] Pistons now use the new block stuff --- .../erosion/GeyserboundPacketHandlerImpl.java | 13 +- .../geysermc/geyser/level/WorldManager.java | 9 + .../geyser/level/block/BlockStateValues.java | 98 +-- .../geysermc/geyser/level/block/Blocks.java | 704 +++++++++--------- .../level/block/property/Properties.java | 2 +- .../geyser/level/block/type/Block.java | 86 +++ .../geyser/level/block/type/BlockState.java | 4 + .../level/block/type/CauldronBlock.java | 51 ++ .../geyser/level/block/type/ChestBlock.java | 52 ++ .../geyser/level/block/type/DoorBlock.java | 50 ++ .../block/type/FlowerPotBlock.java} | 74 +- .../geyser/level/block/type/LecternBlock.java | 61 ++ .../level/block/type/MovingPistonBlock.java | 42 ++ .../geyser/level/block/type/PistonBlock.java | 47 ++ .../geyser/level/block/type/SkullBlock.java | 54 ++ .../populator/BlockRegistryPopulator.java | 40 +- .../geyser/registry/type/BlockMapping.java | 15 +- .../geyser/registry/type/BlockMappings.java | 5 + .../geyser/session/cache/TagCache.java | 12 - .../geyser/session/cache/WorldCache.java | 2 +- ...a => BedrockChunkWantsBlockEntityTag.java} | 30 +- .../block/entity/BedrockOnlyBlockEntity.java | 82 -- .../DoubleChestBlockEntityTranslator.java | 21 +- .../level/block/entity/PistonBlockEntity.java | 85 +-- .../BedrockBlockPickRequestTranslator.java | 4 +- .../java/level/JavaBlockEventTranslator.java | 22 +- .../JavaLevelChunkWithLightTranslator.java | 19 +- .../geyser/util/BlockEntityUtils.java | 12 - .../org/geysermc/geyser/util/ChunkUtils.java | 111 +-- 29 files changed, 978 insertions(+), 829 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/type/CauldronBlock.java create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/type/ChestBlock.java create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/type/DoorBlock.java rename core/src/main/java/org/geysermc/geyser/{translator/level/block/entity/FlowerPotBlockEntityTranslator.java => level/block/type/FlowerPotBlock.java} (60%) create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/type/LecternBlock.java create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/type/MovingPistonBlock.java create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/type/PistonBlock.java create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/type/SkullBlock.java rename core/src/main/java/org/geysermc/geyser/translator/level/block/entity/{PistonBlockEntityTranslator.java => BedrockChunkWantsBlockEntityTag.java} (59%) delete mode 100644 core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedrockOnlyBlockEntity.java diff --git a/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java b/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java index b76dc0b85..6e22fd430 100644 --- a/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java +++ b/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java @@ -26,11 +26,12 @@ package org.geysermc.geyser.erosion; import io.netty.channel.Channel; +import it.unimi.dsi.fastutil.Pair; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -import it.unimi.dsi.fastutil.objects.Object2IntArrayMap; -import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import lombok.Getter; import lombok.Setter; import org.cloudburstmc.math.vector.Vector3i; @@ -44,6 +45,7 @@ import org.geysermc.erosion.packet.backendbound.BackendboundPacket; import org.geysermc.erosion.packet.geyserbound.*; import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.type.Block; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.level.physics.Direction; import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.session.GeyserSession; @@ -153,9 +155,10 @@ public final class GeyserboundPacketHandlerImpl extends AbstractGeyserboundPacke var stream = packet.getAttachedBlocks() .object2IntEntrySet() .stream() - .filter(entry -> BlockStateValues.canPistonMoveBlock(entry.getIntValue(), isExtend)); - Object2IntMap attachedBlocks = new Object2IntArrayMap<>(); - stream.forEach(entry -> attachedBlocks.put(entry.getKey(), entry.getIntValue())); + .map(entry -> Pair.of(entry.getKey(), BlockState.of(entry.getIntValue()))) + .filter(pair -> BlockStateValues.canPistonMoveBlock(pair.value(), isExtend)); + Object2ObjectMap attachedBlocks = new Object2ObjectOpenHashMap<>(); + stream.forEach(pair -> attachedBlocks.put(pair.key(), pair.value())); session.executeInEventLoop(() -> { PistonCache pistonCache = session.getPistonCache(); diff --git a/core/src/main/java/org/geysermc/geyser/level/WorldManager.java b/core/src/main/java/org/geysermc/geyser/level/WorldManager.java index cd6c9e824..5edce21dc 100644 --- a/core/src/main/java/org/geysermc/geyser/level/WorldManager.java +++ b/core/src/main/java/org/geysermc/geyser/level/WorldManager.java @@ -33,6 +33,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3i; import org.geysermc.erosion.util.BlockPositionIterator; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponent; @@ -58,6 +59,14 @@ import java.util.function.Function; */ public abstract class WorldManager { + public final BlockState blockAt(GeyserSession session, Vector3i vector3i) { + return BlockState.of(this.getBlockAt(session, vector3i)); + } + + public BlockState blockAt(GeyserSession session, int x, int y, int z) { + return BlockState.of(this.getBlockAt(session, x, y, z)); + } + /** * Gets the Java block state at the specified location * diff --git a/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java b/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java index e2a2cb5eb..a64e5c1c8 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java @@ -29,12 +29,14 @@ import com.fasterxml.jackson.databind.JsonNode; import it.unimi.dsi.fastutil.ints.*; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.type.Block; +import org.geysermc.geyser.level.block.type.BlockState; +import org.geysermc.geyser.level.block.type.PistonBlock; import org.geysermc.geyser.level.physics.Direction; import org.geysermc.geyser.level.physics.PistonBehavior; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.type.BlockMapping; -import org.geysermc.geyser.translator.level.block.entity.PistonBlockEntityTranslator; import org.geysermc.geyser.util.collection.FixedInt2ByteMap; import org.geysermc.geyser.util.collection.FixedInt2IntMap; import org.geysermc.geyser.util.collection.LecternHasBookMap; @@ -229,28 +231,6 @@ public final class BlockStateValues { return BANNER_COLORS.getOrDefault(state, -1); } - /** - * Bed colors are part of the namespaced ID in Java Edition, but part of the block entity tag in Bedrock. - * This gives a byte color that Bedrock can use - Bedrock needs a byte in the final tag. - * - * @param state BlockState of the block - * @return Bed color byte or -1 if no color - */ - public static byte getBedColor(int state) { - return BED_COLORS.getOrDefault(state, (byte) -1); - } - - /** - * The brush progress of suspicious sand/gravel is not sent by the java server when it updates the block entity. - * Although brush progress is part of the bedrock block state, it must be included in the block entity update. - * - * @param state BlockState of the block - * @return brush progress or 0 if the lookup failed - */ - public static int getBrushProgress(int state) { - return BRUSH_PROGRESS.getOrDefault(state, 0); - } - /** * @return if this Java block state is a non-empty non-water cauldron */ @@ -341,18 +321,6 @@ public final class BlockStateValues { return PISTON_HEADS.getOrDefault(direction, Block.JAVA_AIR_ID); } - /** - * Check if a block is a minecraft:moving_piston - * This is used in ChunkUtils to prevent them from being placed as it causes - * pistons to flicker and it is not needed - * - * @param state Block state of the block - * @return True if the block is a moving_piston - */ - public static boolean isMovingPiston(int state) { - return MOVING_PISTONS.contains(state); - } - /** * This is used in GeyserPistonEvents.java and accepts minecraft:piston, * minecraft:sticky_piston, and minecraft:moving_piston. @@ -371,8 +339,9 @@ public final class BlockStateValues { * @param state The block state * @return True if the block sticks to adjacent blocks */ - public static boolean isBlockSticky(int state) { - return state == JAVA_SLIME_BLOCK_ID || state == JAVA_HONEY_BLOCK_ID; + public static boolean isBlockSticky(BlockState state) { + Block block = state.block(); + return block == Blocks.SLIME_BLOCK || block == Blocks.HONEY_BLOCK; } /** @@ -382,13 +351,13 @@ public final class BlockStateValues { * @param stateB The block state of block b * @return True if the blocks are attached to each other */ - public static boolean isBlockAttached(int stateA, int stateB) { + public static boolean isBlockAttached(BlockState stateA, BlockState stateB) { boolean aSticky = isBlockSticky(stateA); boolean bSticky = isBlockSticky(stateB); if (aSticky && bSticky) { // Only matching sticky blocks are attached together // Honey + Honey & Slime + Slime - return stateA == stateB; + return stateA.block() == stateB.block(); } return aSticky || bSticky; } @@ -397,27 +366,30 @@ public final class BlockStateValues { * @param state The block state of the block * @return true if a piston can break the block */ - public static boolean canPistonDestroyBlock(int state) { - return BlockRegistries.JAVA_BLOCKS.getOrDefault(state, BlockMapping.DEFAULT).getPistonBehavior() == PistonBehavior.DESTROY; + public static boolean canPistonDestroyBlock(BlockState state) { + return state.block().pushReaction() == PistonBehavior.DESTROY; } - public static boolean canPistonMoveBlock(int javaId, boolean isPushing) { - if (javaId == Block.JAVA_AIR_ID) { + public static boolean canPistonMoveBlock(BlockState state, boolean isPushing) { + Block block = state.block(); + if (block == Blocks.AIR) { return true; } - // Pistons can only be moved if they aren't extended - if (PistonBlockEntityTranslator.isBlock(javaId)) { - return !PISTON_VALUES.get(javaId); - } - BlockMapping block = BlockRegistries.JAVA_BLOCKS.getOrDefault(javaId, BlockMapping.DEFAULT); - // Bedrock, End portal frames, etc. can't be moved - if (block.getHardness() == -1.0d) { + if (block == Blocks.OBSIDIAN || block == Blocks.CRYING_OBSIDIAN || block == Blocks.RESPAWN_ANCHOR || block == Blocks.REINFORCED_DEEPSLATE) { // Hardcoded as of 1.20.5 return false; } - return switch (block.getPistonBehavior()) { + // Pistons can only be moved if they aren't extended + if (block instanceof PistonBlock) { + return !state.getValue(Properties.EXTENDED); + } + // Bedrock, End portal frames, etc. can't be moved + if (block.destroyTime() == -1.0f) { + return false; + } + return switch (block.pushReaction()) { case BLOCK, DESTROY -> false; case PUSH_ONLY -> isPushing; // Glazed terracotta can only be pushed - default -> !block.isBlockEntity(); // Pistons can't move block entities + default -> !block.hasBlockEntity(); // Pistons can't move block entities }; } @@ -443,17 +415,6 @@ public final class BlockStateValues { return SKULL_ROTATIONS.getOrDefault(state, (byte) -1); } - /** - * As of Java 1.20.2: - * Skull powered states are part of the namespaced ID in Java Edition, but part of the block entity tag in Bedrock. - * - * @param state BlockState of the block - * @return true if this skull is currently being powered. - */ - public static boolean isSkullPowered(int state) { - return SKULL_POWERED.contains(state); - } - /** * Skull rotations are part of the namespaced ID in Java Edition, but part of the block entity tag in Bedrock. * This gives a integer rotation that Bedrock can use. @@ -464,17 +425,6 @@ public final class BlockStateValues { return SKULL_WALL_DIRECTIONS; } - /** - * Shulker box directions are part of the namespaced ID in Java Edition, but part of the block entity tag in Bedrock. - * This gives a byte direction that Bedrock can use. - * - * @param state BlockState of the block - * @return Shulker direction value or -1 if no value - */ - public static byte getShulkerBoxDirection(int state) { - return SHULKERBOX_DIRECTIONS.getOrDefault(state, (byte) -1); - } - /** * Get the level of water from the block state. * diff --git a/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java b/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java index 1f9c9c162..142708dd9 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.level.block; -import org.geysermc.geyser.level.block.type.BannerBlock; -import org.geysermc.geyser.level.block.type.BedBlock; -import org.geysermc.geyser.level.block.type.Block; +import org.geysermc.geyser.level.block.property.ChestType; +import org.geysermc.geyser.level.block.type.*; import org.geysermc.geyser.level.physics.Axis; import org.geysermc.geyser.level.physics.Direction; +import org.geysermc.geyser.level.physics.PistonBehavior; import org.geysermc.geyser.registry.BlockRegistries; import static org.geysermc.geyser.level.block.property.Properties.*; @@ -62,36 +62,36 @@ public final class Blocks { public static final Block MANGROVE_PLANKS = register(new Block("mangrove_planks", builder().destroyTime(2.0f))); public static final Block BAMBOO_PLANKS = register(new Block("bamboo_planks", builder().destroyTime(2.0f))); public static final Block BAMBOO_MOSAIC = register(new Block("bamboo_mosaic", builder().destroyTime(2.0f))); - public static final Block OAK_SAPLING = register(new Block("oak_sapling", builder() + public static final Block OAK_SAPLING = register(new Block("oak_sapling", builder().pushReaction(PistonBehavior.DESTROY) .intState(STAGE, 0, 1))); - public static final Block SPRUCE_SAPLING = register(new Block("spruce_sapling", builder() + public static final Block SPRUCE_SAPLING = register(new Block("spruce_sapling", builder().pushReaction(PistonBehavior.DESTROY) .intState(STAGE, 0, 1))); - public static final Block BIRCH_SAPLING = register(new Block("birch_sapling", builder() + public static final Block BIRCH_SAPLING = register(new Block("birch_sapling", builder().pushReaction(PistonBehavior.DESTROY) .intState(STAGE, 0, 1))); - public static final Block JUNGLE_SAPLING = register(new Block("jungle_sapling", builder() + public static final Block JUNGLE_SAPLING = register(new Block("jungle_sapling", builder().pushReaction(PistonBehavior.DESTROY) .intState(STAGE, 0, 1))); - public static final Block ACACIA_SAPLING = register(new Block("acacia_sapling", builder() + public static final Block ACACIA_SAPLING = register(new Block("acacia_sapling", builder().pushReaction(PistonBehavior.DESTROY) .intState(STAGE, 0, 1))); - public static final Block CHERRY_SAPLING = register(new Block("cherry_sapling", builder() + public static final Block CHERRY_SAPLING = register(new Block("cherry_sapling", builder().pushReaction(PistonBehavior.DESTROY) .intState(STAGE, 0, 1))); - public static final Block DARK_OAK_SAPLING = register(new Block("dark_oak_sapling", builder() + public static final Block DARK_OAK_SAPLING = register(new Block("dark_oak_sapling", builder().pushReaction(PistonBehavior.DESTROY) .intState(STAGE, 0, 1))); - public static final Block MANGROVE_PROPAGULE = register(new Block("mangrove_propagule", builder() + public static final Block MANGROVE_PROPAGULE = register(new Block("mangrove_propagule", builder().pushReaction(PistonBehavior.DESTROY) .intState(AGE_4, 0, 4) .booleanState(HANGING) .intState(STAGE, 0, 1) .booleanState(WATERLOGGED))); public static final Block BEDROCK = register(new Block("bedrock", builder().destroyTime(-1.0f))); - public static final Block WATER = register(new Block("water", builder().destroyTime(100.0f) + public static final Block WATER = register(new Block("water", builder().destroyTime(100.0f).pushReaction(PistonBehavior.DESTROY) .intState(LEVEL, 0, 15))); - public static final Block LAVA = register(new Block("lava", builder().destroyTime(100.0f) + public static final Block LAVA = register(new Block("lava", builder().destroyTime(100.0f).pushReaction(PistonBehavior.DESTROY) .intState(LEVEL, 0, 15))); public static final Block SAND = register(new Block("sand", builder().destroyTime(0.5f))); - public static final Block SUSPICIOUS_SAND = register(new Block("suspicious_sand", builder().setBlockEntity().destroyTime(0.25f) + public static final Block SUSPICIOUS_SAND = register(new Block("suspicious_sand", builder().setBlockEntity().destroyTime(0.25f).pushReaction(PistonBehavior.DESTROY) .intState(DUSTED, 0, 3))); public static final Block RED_SAND = register(new Block("red_sand", builder().destroyTime(0.5f))); public static final Block GRAVEL = register(new Block("gravel", builder().destroyTime(0.6f))); - public static final Block SUSPICIOUS_GRAVEL = register(new Block("suspicious_gravel", builder().setBlockEntity().destroyTime(0.25f) + public static final Block SUSPICIOUS_GRAVEL = register(new Block("suspicious_gravel", builder().setBlockEntity().destroyTime(0.25f).pushReaction(PistonBehavior.DESTROY) .intState(DUSTED, 0, 3))); public static final Block GOLD_ORE = register(new Block("gold_ore", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); public static final Block DEEPSLATE_GOLD_ORE = register(new Block("deepslate_gold_ore", builder().requiresCorrectToolForDrops().destroyTime(4.5f))); @@ -172,43 +172,43 @@ public final class Blocks { .enumState(AXIS, Axis.VALUES))); public static final Block STRIPPED_MANGROVE_WOOD = register(new Block("stripped_mangrove_wood", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block OAK_LEAVES = register(new Block("oak_leaves", builder().destroyTime(0.2f) + public static final Block OAK_LEAVES = register(new Block("oak_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .intState(DISTANCE, 1, 7) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); - public static final Block SPRUCE_LEAVES = register(new Block("spruce_leaves", builder().destroyTime(0.2f) + public static final Block SPRUCE_LEAVES = register(new Block("spruce_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .intState(DISTANCE, 1, 7) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); - public static final Block BIRCH_LEAVES = register(new Block("birch_leaves", builder().destroyTime(0.2f) + public static final Block BIRCH_LEAVES = register(new Block("birch_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .intState(DISTANCE, 1, 7) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); - public static final Block JUNGLE_LEAVES = register(new Block("jungle_leaves", builder().destroyTime(0.2f) + public static final Block JUNGLE_LEAVES = register(new Block("jungle_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .intState(DISTANCE, 1, 7) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); - public static final Block ACACIA_LEAVES = register(new Block("acacia_leaves", builder().destroyTime(0.2f) + public static final Block ACACIA_LEAVES = register(new Block("acacia_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .intState(DISTANCE, 1, 7) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); - public static final Block CHERRY_LEAVES = register(new Block("cherry_leaves", builder().destroyTime(0.2f) + public static final Block CHERRY_LEAVES = register(new Block("cherry_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .intState(DISTANCE, 1, 7) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); - public static final Block DARK_OAK_LEAVES = register(new Block("dark_oak_leaves", builder().destroyTime(0.2f) + public static final Block DARK_OAK_LEAVES = register(new Block("dark_oak_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .intState(DISTANCE, 1, 7) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); - public static final Block MANGROVE_LEAVES = register(new Block("mangrove_leaves", builder().destroyTime(0.2f) + public static final Block MANGROVE_LEAVES = register(new Block("mangrove_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .intState(DISTANCE, 1, 7) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); - public static final Block AZALEA_LEAVES = register(new Block("azalea_leaves", builder().destroyTime(0.2f) + public static final Block AZALEA_LEAVES = register(new Block("azalea_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .intState(DISTANCE, 1, 7) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); - public static final Block FLOWERING_AZALEA_LEAVES = register(new Block("flowering_azalea_leaves", builder().destroyTime(0.2f) + public static final Block FLOWERING_AZALEA_LEAVES = register(new Block("flowering_azalea_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .intState(DISTANCE, 1, 7) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); @@ -228,67 +228,67 @@ public final class Blocks { .enumState(NOTEBLOCK_INSTRUMENT, "harp", "basedrum", "snare", "hat", "bass", "flute", "bell", "guitar", "chime", "xylophone", "iron_xylophone", "cow_bell", "didgeridoo", "bit", "banjo", "pling", "zombie", "skeleton", "creeper", "dragon", "wither_skeleton", "piglin", "custom_head") .intState(NOTE, 0, 24) .booleanState(POWERED))); - public static final Block WHITE_BED = register(new BedBlock("white_bed", 0, builder().setBlockEntity().destroyTime(0.2f) + public static final Block WHITE_BED = register(new BedBlock("white_bed", 0, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block ORANGE_BED = register(new BedBlock("orange_bed", 1, builder().setBlockEntity().destroyTime(0.2f) + public static final Block ORANGE_BED = register(new BedBlock("orange_bed", 1, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block MAGENTA_BED = register(new BedBlock("magenta_bed", 2, builder().setBlockEntity().destroyTime(0.2f) + public static final Block MAGENTA_BED = register(new BedBlock("magenta_bed", 2, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block LIGHT_BLUE_BED = register(new BedBlock("light_blue_bed", 3, builder().setBlockEntity().destroyTime(0.2f) + public static final Block LIGHT_BLUE_BED = register(new BedBlock("light_blue_bed", 3, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block YELLOW_BED = register(new BedBlock("yellow_bed", 4, builder().setBlockEntity().destroyTime(0.2f) + public static final Block YELLOW_BED = register(new BedBlock("yellow_bed", 4, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block LIME_BED = register(new BedBlock("lime_bed", 5, builder().setBlockEntity().destroyTime(0.2f) + public static final Block LIME_BED = register(new BedBlock("lime_bed", 5, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block PINK_BED = register(new BedBlock("pink_bed", 6, builder().setBlockEntity().destroyTime(0.2f) + public static final Block PINK_BED = register(new BedBlock("pink_bed", 6, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block GRAY_BED = register(new BedBlock("gray_bed", 7, builder().setBlockEntity().destroyTime(0.2f) + public static final Block GRAY_BED = register(new BedBlock("gray_bed", 7, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block LIGHT_GRAY_BED = register(new BedBlock("light_gray_bed", 8, builder().setBlockEntity().destroyTime(0.2f) + public static final Block LIGHT_GRAY_BED = register(new BedBlock("light_gray_bed", 8, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block CYAN_BED = register(new BedBlock("cyan_bed", 9, builder().setBlockEntity().destroyTime(0.2f) + public static final Block CYAN_BED = register(new BedBlock("cyan_bed", 9, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block PURPLE_BED = register(new BedBlock("purple_bed", 10, builder().setBlockEntity().destroyTime(0.2f) + public static final Block PURPLE_BED = register(new BedBlock("purple_bed", 10, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block BLUE_BED = register(new BedBlock("blue_bed", 11, builder().setBlockEntity().destroyTime(0.2f) + public static final Block BLUE_BED = register(new BedBlock("blue_bed", 11, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block BROWN_BED = register(new BedBlock("brown_bed", 12, builder().setBlockEntity().destroyTime(0.2f) + public static final Block BROWN_BED = register(new BedBlock("brown_bed", 12, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block GREEN_BED = register(new BedBlock("green_bed", 13, builder().setBlockEntity().destroyTime(0.2f) + public static final Block GREEN_BED = register(new BedBlock("green_bed", 13, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block RED_BED = register(new BedBlock("red_bed", 14, builder().setBlockEntity().destroyTime(0.2f) + public static final Block RED_BED = register(new BedBlock("red_bed", 14, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); - public static final Block BLACK_BED = register(new BedBlock("black_bed", 15, builder().setBlockEntity().destroyTime(0.2f) + public static final Block BLACK_BED = register(new BedBlock("black_bed", 15, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) .enumState(BED_PART, "head", "foot"))); @@ -300,20 +300,20 @@ public final class Blocks { .booleanState(POWERED) .enumState(RAIL_SHAPE_STRAIGHT, "north_south", "east_west", "ascending_east", "ascending_west", "ascending_north", "ascending_south") .booleanState(WATERLOGGED))); - public static final Block STICKY_PISTON = register(new Block("sticky_piston", builder().destroyTime(1.5f) + public static final Block STICKY_PISTON = register(new PistonBlock("sticky_piston", builder().destroyTime(1.5f).pushReaction(PistonBehavior.BLOCK) .booleanState(EXTENDED) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block COBWEB = register(new Block("cobweb", builder().requiresCorrectToolForDrops().destroyTime(4.0f))); - public static final Block SHORT_GRASS = register(new Block("short_grass", builder())); - public static final Block FERN = register(new Block("fern", builder())); - public static final Block DEAD_BUSH = register(new Block("dead_bush", builder())); - public static final Block SEAGRASS = register(new Block("seagrass", builder())); - public static final Block TALL_SEAGRASS = register(new Block("tall_seagrass", builder() + public static final Block COBWEB = register(new Block("cobweb", builder().requiresCorrectToolForDrops().destroyTime(4.0f).pushReaction(PistonBehavior.DESTROY))); + public static final Block SHORT_GRASS = register(new Block("short_grass", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block FERN = register(new Block("fern", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block DEAD_BUSH = register(new Block("dead_bush", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block SEAGRASS = register(new Block("seagrass", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block TALL_SEAGRASS = register(new Block("tall_seagrass", builder().pushReaction(PistonBehavior.DESTROY) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); - public static final Block PISTON = register(new Block("piston", builder().destroyTime(1.5f) + public static final Block PISTON = register(new PistonBlock("piston", builder().destroyTime(1.5f).pushReaction(PistonBehavior.BLOCK) .booleanState(EXTENDED) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block PISTON_HEAD = register(new Block("piston_head", builder().destroyTime(1.5f) + public static final Block PISTON_HEAD = register(new Block("piston_head", builder().destroyTime(1.5f).pushReaction(PistonBehavior.BLOCK) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) .booleanState(SHORT) .enumState(PISTON_TYPE, "normal", "sticky"))); @@ -333,25 +333,25 @@ public final class Blocks { public static final Block GREEN_WOOL = register(new Block("green_wool", builder().destroyTime(0.8f))); public static final Block RED_WOOL = register(new Block("red_wool", builder().destroyTime(0.8f))); public static final Block BLACK_WOOL = register(new Block("black_wool", builder().destroyTime(0.8f))); - public static final Block MOVING_PISTON = register(new Block("moving_piston", builder().setBlockEntity().destroyTime(-1.0f) + public static final Block MOVING_PISTON = register(new MovingPistonBlock("moving_piston", builder().setBlockEntity().destroyTime(-1.0f).pushReaction(PistonBehavior.BLOCK) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) .enumState(PISTON_TYPE, "normal", "sticky"))); - public static final Block DANDELION = register(new Block("dandelion", builder())); - public static final Block TORCHFLOWER = register(new Block("torchflower", builder())); - public static final Block POPPY = register(new Block("poppy", builder())); - public static final Block BLUE_ORCHID = register(new Block("blue_orchid", builder())); - public static final Block ALLIUM = register(new Block("allium", builder())); - public static final Block AZURE_BLUET = register(new Block("azure_bluet", builder())); - public static final Block RED_TULIP = register(new Block("red_tulip", builder())); - public static final Block ORANGE_TULIP = register(new Block("orange_tulip", builder())); - public static final Block WHITE_TULIP = register(new Block("white_tulip", builder())); - public static final Block PINK_TULIP = register(new Block("pink_tulip", builder())); - public static final Block OXEYE_DAISY = register(new Block("oxeye_daisy", builder())); - public static final Block CORNFLOWER = register(new Block("cornflower", builder())); - public static final Block WITHER_ROSE = register(new Block("wither_rose", builder())); - public static final Block LILY_OF_THE_VALLEY = register(new Block("lily_of_the_valley", builder())); - public static final Block BROWN_MUSHROOM = register(new Block("brown_mushroom", builder())); - public static final Block RED_MUSHROOM = register(new Block("red_mushroom", builder())); + public static final Block DANDELION = register(new Block("dandelion", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block TORCHFLOWER = register(new Block("torchflower", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POPPY = register(new Block("poppy", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block BLUE_ORCHID = register(new Block("blue_orchid", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block ALLIUM = register(new Block("allium", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block AZURE_BLUET = register(new Block("azure_bluet", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block RED_TULIP = register(new Block("red_tulip", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block ORANGE_TULIP = register(new Block("orange_tulip", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block WHITE_TULIP = register(new Block("white_tulip", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block PINK_TULIP = register(new Block("pink_tulip", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block OXEYE_DAISY = register(new Block("oxeye_daisy", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block CORNFLOWER = register(new Block("cornflower", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block WITHER_ROSE = register(new Block("wither_rose", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block LILY_OF_THE_VALLEY = register(new Block("lily_of_the_valley", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block BROWN_MUSHROOM = register(new Block("brown_mushroom", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block RED_MUSHROOM = register(new Block("red_mushroom", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block GOLD_BLOCK = register(new Block("gold_block", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); public static final Block IRON_BLOCK = register(new Block("iron_block", builder().requiresCorrectToolForDrops().destroyTime(5.0f))); public static final Block BRICKS = register(new Block("bricks", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); @@ -368,28 +368,28 @@ public final class Blocks { .booleanState(CHISELED_BOOKSHELF_SLOT_5_OCCUPIED))); public static final Block MOSSY_COBBLESTONE = register(new Block("mossy_cobblestone", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); public static final Block OBSIDIAN = register(new Block("obsidian", builder().requiresCorrectToolForDrops().destroyTime(50.0f))); - public static final Block TORCH = register(new Block("torch", builder())); - public static final Block WALL_TORCH = register(new Block("wall_torch", builder() + public static final Block TORCH = register(new Block("torch", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block WALL_TORCH = register(new Block("wall_torch", builder().pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block FIRE = register(new Block("fire", builder() + public static final Block FIRE = register(new Block("fire", builder().pushReaction(PistonBehavior.DESTROY) .intState(AGE_15, 0, 15) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(UP) .booleanState(WEST))); - public static final Block SOUL_FIRE = register(new Block("soul_fire", builder())); + public static final Block SOUL_FIRE = register(new Block("soul_fire", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block SPAWNER = register(new Block("spawner", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(5.0f))); public static final Block OAK_STAIRS = register(new Block("oak_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block CHEST = register(new Block("chest", builder().setBlockEntity().destroyTime(2.5f) + public static final Block CHEST = register(new ChestBlock("chest", builder().setBlockEntity().destroyTime(2.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(CHEST_TYPE, "single", "left", "right") + .enumState(CHEST_TYPE, ChestType.VALUES) .booleanState(WATERLOGGED))); - public static final Block REDSTONE_WIRE = register(new Block("redstone_wire", builder() + public static final Block REDSTONE_WIRE = register(new Block("redstone_wire", builder().pushReaction(PistonBehavior.DESTROY) .enumState(EAST_REDSTONE, "up", "side", "none") .enumState(NORTH_REDSTONE, "up", "side", "none") .intState(POWER, 0, 15) @@ -399,7 +399,7 @@ public final class Blocks { public static final Block DEEPSLATE_DIAMOND_ORE = register(new Block("deepslate_diamond_ore", builder().requiresCorrectToolForDrops().destroyTime(4.5f))); public static final Block DIAMOND_BLOCK = register(new Block("diamond_block", builder().requiresCorrectToolForDrops().destroyTime(5.0f))); public static final Block CRAFTING_TABLE = register(new Block("crafting_table", builder().destroyTime(2.5f))); - public static final Block WHEAT = register(new Block("wheat", builder() + public static final Block WHEAT = register(new Block("wheat", builder().pushReaction(PistonBehavior.DESTROY) .intState(AGE_7, 0, 7))); public static final Block FARMLAND = register(new Block("farmland", builder().destroyTime(0.6f) .intState(MOISTURE, 0, 7))); @@ -433,13 +433,13 @@ public final class Blocks { public static final Block BAMBOO_SIGN = register(new Block("bamboo_sign", builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15) .booleanState(WATERLOGGED))); - public static final Block OAK_DOOR = register(new Block("oak_door", builder().destroyTime(3.0f) + public static final Block OAK_DOOR = register(new DoorBlock("oak_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block LADDER = register(new Block("ladder", builder().destroyTime(0.4f) + public static final Block LADDER = register(new Block("ladder", builder().destroyTime(0.4f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); public static final Block RAIL = register(new Block("rail", builder().destroyTime(0.7f) @@ -554,57 +554,57 @@ public final class Blocks { public static final Block BAMBOO_WALL_HANGING_SIGN = register(new Block("bamboo_wall_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block LEVER = register(new Block("lever", builder().destroyTime(0.5f) + public static final Block LEVER = register(new Block("lever", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block STONE_PRESSURE_PLATE = register(new Block("stone_pressure_plate", builder().requiresCorrectToolForDrops().destroyTime(0.5f) + public static final Block STONE_PRESSURE_PLATE = register(new Block("stone_pressure_plate", builder().requiresCorrectToolForDrops().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED))); - public static final Block IRON_DOOR = register(new Block("iron_door", builder().requiresCorrectToolForDrops().destroyTime(5.0f) + public static final Block IRON_DOOR = register(new DoorBlock("iron_door", builder().requiresCorrectToolForDrops().destroyTime(5.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block OAK_PRESSURE_PLATE = register(new Block("oak_pressure_plate", builder().destroyTime(0.5f) + public static final Block OAK_PRESSURE_PLATE = register(new Block("oak_pressure_plate", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED))); - public static final Block SPRUCE_PRESSURE_PLATE = register(new Block("spruce_pressure_plate", builder().destroyTime(0.5f) + public static final Block SPRUCE_PRESSURE_PLATE = register(new Block("spruce_pressure_plate", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED))); - public static final Block BIRCH_PRESSURE_PLATE = register(new Block("birch_pressure_plate", builder().destroyTime(0.5f) + public static final Block BIRCH_PRESSURE_PLATE = register(new Block("birch_pressure_plate", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED))); - public static final Block JUNGLE_PRESSURE_PLATE = register(new Block("jungle_pressure_plate", builder().destroyTime(0.5f) + public static final Block JUNGLE_PRESSURE_PLATE = register(new Block("jungle_pressure_plate", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED))); - public static final Block ACACIA_PRESSURE_PLATE = register(new Block("acacia_pressure_plate", builder().destroyTime(0.5f) + public static final Block ACACIA_PRESSURE_PLATE = register(new Block("acacia_pressure_plate", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED))); - public static final Block CHERRY_PRESSURE_PLATE = register(new Block("cherry_pressure_plate", builder().destroyTime(0.5f) + public static final Block CHERRY_PRESSURE_PLATE = register(new Block("cherry_pressure_plate", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED))); - public static final Block DARK_OAK_PRESSURE_PLATE = register(new Block("dark_oak_pressure_plate", builder().destroyTime(0.5f) + public static final Block DARK_OAK_PRESSURE_PLATE = register(new Block("dark_oak_pressure_plate", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED))); - public static final Block MANGROVE_PRESSURE_PLATE = register(new Block("mangrove_pressure_plate", builder().destroyTime(0.5f) + public static final Block MANGROVE_PRESSURE_PLATE = register(new Block("mangrove_pressure_plate", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED))); - public static final Block BAMBOO_PRESSURE_PLATE = register(new Block("bamboo_pressure_plate", builder().destroyTime(0.5f) + public static final Block BAMBOO_PRESSURE_PLATE = register(new Block("bamboo_pressure_plate", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED))); public static final Block REDSTONE_ORE = register(new Block("redstone_ore", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .booleanState(LIT))); public static final Block DEEPSLATE_REDSTONE_ORE = register(new Block("deepslate_redstone_ore", builder().requiresCorrectToolForDrops().destroyTime(4.5f) .booleanState(LIT))); - public static final Block REDSTONE_TORCH = register(new Block("redstone_torch", builder() + public static final Block REDSTONE_TORCH = register(new Block("redstone_torch", builder().pushReaction(PistonBehavior.DESTROY) .booleanState(LIT))); - public static final Block REDSTONE_WALL_TORCH = register(new Block("redstone_wall_torch", builder() + public static final Block REDSTONE_WALL_TORCH = register(new Block("redstone_wall_torch", builder().pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(LIT))); - public static final Block STONE_BUTTON = register(new Block("stone_button", builder().destroyTime(0.5f) + public static final Block STONE_BUTTON = register(new Block("stone_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block SNOW = register(new Block("snow", builder().requiresCorrectToolForDrops().destroyTime(0.1f) + public static final Block SNOW = register(new Block("snow", builder().requiresCorrectToolForDrops().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) .intState(LAYERS, 1, 8))); public static final Block ICE = register(new Block("ice", builder().destroyTime(0.5f))); public static final Block SNOW_BLOCK = register(new Block("snow_block", builder().requiresCorrectToolForDrops().destroyTime(0.2f))); - public static final Block CACTUS = register(new Block("cactus", builder().destroyTime(0.4f) + public static final Block CACTUS = register(new Block("cactus", builder().destroyTime(0.4f).pushReaction(PistonBehavior.DESTROY) .intState(AGE_15, 0, 15))); public static final Block CLAY = register(new Block("clay", builder().destroyTime(0.6f))); - public static final Block SUGAR_CANE = register(new Block("sugar_cane", builder() + public static final Block SUGAR_CANE = register(new Block("sugar_cane", builder().pushReaction(PistonBehavior.DESTROY) .intState(AGE_15, 0, 15))); public static final Block JUKEBOX = register(new Block("jukebox", builder().setBlockEntity().destroyTime(2.0f) .booleanState(HAS_RECORD))); @@ -621,19 +621,19 @@ public final class Blocks { .enumState(AXIS, Axis.VALUES))); public static final Block POLISHED_BASALT = register(new Block("polished_basalt", builder().requiresCorrectToolForDrops().destroyTime(1.25f) .enumState(AXIS, Axis.VALUES))); - public static final Block SOUL_TORCH = register(new Block("soul_torch", builder())); - public static final Block SOUL_WALL_TORCH = register(new Block("soul_wall_torch", builder() + public static final Block SOUL_TORCH = register(new Block("soul_torch", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block SOUL_WALL_TORCH = register(new Block("soul_wall_torch", builder().pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); public static final Block GLOWSTONE = register(new Block("glowstone", builder().destroyTime(0.3f))); - public static final Block NETHER_PORTAL = register(new Block("nether_portal", builder().destroyTime(-1.0f) + public static final Block NETHER_PORTAL = register(new Block("nether_portal", builder().destroyTime(-1.0f).pushReaction(PistonBehavior.BLOCK) .enumState(HORIZONTAL_AXIS, Axis.X, Axis.Z))); - public static final Block CARVED_PUMPKIN = register(new Block("carved_pumpkin", builder().destroyTime(1.0f) + public static final Block CARVED_PUMPKIN = register(new Block("carved_pumpkin", builder().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block JACK_O_LANTERN = register(new Block("jack_o_lantern", builder().destroyTime(1.0f) + public static final Block JACK_O_LANTERN = register(new Block("jack_o_lantern", builder().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block CAKE = register(new Block("cake", builder().destroyTime(0.5f) + public static final Block CAKE = register(new Block("cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .intState(BITES, 0, 6))); - public static final Block REPEATER = register(new Block("repeater", builder() + public static final Block REPEATER = register(new Block("repeater", builder().pushReaction(PistonBehavior.DESTROY) .intState(DELAY, 1, 4) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(LOCKED) @@ -756,23 +756,23 @@ public final class Blocks { .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block PUMPKIN = register(new Block("pumpkin", builder().destroyTime(1.0f))); - public static final Block MELON = register(new Block("melon", builder().destroyTime(1.0f))); - public static final Block ATTACHED_PUMPKIN_STEM = register(new Block("attached_pumpkin_stem", builder() + public static final Block PUMPKIN = register(new Block("pumpkin", builder().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY))); + public static final Block MELON = register(new Block("melon", builder().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY))); + public static final Block ATTACHED_PUMPKIN_STEM = register(new Block("attached_pumpkin_stem", builder().pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block ATTACHED_MELON_STEM = register(new Block("attached_melon_stem", builder() + public static final Block ATTACHED_MELON_STEM = register(new Block("attached_melon_stem", builder().pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block PUMPKIN_STEM = register(new Block("pumpkin_stem", builder() + public static final Block PUMPKIN_STEM = register(new Block("pumpkin_stem", builder().pushReaction(PistonBehavior.DESTROY) .intState(AGE_7, 0, 7))); - public static final Block MELON_STEM = register(new Block("melon_stem", builder() + public static final Block MELON_STEM = register(new Block("melon_stem", builder().pushReaction(PistonBehavior.DESTROY) .intState(AGE_7, 0, 7))); - public static final Block VINE = register(new Block("vine", builder().destroyTime(0.2f) + public static final Block VINE = register(new Block("vine", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(UP) .booleanState(WEST))); - public static final Block GLOW_LICHEN = register(new Block("glow_lichen", builder().destroyTime(0.2f) + public static final Block GLOW_LICHEN = register(new Block("glow_lichen", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .booleanState(DOWN) .booleanState(EAST) .booleanState(NORTH) @@ -802,7 +802,7 @@ public final class Blocks { .booleanState(WATERLOGGED))); public static final Block MYCELIUM = register(new Block("mycelium", builder().destroyTime(0.6f) .booleanState(SNOWY))); - public static final Block LILY_PAD = register(new Block("lily_pad", builder())); + public static final Block LILY_PAD = register(new Block("lily_pad", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block NETHER_BRICKS = register(new Block("nether_bricks", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); public static final Block NETHER_BRICK_FENCE = register(new Block("nether_brick_fence", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .booleanState(EAST) @@ -815,28 +815,28 @@ public final class Blocks { .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block NETHER_WART = register(new Block("nether_wart", builder() + public static final Block NETHER_WART = register(new Block("nether_wart", builder().pushReaction(PistonBehavior.DESTROY) .intState(AGE_3, 0, 3))); public static final Block ENCHANTING_TABLE = register(new Block("enchanting_table", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(5.0f))); public static final Block BREWING_STAND = register(new Block("brewing_stand", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(0.5f) .booleanState(HAS_BOTTLE_0) .booleanState(HAS_BOTTLE_1) .booleanState(HAS_BOTTLE_2))); - public static final Block CAULDRON = register(new Block("cauldron", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); + public static final Block CAULDRON = register(new CauldronBlock("cauldron", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); public static final Block WATER_CAULDRON = register(new Block("water_cauldron", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .intState(LEVEL_CAULDRON, 1, 3))); public static final Block LAVA_CAULDRON = register(new Block("lava_cauldron", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); public static final Block POWDER_SNOW_CAULDRON = register(new Block("powder_snow_cauldron", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .intState(LEVEL_CAULDRON, 1, 3))); - public static final Block END_PORTAL = register(new Block("end_portal", builder().setBlockEntity().destroyTime(-1.0f))); + public static final Block END_PORTAL = register(new Block("end_portal", builder().setBlockEntity().destroyTime(-1.0f).pushReaction(PistonBehavior.BLOCK))); public static final Block END_PORTAL_FRAME = register(new Block("end_portal_frame", builder().destroyTime(-1.0f) .booleanState(EYE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); public static final Block END_STONE = register(new Block("end_stone", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); - public static final Block DRAGON_EGG = register(new Block("dragon_egg", builder().destroyTime(3.0f))); + public static final Block DRAGON_EGG = register(new Block("dragon_egg", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY))); public static final Block REDSTONE_LAMP = register(new Block("redstone_lamp", builder().destroyTime(0.3f) .booleanState(LIT))); - public static final Block COCOA = register(new Block("cocoa", builder().destroyTime(0.2f) + public static final Block COCOA = register(new Block("cocoa", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .intState(AGE_2, 0, 2) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); public static final Block SANDSTONE_STAIRS = register(new Block("sandstone_stairs", builder().requiresCorrectToolForDrops().destroyTime(0.8f) @@ -849,11 +849,11 @@ public final class Blocks { public static final Block ENDER_CHEST = register(new Block("ender_chest", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(22.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block TRIPWIRE_HOOK = register(new Block("tripwire_hook", builder() + public static final Block TRIPWIRE_HOOK = register(new Block("tripwire_hook", builder().pushReaction(PistonBehavior.DESTROY) .booleanState(ATTACHED) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block TRIPWIRE = register(new Block("tripwire", builder() + public static final Block TRIPWIRE = register(new Block("tripwire", builder().pushReaction(PistonBehavior.DESTROY) .booleanState(ATTACHED) .booleanState(DISARMED) .booleanState(EAST) @@ -895,131 +895,131 @@ public final class Blocks { .booleanState(UP) .booleanState(WATERLOGGED) .enumState(WEST_WALL, "none", "low", "tall"))); - public static final Block FLOWER_POT = register(new Block("flower_pot", builder())); - public static final Block POTTED_TORCHFLOWER = register(new Block("potted_torchflower", builder())); - public static final Block POTTED_OAK_SAPLING = register(new Block("potted_oak_sapling", builder())); - public static final Block POTTED_SPRUCE_SAPLING = register(new Block("potted_spruce_sapling", builder())); - public static final Block POTTED_BIRCH_SAPLING = register(new Block("potted_birch_sapling", builder())); - public static final Block POTTED_JUNGLE_SAPLING = register(new Block("potted_jungle_sapling", builder())); - public static final Block POTTED_ACACIA_SAPLING = register(new Block("potted_acacia_sapling", builder())); - public static final Block POTTED_CHERRY_SAPLING = register(new Block("potted_cherry_sapling", builder())); - public static final Block POTTED_DARK_OAK_SAPLING = register(new Block("potted_dark_oak_sapling", builder())); - public static final Block POTTED_MANGROVE_PROPAGULE = register(new Block("potted_mangrove_propagule", builder())); - public static final Block POTTED_FERN = register(new Block("potted_fern", builder())); - public static final Block POTTED_DANDELION = register(new Block("potted_dandelion", builder())); - public static final Block POTTED_POPPY = register(new Block("potted_poppy", builder())); - public static final Block POTTED_BLUE_ORCHID = register(new Block("potted_blue_orchid", builder())); - public static final Block POTTED_ALLIUM = register(new Block("potted_allium", builder())); - public static final Block POTTED_AZURE_BLUET = register(new Block("potted_azure_bluet", builder())); - public static final Block POTTED_RED_TULIP = register(new Block("potted_red_tulip", builder())); - public static final Block POTTED_ORANGE_TULIP = register(new Block("potted_orange_tulip", builder())); - public static final Block POTTED_WHITE_TULIP = register(new Block("potted_white_tulip", builder())); - public static final Block POTTED_PINK_TULIP = register(new Block("potted_pink_tulip", builder())); - public static final Block POTTED_OXEYE_DAISY = register(new Block("potted_oxeye_daisy", builder())); - public static final Block POTTED_CORNFLOWER = register(new Block("potted_cornflower", builder())); - public static final Block POTTED_LILY_OF_THE_VALLEY = register(new Block("potted_lily_of_the_valley", builder())); - public static final Block POTTED_WITHER_ROSE = register(new Block("potted_wither_rose", builder())); - public static final Block POTTED_RED_MUSHROOM = register(new Block("potted_red_mushroom", builder())); - public static final Block POTTED_BROWN_MUSHROOM = register(new Block("potted_brown_mushroom", builder())); - public static final Block POTTED_DEAD_BUSH = register(new Block("potted_dead_bush", builder())); - public static final Block POTTED_CACTUS = register(new Block("potted_cactus", builder())); - public static final Block CARROTS = register(new Block("carrots", builder() + public static final Block FLOWER_POT = register(new FlowerPotBlock("flower_pot", AIR, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_TORCHFLOWER = register(new FlowerPotBlock("potted_torchflower", TORCHFLOWER, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_OAK_SAPLING = register(new FlowerPotBlock("potted_oak_sapling", OAK_SAPLING, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_SPRUCE_SAPLING = register(new FlowerPotBlock("potted_spruce_sapling", SPRUCE_SAPLING, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_BIRCH_SAPLING = register(new FlowerPotBlock("potted_birch_sapling", BIRCH_SAPLING, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_JUNGLE_SAPLING = register(new FlowerPotBlock("potted_jungle_sapling", JUNGLE_SAPLING, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_ACACIA_SAPLING = register(new FlowerPotBlock("potted_acacia_sapling", ACACIA_SAPLING, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_CHERRY_SAPLING = register(new FlowerPotBlock("potted_cherry_sapling", CHERRY_SAPLING, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_DARK_OAK_SAPLING = register(new FlowerPotBlock("potted_dark_oak_sapling", DARK_OAK_SAPLING, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_MANGROVE_PROPAGULE = register(new FlowerPotBlock("potted_mangrove_propagule", MANGROVE_PROPAGULE, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_FERN = register(new FlowerPotBlock("potted_fern", FERN, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_DANDELION = register(new FlowerPotBlock("potted_dandelion", DANDELION, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_POPPY = register(new FlowerPotBlock("potted_poppy", POPPY, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_BLUE_ORCHID = register(new FlowerPotBlock("potted_blue_orchid", BLUE_ORCHID, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_ALLIUM = register(new FlowerPotBlock("potted_allium", ALLIUM, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_AZURE_BLUET = register(new FlowerPotBlock("potted_azure_bluet", AZURE_BLUET, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_RED_TULIP = register(new FlowerPotBlock("potted_red_tulip", RED_TULIP, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_ORANGE_TULIP = register(new FlowerPotBlock("potted_orange_tulip", ORANGE_TULIP, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_WHITE_TULIP = register(new FlowerPotBlock("potted_white_tulip", WHITE_TULIP, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_PINK_TULIP = register(new FlowerPotBlock("potted_pink_tulip", PINK_TULIP, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_OXEYE_DAISY = register(new FlowerPotBlock("potted_oxeye_daisy", OXEYE_DAISY, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_CORNFLOWER = register(new FlowerPotBlock("potted_cornflower", CORNFLOWER, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_LILY_OF_THE_VALLEY = register(new FlowerPotBlock("potted_lily_of_the_valley", LILY_OF_THE_VALLEY, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_WITHER_ROSE = register(new FlowerPotBlock("potted_wither_rose", WITHER_ROSE, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_RED_MUSHROOM = register(new FlowerPotBlock("potted_red_mushroom", RED_MUSHROOM, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_BROWN_MUSHROOM = register(new FlowerPotBlock("potted_brown_mushroom", BROWN_MUSHROOM, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_DEAD_BUSH = register(new FlowerPotBlock("potted_dead_bush", DEAD_BUSH, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_CACTUS = register(new FlowerPotBlock("potted_cactus", CACTUS, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block CARROTS = register(new Block("carrots", builder().pushReaction(PistonBehavior.DESTROY) .intState(AGE_7, 0, 7))); - public static final Block POTATOES = register(new Block("potatoes", builder() + public static final Block POTATOES = register(new Block("potatoes", builder().pushReaction(PistonBehavior.DESTROY) .intState(AGE_7, 0, 7))); - public static final Block OAK_BUTTON = register(new Block("oak_button", builder().destroyTime(0.5f) + public static final Block OAK_BUTTON = register(new Block("oak_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block SPRUCE_BUTTON = register(new Block("spruce_button", builder().destroyTime(0.5f) + public static final Block SPRUCE_BUTTON = register(new Block("spruce_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block BIRCH_BUTTON = register(new Block("birch_button", builder().destroyTime(0.5f) + public static final Block BIRCH_BUTTON = register(new Block("birch_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block JUNGLE_BUTTON = register(new Block("jungle_button", builder().destroyTime(0.5f) + public static final Block JUNGLE_BUTTON = register(new Block("jungle_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block ACACIA_BUTTON = register(new Block("acacia_button", builder().destroyTime(0.5f) + public static final Block ACACIA_BUTTON = register(new Block("acacia_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block CHERRY_BUTTON = register(new Block("cherry_button", builder().destroyTime(0.5f) + public static final Block CHERRY_BUTTON = register(new Block("cherry_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block DARK_OAK_BUTTON = register(new Block("dark_oak_button", builder().destroyTime(0.5f) + public static final Block DARK_OAK_BUTTON = register(new Block("dark_oak_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block MANGROVE_BUTTON = register(new Block("mangrove_button", builder().destroyTime(0.5f) + public static final Block MANGROVE_BUTTON = register(new Block("mangrove_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block BAMBOO_BUTTON = register(new Block("bamboo_button", builder().destroyTime(0.5f) + public static final Block BAMBOO_BUTTON = register(new Block("bamboo_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block SKELETON_SKULL = register(new Block("skeleton_skull", builder().setBlockEntity().destroyTime(1.0f) + public static final Block SKELETON_SKULL = register(new SkullBlock("skeleton_skull", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) .intState(ROTATION_16, 0, 15))); - public static final Block SKELETON_WALL_SKULL = register(new Block("skeleton_wall_skull", builder().setBlockEntity().destroyTime(1.0f) + public static final Block SKELETON_WALL_SKULL = register(new SkullBlock("skeleton_wall_skull", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block WITHER_SKELETON_SKULL = register(new Block("wither_skeleton_skull", builder().setBlockEntity().destroyTime(1.0f) + public static final Block WITHER_SKELETON_SKULL = register(new SkullBlock("wither_skeleton_skull", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) .intState(ROTATION_16, 0, 15))); - public static final Block WITHER_SKELETON_WALL_SKULL = register(new Block("wither_skeleton_wall_skull", builder().setBlockEntity().destroyTime(1.0f) + public static final Block WITHER_SKELETON_WALL_SKULL = register(new SkullBlock("wither_skeleton_wall_skull", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block ZOMBIE_HEAD = register(new Block("zombie_head", builder().setBlockEntity().destroyTime(1.0f) + public static final Block ZOMBIE_HEAD = register(new SkullBlock("zombie_head", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) .intState(ROTATION_16, 0, 15))); - public static final Block ZOMBIE_WALL_HEAD = register(new Block("zombie_wall_head", builder().setBlockEntity().destroyTime(1.0f) + public static final Block ZOMBIE_WALL_HEAD = register(new SkullBlock("zombie_wall_head", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block PLAYER_HEAD = register(new Block("player_head", builder().setBlockEntity().destroyTime(1.0f) + public static final Block PLAYER_HEAD = register(new SkullBlock("player_head", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) .intState(ROTATION_16, 0, 15))); - public static final Block PLAYER_WALL_HEAD = register(new Block("player_wall_head", builder().setBlockEntity().destroyTime(1.0f) + public static final Block PLAYER_WALL_HEAD = register(new SkullBlock("player_wall_head", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block CREEPER_HEAD = register(new Block("creeper_head", builder().setBlockEntity().destroyTime(1.0f) + public static final Block CREEPER_HEAD = register(new SkullBlock("creeper_head", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) .intState(ROTATION_16, 0, 15))); - public static final Block CREEPER_WALL_HEAD = register(new Block("creeper_wall_head", builder().setBlockEntity().destroyTime(1.0f) + public static final Block CREEPER_WALL_HEAD = register(new SkullBlock("creeper_wall_head", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block DRAGON_HEAD = register(new Block("dragon_head", builder().setBlockEntity().destroyTime(1.0f) + public static final Block DRAGON_HEAD = register(new SkullBlock("dragon_head", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) .intState(ROTATION_16, 0, 15))); - public static final Block DRAGON_WALL_HEAD = register(new Block("dragon_wall_head", builder().setBlockEntity().destroyTime(1.0f) + public static final Block DRAGON_WALL_HEAD = register(new SkullBlock("dragon_wall_head", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block PIGLIN_HEAD = register(new Block("piglin_head", builder().setBlockEntity().destroyTime(1.0f) + public static final Block PIGLIN_HEAD = register(new SkullBlock("piglin_head", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) .intState(ROTATION_16, 0, 15))); - public static final Block PIGLIN_WALL_HEAD = register(new Block("piglin_wall_head", builder().setBlockEntity().destroyTime(1.0f) + public static final Block PIGLIN_WALL_HEAD = register(new SkullBlock("piglin_wall_head", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block ANVIL = register(new Block("anvil", builder().requiresCorrectToolForDrops().destroyTime(5.0f) + public static final Block ANVIL = register(new Block("anvil", builder().requiresCorrectToolForDrops().destroyTime(5.0f).pushReaction(PistonBehavior.BLOCK) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block CHIPPED_ANVIL = register(new Block("chipped_anvil", builder().requiresCorrectToolForDrops().destroyTime(5.0f) + public static final Block CHIPPED_ANVIL = register(new Block("chipped_anvil", builder().requiresCorrectToolForDrops().destroyTime(5.0f).pushReaction(PistonBehavior.BLOCK) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block DAMAGED_ANVIL = register(new Block("damaged_anvil", builder().requiresCorrectToolForDrops().destroyTime(5.0f) + public static final Block DAMAGED_ANVIL = register(new Block("damaged_anvil", builder().requiresCorrectToolForDrops().destroyTime(5.0f).pushReaction(PistonBehavior.BLOCK) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block TRAPPED_CHEST = register(new Block("trapped_chest", builder().setBlockEntity().destroyTime(2.5f) + public static final Block TRAPPED_CHEST = register(new ChestBlock("trapped_chest", builder().setBlockEntity().destroyTime(2.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(CHEST_TYPE, "single", "left", "right") + .enumState(CHEST_TYPE, ChestType.VALUES) .booleanState(WATERLOGGED))); - public static final Block LIGHT_WEIGHTED_PRESSURE_PLATE = register(new Block("light_weighted_pressure_plate", builder().requiresCorrectToolForDrops().destroyTime(0.5f) + public static final Block LIGHT_WEIGHTED_PRESSURE_PLATE = register(new Block("light_weighted_pressure_plate", builder().requiresCorrectToolForDrops().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .intState(POWER, 0, 15))); - public static final Block HEAVY_WEIGHTED_PRESSURE_PLATE = register(new Block("heavy_weighted_pressure_plate", builder().requiresCorrectToolForDrops().destroyTime(0.5f) + public static final Block HEAVY_WEIGHTED_PRESSURE_PLATE = register(new Block("heavy_weighted_pressure_plate", builder().requiresCorrectToolForDrops().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .intState(POWER, 0, 15))); - public static final Block COMPARATOR = register(new Block("comparator", builder().setBlockEntity() + public static final Block COMPARATOR = register(new Block("comparator", builder().setBlockEntity().pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(MODE_COMPARATOR, "compare", "subtract") .booleanState(POWERED))); @@ -1190,7 +1190,7 @@ public final class Blocks { .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); public static final Block SLIME_BLOCK = register(new Block("slime_block", builder())); - public static final Block BARRIER = register(new Block("barrier", builder().destroyTime(-1.0f) + public static final Block BARRIER = register(new Block("barrier", builder().destroyTime(-1.0f).pushReaction(PistonBehavior.BLOCK) .booleanState(WATERLOGGED))); public static final Block LIGHT = register(new Block("light", builder().destroyTime(-1.0f) .intState(LEVEL, 0, 15) @@ -1250,17 +1250,17 @@ public final class Blocks { public static final Block TERRACOTTA = register(new Block("terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.25f))); public static final Block COAL_BLOCK = register(new Block("coal_block", builder().requiresCorrectToolForDrops().destroyTime(5.0f))); public static final Block PACKED_ICE = register(new Block("packed_ice", builder().destroyTime(0.5f))); - public static final Block SUNFLOWER = register(new Block("sunflower", builder() + public static final Block SUNFLOWER = register(new Block("sunflower", builder().pushReaction(PistonBehavior.DESTROY) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); - public static final Block LILAC = register(new Block("lilac", builder() + public static final Block LILAC = register(new Block("lilac", builder().pushReaction(PistonBehavior.DESTROY) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); - public static final Block ROSE_BUSH = register(new Block("rose_bush", builder() + public static final Block ROSE_BUSH = register(new Block("rose_bush", builder().pushReaction(PistonBehavior.DESTROY) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); - public static final Block PEONY = register(new Block("peony", builder() + public static final Block PEONY = register(new Block("peony", builder().pushReaction(PistonBehavior.DESTROY) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); - public static final Block TALL_GRASS = register(new Block("tall_grass", builder() + public static final Block TALL_GRASS = register(new Block("tall_grass", builder().pushReaction(PistonBehavior.DESTROY) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); - public static final Block LARGE_FERN = register(new Block("large_fern", builder() + public static final Block LARGE_FERN = register(new Block("large_fern", builder().pushReaction(PistonBehavior.DESTROY) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); public static final Block WHITE_BANNER = register(new BannerBlock("white_banner", 0, builder().setBlockEntity().destroyTime(1.0f) .intState(ROTATION_16, 0, 15))); @@ -1498,49 +1498,49 @@ public final class Blocks { .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block SPRUCE_DOOR = register(new Block("spruce_door", builder().destroyTime(3.0f) + public static final Block SPRUCE_DOOR = register(new DoorBlock("spruce_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block BIRCH_DOOR = register(new Block("birch_door", builder().destroyTime(3.0f) + public static final Block BIRCH_DOOR = register(new DoorBlock("birch_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block JUNGLE_DOOR = register(new Block("jungle_door", builder().destroyTime(3.0f) + public static final Block JUNGLE_DOOR = register(new DoorBlock("jungle_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block ACACIA_DOOR = register(new Block("acacia_door", builder().destroyTime(3.0f) + public static final Block ACACIA_DOOR = register(new DoorBlock("acacia_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block CHERRY_DOOR = register(new Block("cherry_door", builder().destroyTime(3.0f) + public static final Block CHERRY_DOOR = register(new DoorBlock("cherry_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block DARK_OAK_DOOR = register(new Block("dark_oak_door", builder().destroyTime(3.0f) + public static final Block DARK_OAK_DOOR = register(new DoorBlock("dark_oak_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block MANGROVE_DOOR = register(new Block("mangrove_door", builder().destroyTime(3.0f) + public static final Block MANGROVE_DOOR = register(new DoorBlock("mangrove_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block BAMBOO_DOOR = register(new Block("bamboo_door", builder().destroyTime(3.0f) + public static final Block BAMBOO_DOOR = register(new DoorBlock("bamboo_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") @@ -1548,14 +1548,14 @@ public final class Blocks { .booleanState(POWERED))); public static final Block END_ROD = register(new Block("end_rod", builder() .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block CHORUS_PLANT = register(new Block("chorus_plant", builder().destroyTime(0.4f) + public static final Block CHORUS_PLANT = register(new Block("chorus_plant", builder().destroyTime(0.4f).pushReaction(PistonBehavior.DESTROY) .booleanState(DOWN) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) .booleanState(UP) .booleanState(WEST))); - public static final Block CHORUS_FLOWER = register(new Block("chorus_flower", builder().destroyTime(0.4f) + public static final Block CHORUS_FLOWER = register(new Block("chorus_flower", builder().destroyTime(0.4f).pushReaction(PistonBehavior.DESTROY) .intState(AGE_5, 0, 5))); public static final Block PURPUR_BLOCK = register(new Block("purpur_block", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block PURPUR_PILLAR = register(new Block("purpur_pillar", builder().requiresCorrectToolForDrops().destroyTime(1.5f) @@ -1566,17 +1566,17 @@ public final class Blocks { .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); public static final Block END_STONE_BRICKS = register(new Block("end_stone_bricks", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); - public static final Block TORCHFLOWER_CROP = register(new Block("torchflower_crop", builder() + public static final Block TORCHFLOWER_CROP = register(new Block("torchflower_crop", builder().pushReaction(PistonBehavior.DESTROY) .intState(AGE_1, 0, 1))); - public static final Block PITCHER_CROP = register(new Block("pitcher_crop", builder() + public static final Block PITCHER_CROP = register(new Block("pitcher_crop", builder().pushReaction(PistonBehavior.DESTROY) .intState(AGE_4, 0, 4) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); - public static final Block PITCHER_PLANT = register(new Block("pitcher_plant", builder() + public static final Block PITCHER_PLANT = register(new Block("pitcher_plant", builder().pushReaction(PistonBehavior.DESTROY) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); - public static final Block BEETROOTS = register(new Block("beetroots", builder() + public static final Block BEETROOTS = register(new Block("beetroots", builder().pushReaction(PistonBehavior.DESTROY) .intState(AGE_3, 0, 3))); public static final Block DIRT_PATH = register(new Block("dirt_path", builder().destroyTime(0.65f))); - public static final Block END_GATEWAY = register(new Block("end_gateway", builder().setBlockEntity().destroyTime(-1.0f))); + public static final Block END_GATEWAY = register(new Block("end_gateway", builder().setBlockEntity().destroyTime(-1.0f).pushReaction(PistonBehavior.BLOCK))); public static final Block REPEATING_COMMAND_BLOCK = register(new Block("repeating_command_block", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(-1.0f) .booleanState(CONDITIONAL) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); @@ -1590,75 +1590,75 @@ public final class Blocks { public static final Block RED_NETHER_BRICKS = register(new Block("red_nether_bricks", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); public static final Block BONE_BLOCK = register(new Block("bone_block", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); - public static final Block STRUCTURE_VOID = register(new Block("structure_void", builder())); + public static final Block STRUCTURE_VOID = register(new Block("structure_void", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block OBSERVER = register(new Block("observer", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) .booleanState(POWERED))); - public static final Block SHULKER_BOX = register(new Block("shulker_box", builder().setBlockEntity().destroyTime(2.0f) + public static final Block SHULKER_BOX = register(new Block("shulker_box", builder().setBlockEntity().destroyTime(2.0f).pushReaction(PistonBehavior.DESTROY) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block WHITE_SHULKER_BOX = register(new Block("white_shulker_box", builder().setBlockEntity().destroyTime(2.0f) + public static final Block WHITE_SHULKER_BOX = register(new Block("white_shulker_box", builder().setBlockEntity().destroyTime(2.0f).pushReaction(PistonBehavior.DESTROY) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block ORANGE_SHULKER_BOX = register(new Block("orange_shulker_box", builder().setBlockEntity().destroyTime(2.0f) + public static final Block ORANGE_SHULKER_BOX = register(new Block("orange_shulker_box", builder().setBlockEntity().destroyTime(2.0f).pushReaction(PistonBehavior.DESTROY) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block MAGENTA_SHULKER_BOX = register(new Block("magenta_shulker_box", builder().setBlockEntity().destroyTime(2.0f) + public static final Block MAGENTA_SHULKER_BOX = register(new Block("magenta_shulker_box", builder().setBlockEntity().destroyTime(2.0f).pushReaction(PistonBehavior.DESTROY) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block LIGHT_BLUE_SHULKER_BOX = register(new Block("light_blue_shulker_box", builder().setBlockEntity().destroyTime(2.0f) + public static final Block LIGHT_BLUE_SHULKER_BOX = register(new Block("light_blue_shulker_box", builder().setBlockEntity().destroyTime(2.0f).pushReaction(PistonBehavior.DESTROY) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block YELLOW_SHULKER_BOX = register(new Block("yellow_shulker_box", builder().setBlockEntity().destroyTime(2.0f) + public static final Block YELLOW_SHULKER_BOX = register(new Block("yellow_shulker_box", builder().setBlockEntity().destroyTime(2.0f).pushReaction(PistonBehavior.DESTROY) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block LIME_SHULKER_BOX = register(new Block("lime_shulker_box", builder().setBlockEntity().destroyTime(2.0f) + public static final Block LIME_SHULKER_BOX = register(new Block("lime_shulker_box", builder().setBlockEntity().destroyTime(2.0f).pushReaction(PistonBehavior.DESTROY) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block PINK_SHULKER_BOX = register(new Block("pink_shulker_box", builder().setBlockEntity().destroyTime(2.0f) + public static final Block PINK_SHULKER_BOX = register(new Block("pink_shulker_box", builder().setBlockEntity().destroyTime(2.0f).pushReaction(PistonBehavior.DESTROY) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block GRAY_SHULKER_BOX = register(new Block("gray_shulker_box", builder().setBlockEntity().destroyTime(2.0f) + public static final Block GRAY_SHULKER_BOX = register(new Block("gray_shulker_box", builder().setBlockEntity().destroyTime(2.0f).pushReaction(PistonBehavior.DESTROY) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block LIGHT_GRAY_SHULKER_BOX = register(new Block("light_gray_shulker_box", builder().setBlockEntity().destroyTime(2.0f) + public static final Block LIGHT_GRAY_SHULKER_BOX = register(new Block("light_gray_shulker_box", builder().setBlockEntity().destroyTime(2.0f).pushReaction(PistonBehavior.DESTROY) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block CYAN_SHULKER_BOX = register(new Block("cyan_shulker_box", builder().setBlockEntity().destroyTime(2.0f) + public static final Block CYAN_SHULKER_BOX = register(new Block("cyan_shulker_box", builder().setBlockEntity().destroyTime(2.0f).pushReaction(PistonBehavior.DESTROY) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block PURPLE_SHULKER_BOX = register(new Block("purple_shulker_box", builder().setBlockEntity().destroyTime(2.0f) + public static final Block PURPLE_SHULKER_BOX = register(new Block("purple_shulker_box", builder().setBlockEntity().destroyTime(2.0f).pushReaction(PistonBehavior.DESTROY) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block BLUE_SHULKER_BOX = register(new Block("blue_shulker_box", builder().setBlockEntity().destroyTime(2.0f) + public static final Block BLUE_SHULKER_BOX = register(new Block("blue_shulker_box", builder().setBlockEntity().destroyTime(2.0f).pushReaction(PistonBehavior.DESTROY) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block BROWN_SHULKER_BOX = register(new Block("brown_shulker_box", builder().setBlockEntity().destroyTime(2.0f) + public static final Block BROWN_SHULKER_BOX = register(new Block("brown_shulker_box", builder().setBlockEntity().destroyTime(2.0f).pushReaction(PistonBehavior.DESTROY) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block GREEN_SHULKER_BOX = register(new Block("green_shulker_box", builder().setBlockEntity().destroyTime(2.0f) + public static final Block GREEN_SHULKER_BOX = register(new Block("green_shulker_box", builder().setBlockEntity().destroyTime(2.0f).pushReaction(PistonBehavior.DESTROY) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block RED_SHULKER_BOX = register(new Block("red_shulker_box", builder().setBlockEntity().destroyTime(2.0f) + public static final Block RED_SHULKER_BOX = register(new Block("red_shulker_box", builder().setBlockEntity().destroyTime(2.0f).pushReaction(PistonBehavior.DESTROY) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block BLACK_SHULKER_BOX = register(new Block("black_shulker_box", builder().setBlockEntity().destroyTime(2.0f) + public static final Block BLACK_SHULKER_BOX = register(new Block("black_shulker_box", builder().setBlockEntity().destroyTime(2.0f).pushReaction(PistonBehavior.DESTROY) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block WHITE_GLAZED_TERRACOTTA = register(new Block("white_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) + public static final Block WHITE_GLAZED_TERRACOTTA = register(new Block("white_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f).pushReaction(PistonBehavior.PUSH_ONLY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block ORANGE_GLAZED_TERRACOTTA = register(new Block("orange_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) + public static final Block ORANGE_GLAZED_TERRACOTTA = register(new Block("orange_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f).pushReaction(PistonBehavior.PUSH_ONLY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block MAGENTA_GLAZED_TERRACOTTA = register(new Block("magenta_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) + public static final Block MAGENTA_GLAZED_TERRACOTTA = register(new Block("magenta_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f).pushReaction(PistonBehavior.PUSH_ONLY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block LIGHT_BLUE_GLAZED_TERRACOTTA = register(new Block("light_blue_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) + public static final Block LIGHT_BLUE_GLAZED_TERRACOTTA = register(new Block("light_blue_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f).pushReaction(PistonBehavior.PUSH_ONLY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block YELLOW_GLAZED_TERRACOTTA = register(new Block("yellow_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) + public static final Block YELLOW_GLAZED_TERRACOTTA = register(new Block("yellow_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f).pushReaction(PistonBehavior.PUSH_ONLY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block LIME_GLAZED_TERRACOTTA = register(new Block("lime_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) + public static final Block LIME_GLAZED_TERRACOTTA = register(new Block("lime_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f).pushReaction(PistonBehavior.PUSH_ONLY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block PINK_GLAZED_TERRACOTTA = register(new Block("pink_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) + public static final Block PINK_GLAZED_TERRACOTTA = register(new Block("pink_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f).pushReaction(PistonBehavior.PUSH_ONLY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block GRAY_GLAZED_TERRACOTTA = register(new Block("gray_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) + public static final Block GRAY_GLAZED_TERRACOTTA = register(new Block("gray_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f).pushReaction(PistonBehavior.PUSH_ONLY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block LIGHT_GRAY_GLAZED_TERRACOTTA = register(new Block("light_gray_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) + public static final Block LIGHT_GRAY_GLAZED_TERRACOTTA = register(new Block("light_gray_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f).pushReaction(PistonBehavior.PUSH_ONLY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block CYAN_GLAZED_TERRACOTTA = register(new Block("cyan_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) + public static final Block CYAN_GLAZED_TERRACOTTA = register(new Block("cyan_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f).pushReaction(PistonBehavior.PUSH_ONLY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block PURPLE_GLAZED_TERRACOTTA = register(new Block("purple_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) + public static final Block PURPLE_GLAZED_TERRACOTTA = register(new Block("purple_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f).pushReaction(PistonBehavior.PUSH_ONLY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block BLUE_GLAZED_TERRACOTTA = register(new Block("blue_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) + public static final Block BLUE_GLAZED_TERRACOTTA = register(new Block("blue_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f).pushReaction(PistonBehavior.PUSH_ONLY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block BROWN_GLAZED_TERRACOTTA = register(new Block("brown_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) + public static final Block BROWN_GLAZED_TERRACOTTA = register(new Block("brown_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f).pushReaction(PistonBehavior.PUSH_ONLY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block GREEN_GLAZED_TERRACOTTA = register(new Block("green_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) + public static final Block GREEN_GLAZED_TERRACOTTA = register(new Block("green_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f).pushReaction(PistonBehavior.PUSH_ONLY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block RED_GLAZED_TERRACOTTA = register(new Block("red_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) + public static final Block RED_GLAZED_TERRACOTTA = register(new Block("red_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f).pushReaction(PistonBehavior.PUSH_ONLY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block BLACK_GLAZED_TERRACOTTA = register(new Block("black_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f) + public static final Block BLACK_GLAZED_TERRACOTTA = register(new Block("black_glazed_terracotta", builder().requiresCorrectToolForDrops().destroyTime(1.4f).pushReaction(PistonBehavior.PUSH_ONLY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); public static final Block WHITE_CONCRETE = register(new Block("white_concrete", builder().requiresCorrectToolForDrops().destroyTime(1.8f))); public static final Block ORANGE_CONCRETE = register(new Block("orange_concrete", builder().requiresCorrectToolForDrops().destroyTime(1.8f))); @@ -1692,11 +1692,11 @@ public final class Blocks { public static final Block GREEN_CONCRETE_POWDER = register(new Block("green_concrete_powder", builder().destroyTime(0.5f))); public static final Block RED_CONCRETE_POWDER = register(new Block("red_concrete_powder", builder().destroyTime(0.5f))); public static final Block BLACK_CONCRETE_POWDER = register(new Block("black_concrete_powder", builder().destroyTime(0.5f))); - public static final Block KELP = register(new Block("kelp", builder() + public static final Block KELP = register(new Block("kelp", builder().pushReaction(PistonBehavior.DESTROY) .intState(AGE_25, 0, 25))); - public static final Block KELP_PLANT = register(new Block("kelp_plant", builder())); + public static final Block KELP_PLANT = register(new Block("kelp_plant", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block DRIED_KELP_BLOCK = register(new Block("dried_kelp_block", builder().destroyTime(0.5f))); - public static final Block TURTLE_EGG = register(new Block("turtle_egg", builder().destroyTime(0.5f) + public static final Block TURTLE_EGG = register(new Block("turtle_egg", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .intState(EGGS, 1, 4) .intState(HATCH, 0, 2))); public static final Block SNIFFER_EGG = register(new Block("sniffer_egg", builder().destroyTime(0.5f) @@ -1721,15 +1721,15 @@ public final class Blocks { .booleanState(WATERLOGGED))); public static final Block DEAD_HORN_CORAL = register(new Block("dead_horn_coral", builder().requiresCorrectToolForDrops() .booleanState(WATERLOGGED))); - public static final Block TUBE_CORAL = register(new Block("tube_coral", builder() + public static final Block TUBE_CORAL = register(new Block("tube_coral", builder().pushReaction(PistonBehavior.DESTROY) .booleanState(WATERLOGGED))); - public static final Block BRAIN_CORAL = register(new Block("brain_coral", builder() + public static final Block BRAIN_CORAL = register(new Block("brain_coral", builder().pushReaction(PistonBehavior.DESTROY) .booleanState(WATERLOGGED))); - public static final Block BUBBLE_CORAL = register(new Block("bubble_coral", builder() + public static final Block BUBBLE_CORAL = register(new Block("bubble_coral", builder().pushReaction(PistonBehavior.DESTROY) .booleanState(WATERLOGGED))); - public static final Block FIRE_CORAL = register(new Block("fire_coral", builder() + public static final Block FIRE_CORAL = register(new Block("fire_coral", builder().pushReaction(PistonBehavior.DESTROY) .booleanState(WATERLOGGED))); - public static final Block HORN_CORAL = register(new Block("horn_coral", builder() + public static final Block HORN_CORAL = register(new Block("horn_coral", builder().pushReaction(PistonBehavior.DESTROY) .booleanState(WATERLOGGED))); public static final Block DEAD_TUBE_CORAL_FAN = register(new Block("dead_tube_coral_fan", builder().requiresCorrectToolForDrops() .booleanState(WATERLOGGED))); @@ -1741,15 +1741,15 @@ public final class Blocks { .booleanState(WATERLOGGED))); public static final Block DEAD_HORN_CORAL_FAN = register(new Block("dead_horn_coral_fan", builder().requiresCorrectToolForDrops() .booleanState(WATERLOGGED))); - public static final Block TUBE_CORAL_FAN = register(new Block("tube_coral_fan", builder() + public static final Block TUBE_CORAL_FAN = register(new Block("tube_coral_fan", builder().pushReaction(PistonBehavior.DESTROY) .booleanState(WATERLOGGED))); - public static final Block BRAIN_CORAL_FAN = register(new Block("brain_coral_fan", builder() + public static final Block BRAIN_CORAL_FAN = register(new Block("brain_coral_fan", builder().pushReaction(PistonBehavior.DESTROY) .booleanState(WATERLOGGED))); - public static final Block BUBBLE_CORAL_FAN = register(new Block("bubble_coral_fan", builder() + public static final Block BUBBLE_CORAL_FAN = register(new Block("bubble_coral_fan", builder().pushReaction(PistonBehavior.DESTROY) .booleanState(WATERLOGGED))); - public static final Block FIRE_CORAL_FAN = register(new Block("fire_coral_fan", builder() + public static final Block FIRE_CORAL_FAN = register(new Block("fire_coral_fan", builder().pushReaction(PistonBehavior.DESTROY) .booleanState(WATERLOGGED))); - public static final Block HORN_CORAL_FAN = register(new Block("horn_coral_fan", builder() + public static final Block HORN_CORAL_FAN = register(new Block("horn_coral_fan", builder().pushReaction(PistonBehavior.DESTROY) .booleanState(WATERLOGGED))); public static final Block DEAD_TUBE_CORAL_WALL_FAN = register(new Block("dead_tube_coral_wall_fan", builder().requiresCorrectToolForDrops() .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) @@ -1766,36 +1766,36 @@ public final class Blocks { public static final Block DEAD_HORN_CORAL_WALL_FAN = register(new Block("dead_horn_coral_wall_fan", builder().requiresCorrectToolForDrops() .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block TUBE_CORAL_WALL_FAN = register(new Block("tube_coral_wall_fan", builder() + public static final Block TUBE_CORAL_WALL_FAN = register(new Block("tube_coral_wall_fan", builder().pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block BRAIN_CORAL_WALL_FAN = register(new Block("brain_coral_wall_fan", builder() + public static final Block BRAIN_CORAL_WALL_FAN = register(new Block("brain_coral_wall_fan", builder().pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block BUBBLE_CORAL_WALL_FAN = register(new Block("bubble_coral_wall_fan", builder() + public static final Block BUBBLE_CORAL_WALL_FAN = register(new Block("bubble_coral_wall_fan", builder().pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block FIRE_CORAL_WALL_FAN = register(new Block("fire_coral_wall_fan", builder() + public static final Block FIRE_CORAL_WALL_FAN = register(new Block("fire_coral_wall_fan", builder().pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block HORN_CORAL_WALL_FAN = register(new Block("horn_coral_wall_fan", builder() + public static final Block HORN_CORAL_WALL_FAN = register(new Block("horn_coral_wall_fan", builder().pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block SEA_PICKLE = register(new Block("sea_pickle", builder() + public static final Block SEA_PICKLE = register(new Block("sea_pickle", builder().pushReaction(PistonBehavior.DESTROY) .intState(PICKLES, 1, 4) .booleanState(WATERLOGGED))); public static final Block BLUE_ICE = register(new Block("blue_ice", builder().destroyTime(2.8f))); public static final Block CONDUIT = register(new Block("conduit", builder().setBlockEntity().destroyTime(3.0f) .booleanState(WATERLOGGED))); - public static final Block BAMBOO_SAPLING = register(new Block("bamboo_sapling", builder().destroyTime(1.0f))); - public static final Block BAMBOO = register(new Block("bamboo", builder().destroyTime(1.0f) + public static final Block BAMBOO_SAPLING = register(new Block("bamboo_sapling", builder().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY))); + public static final Block BAMBOO = register(new Block("bamboo", builder().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .intState(AGE_1, 0, 1) .enumState(BAMBOO_LEAVES, "none", "small", "large") .intState(STAGE, 0, 1))); - public static final Block POTTED_BAMBOO = register(new Block("potted_bamboo", builder())); + public static final Block POTTED_BAMBOO = register(new FlowerPotBlock("potted_bamboo", BAMBOO, builder().pushReaction(PistonBehavior.DESTROY))); public static final Block VOID_AIR = register(new Block("void_air", builder())); public static final Block CAVE_AIR = register(new Block("cave_air", builder())); - public static final Block BUBBLE_COLUMN = register(new Block("bubble_column", builder() + public static final Block BUBBLE_COLUMN = register(new Block("bubble_column", builder().pushReaction(PistonBehavior.DESTROY) .booleanState(DRAG))); public static final Block POLISHED_GRANITE_STAIRS = register(new Block("polished_granite_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) @@ -1997,7 +1997,7 @@ public final class Blocks { .booleanState(UP) .booleanState(WATERLOGGED) .enumState(WEST_WALL, "none", "low", "tall"))); - public static final Block SCAFFOLDING = register(new Block("scaffolding", builder() + public static final Block SCAFFOLDING = register(new Block("scaffolding", builder().pushReaction(PistonBehavior.DESTROY) .booleanState(BOTTOM) .intState(STABILITY_DISTANCE, 0, 7) .booleanState(WATERLOGGED))); @@ -2014,24 +2014,24 @@ public final class Blocks { .booleanState(LIT))); public static final Block CARTOGRAPHY_TABLE = register(new Block("cartography_table", builder().destroyTime(2.5f))); public static final Block FLETCHING_TABLE = register(new Block("fletching_table", builder().destroyTime(2.5f))); - public static final Block GRINDSTONE = register(new Block("grindstone", builder().requiresCorrectToolForDrops().destroyTime(2.0f) + public static final Block GRINDSTONE = register(new Block("grindstone", builder().requiresCorrectToolForDrops().destroyTime(2.0f).pushReaction(PistonBehavior.BLOCK) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block LECTERN = register(new Block("lectern", builder().setBlockEntity().destroyTime(2.5f) + public static final Block LECTERN = register(new LecternBlock("lectern", builder().setBlockEntity().destroyTime(2.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(HAS_BOOK) .booleanState(POWERED))); public static final Block SMITHING_TABLE = register(new Block("smithing_table", builder().destroyTime(2.5f))); public static final Block STONECUTTER = register(new Block("stonecutter", builder().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block BELL = register(new Block("bell", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(5.0f) + public static final Block BELL = register(new Block("bell", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(5.0f).pushReaction(PistonBehavior.DESTROY) .enumState(BELL_ATTACHMENT, "floor", "ceiling", "single_wall", "double_wall") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block LANTERN = register(new Block("lantern", builder().requiresCorrectToolForDrops().destroyTime(3.5f) + public static final Block LANTERN = register(new Block("lantern", builder().requiresCorrectToolForDrops().destroyTime(3.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(HANGING) .booleanState(WATERLOGGED))); - public static final Block SOUL_LANTERN = register(new Block("soul_lantern", builder().requiresCorrectToolForDrops().destroyTime(3.5f) + public static final Block SOUL_LANTERN = register(new Block("soul_lantern", builder().requiresCorrectToolForDrops().destroyTime(3.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(HANGING) .booleanState(WATERLOGGED))); public static final Block CAMPFIRE = register(new Block("campfire", builder().setBlockEntity().destroyTime(2.0f) @@ -2044,7 +2044,7 @@ public final class Blocks { .booleanState(LIT) .booleanState(SIGNAL_FIRE) .booleanState(WATERLOGGED))); - public static final Block SWEET_BERRY_BUSH = register(new Block("sweet_berry_bush", builder() + public static final Block SWEET_BERRY_BUSH = register(new Block("sweet_berry_bush", builder().pushReaction(PistonBehavior.DESTROY) .intState(AGE_3, 0, 3))); public static final Block WARPED_STEM = register(new Block("warped_stem", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); @@ -2055,10 +2055,10 @@ public final class Blocks { public static final Block STRIPPED_WARPED_HYPHAE = register(new Block("stripped_warped_hyphae", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); public static final Block WARPED_NYLIUM = register(new Block("warped_nylium", builder().requiresCorrectToolForDrops().destroyTime(0.4f))); - public static final Block WARPED_FUNGUS = register(new Block("warped_fungus", builder())); + public static final Block WARPED_FUNGUS = register(new Block("warped_fungus", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block WARPED_WART_BLOCK = register(new Block("warped_wart_block", builder().destroyTime(1.0f))); - public static final Block WARPED_ROOTS = register(new Block("warped_roots", builder())); - public static final Block NETHER_SPROUTS = register(new Block("nether_sprouts", builder())); + public static final Block WARPED_ROOTS = register(new Block("warped_roots", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block NETHER_SPROUTS = register(new Block("nether_sprouts", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block CRIMSON_STEM = register(new Block("crimson_stem", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); public static final Block STRIPPED_CRIMSON_STEM = register(new Block("stripped_crimson_stem", builder().destroyTime(2.0f) @@ -2068,15 +2068,15 @@ public final class Blocks { public static final Block STRIPPED_CRIMSON_HYPHAE = register(new Block("stripped_crimson_hyphae", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); public static final Block CRIMSON_NYLIUM = register(new Block("crimson_nylium", builder().requiresCorrectToolForDrops().destroyTime(0.4f))); - public static final Block CRIMSON_FUNGUS = register(new Block("crimson_fungus", builder())); + public static final Block CRIMSON_FUNGUS = register(new Block("crimson_fungus", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block SHROOMLIGHT = register(new Block("shroomlight", builder().destroyTime(1.0f))); - public static final Block WEEPING_VINES = register(new Block("weeping_vines", builder() + public static final Block WEEPING_VINES = register(new Block("weeping_vines", builder().pushReaction(PistonBehavior.DESTROY) .intState(AGE_25, 0, 25))); - public static final Block WEEPING_VINES_PLANT = register(new Block("weeping_vines_plant", builder())); - public static final Block TWISTING_VINES = register(new Block("twisting_vines", builder() + public static final Block WEEPING_VINES_PLANT = register(new Block("weeping_vines_plant", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block TWISTING_VINES = register(new Block("twisting_vines", builder().pushReaction(PistonBehavior.DESTROY) .intState(AGE_25, 0, 25))); - public static final Block TWISTING_VINES_PLANT = register(new Block("twisting_vines_plant", builder())); - public static final Block CRIMSON_ROOTS = register(new Block("crimson_roots", builder())); + public static final Block TWISTING_VINES_PLANT = register(new Block("twisting_vines_plant", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block CRIMSON_ROOTS = register(new Block("crimson_roots", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block CRIMSON_PLANKS = register(new Block("crimson_planks", builder().destroyTime(2.0f))); public static final Block WARPED_PLANKS = register(new Block("warped_planks", builder().destroyTime(2.0f))); public static final Block CRIMSON_SLAB = register(new Block("crimson_slab", builder().destroyTime(2.0f) @@ -2085,9 +2085,9 @@ public final class Blocks { public static final Block WARPED_SLAB = register(new Block("warped_slab", builder().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block CRIMSON_PRESSURE_PLATE = register(new Block("crimson_pressure_plate", builder().destroyTime(0.5f) + public static final Block CRIMSON_PRESSURE_PLATE = register(new Block("crimson_pressure_plate", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED))); - public static final Block WARPED_PRESSURE_PLATE = register(new Block("warped_pressure_plate", builder().destroyTime(0.5f) + public static final Block WARPED_PRESSURE_PLATE = register(new Block("warped_pressure_plate", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED))); public static final Block CRIMSON_FENCE = register(new Block("crimson_fence", builder().destroyTime(2.0f) .booleanState(EAST) @@ -2133,21 +2133,21 @@ public final class Blocks { .enumState(HALF, "top", "bottom") .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") .booleanState(WATERLOGGED))); - public static final Block CRIMSON_BUTTON = register(new Block("crimson_button", builder().destroyTime(0.5f) + public static final Block CRIMSON_BUTTON = register(new Block("crimson_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block WARPED_BUTTON = register(new Block("warped_button", builder().destroyTime(0.5f) + public static final Block WARPED_BUTTON = register(new Block("warped_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block CRIMSON_DOOR = register(new Block("crimson_door", builder().destroyTime(3.0f) + public static final Block CRIMSON_DOOR = register(new DoorBlock("crimson_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block WARPED_DOOR = register(new Block("warped_door", builder().destroyTime(3.0f) + public static final Block WARPED_DOOR = register(new DoorBlock("warped_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") @@ -2186,11 +2186,11 @@ public final class Blocks { public static final Block CRYING_OBSIDIAN = register(new Block("crying_obsidian", builder().requiresCorrectToolForDrops().destroyTime(50.0f))); public static final Block RESPAWN_ANCHOR = register(new Block("respawn_anchor", builder().requiresCorrectToolForDrops().destroyTime(50.0f) .intState(RESPAWN_ANCHOR_CHARGES, 0, 4))); - public static final Block POTTED_CRIMSON_FUNGUS = register(new Block("potted_crimson_fungus", builder())); - public static final Block POTTED_WARPED_FUNGUS = register(new Block("potted_warped_fungus", builder())); - public static final Block POTTED_CRIMSON_ROOTS = register(new Block("potted_crimson_roots", builder())); - public static final Block POTTED_WARPED_ROOTS = register(new Block("potted_warped_roots", builder())); - public static final Block LODESTONE = register(new Block("lodestone", builder().requiresCorrectToolForDrops().destroyTime(3.5f))); + public static final Block POTTED_CRIMSON_FUNGUS = register(new FlowerPotBlock("potted_crimson_fungus", CRIMSON_FUNGUS, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_WARPED_FUNGUS = register(new FlowerPotBlock("potted_warped_fungus", WARPED_FUNGUS, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_CRIMSON_ROOTS = register(new FlowerPotBlock("potted_crimson_roots", CRIMSON_ROOTS, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_WARPED_ROOTS = register(new FlowerPotBlock("potted_warped_roots", WARPED_ROOTS, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block LODESTONE = register(new Block("lodestone", builder().requiresCorrectToolForDrops().destroyTime(3.5f).pushReaction(PistonBehavior.BLOCK))); public static final Block BLACKSTONE = register(new Block("blackstone", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block BLACKSTONE_STAIRS = register(new Block("blackstone_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) @@ -2235,9 +2235,9 @@ public final class Blocks { public static final Block POLISHED_BLACKSTONE_SLAB = register(new Block("polished_blackstone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block POLISHED_BLACKSTONE_PRESSURE_PLATE = register(new Block("polished_blackstone_pressure_plate", builder().requiresCorrectToolForDrops().destroyTime(0.5f) + public static final Block POLISHED_BLACKSTONE_PRESSURE_PLATE = register(new Block("polished_blackstone_pressure_plate", builder().requiresCorrectToolForDrops().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED))); - public static final Block POLISHED_BLACKSTONE_BUTTON = register(new Block("polished_blackstone_button", builder().destroyTime(0.5f) + public static final Block POLISHED_BLACKSTONE_BUTTON = register(new Block("polished_blackstone_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); @@ -2251,120 +2251,120 @@ public final class Blocks { public static final Block CHISELED_NETHER_BRICKS = register(new Block("chiseled_nether_bricks", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); public static final Block CRACKED_NETHER_BRICKS = register(new Block("cracked_nether_bricks", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); public static final Block QUARTZ_BRICKS = register(new Block("quartz_bricks", builder().requiresCorrectToolForDrops().destroyTime(0.8f))); - public static final Block CANDLE = register(new Block("candle", builder().destroyTime(0.1f) + public static final Block CANDLE = register(new Block("candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block WHITE_CANDLE = register(new Block("white_candle", builder().destroyTime(0.1f) + public static final Block WHITE_CANDLE = register(new Block("white_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block ORANGE_CANDLE = register(new Block("orange_candle", builder().destroyTime(0.1f) + public static final Block ORANGE_CANDLE = register(new Block("orange_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block MAGENTA_CANDLE = register(new Block("magenta_candle", builder().destroyTime(0.1f) + public static final Block MAGENTA_CANDLE = register(new Block("magenta_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block LIGHT_BLUE_CANDLE = register(new Block("light_blue_candle", builder().destroyTime(0.1f) + public static final Block LIGHT_BLUE_CANDLE = register(new Block("light_blue_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block YELLOW_CANDLE = register(new Block("yellow_candle", builder().destroyTime(0.1f) + public static final Block YELLOW_CANDLE = register(new Block("yellow_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block LIME_CANDLE = register(new Block("lime_candle", builder().destroyTime(0.1f) + public static final Block LIME_CANDLE = register(new Block("lime_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block PINK_CANDLE = register(new Block("pink_candle", builder().destroyTime(0.1f) + public static final Block PINK_CANDLE = register(new Block("pink_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block GRAY_CANDLE = register(new Block("gray_candle", builder().destroyTime(0.1f) + public static final Block GRAY_CANDLE = register(new Block("gray_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block LIGHT_GRAY_CANDLE = register(new Block("light_gray_candle", builder().destroyTime(0.1f) + public static final Block LIGHT_GRAY_CANDLE = register(new Block("light_gray_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block CYAN_CANDLE = register(new Block("cyan_candle", builder().destroyTime(0.1f) + public static final Block CYAN_CANDLE = register(new Block("cyan_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block PURPLE_CANDLE = register(new Block("purple_candle", builder().destroyTime(0.1f) + public static final Block PURPLE_CANDLE = register(new Block("purple_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block BLUE_CANDLE = register(new Block("blue_candle", builder().destroyTime(0.1f) + public static final Block BLUE_CANDLE = register(new Block("blue_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block BROWN_CANDLE = register(new Block("brown_candle", builder().destroyTime(0.1f) + public static final Block BROWN_CANDLE = register(new Block("brown_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block GREEN_CANDLE = register(new Block("green_candle", builder().destroyTime(0.1f) + public static final Block GREEN_CANDLE = register(new Block("green_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block RED_CANDLE = register(new Block("red_candle", builder().destroyTime(0.1f) + public static final Block RED_CANDLE = register(new Block("red_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block BLACK_CANDLE = register(new Block("black_candle", builder().destroyTime(0.1f) + public static final Block BLACK_CANDLE = register(new Block("black_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block CANDLE_CAKE = register(new Block("candle_cake", builder().destroyTime(0.5f) + public static final Block CANDLE_CAKE = register(new Block("candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(LIT))); - public static final Block WHITE_CANDLE_CAKE = register(new Block("white_candle_cake", builder().destroyTime(0.5f) + public static final Block WHITE_CANDLE_CAKE = register(new Block("white_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(LIT))); - public static final Block ORANGE_CANDLE_CAKE = register(new Block("orange_candle_cake", builder().destroyTime(0.5f) + public static final Block ORANGE_CANDLE_CAKE = register(new Block("orange_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(LIT))); - public static final Block MAGENTA_CANDLE_CAKE = register(new Block("magenta_candle_cake", builder().destroyTime(0.5f) + public static final Block MAGENTA_CANDLE_CAKE = register(new Block("magenta_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(LIT))); - public static final Block LIGHT_BLUE_CANDLE_CAKE = register(new Block("light_blue_candle_cake", builder().destroyTime(0.5f) + public static final Block LIGHT_BLUE_CANDLE_CAKE = register(new Block("light_blue_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(LIT))); - public static final Block YELLOW_CANDLE_CAKE = register(new Block("yellow_candle_cake", builder().destroyTime(0.5f) + public static final Block YELLOW_CANDLE_CAKE = register(new Block("yellow_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(LIT))); - public static final Block LIME_CANDLE_CAKE = register(new Block("lime_candle_cake", builder().destroyTime(0.5f) + public static final Block LIME_CANDLE_CAKE = register(new Block("lime_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(LIT))); - public static final Block PINK_CANDLE_CAKE = register(new Block("pink_candle_cake", builder().destroyTime(0.5f) + public static final Block PINK_CANDLE_CAKE = register(new Block("pink_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(LIT))); - public static final Block GRAY_CANDLE_CAKE = register(new Block("gray_candle_cake", builder().destroyTime(0.5f) + public static final Block GRAY_CANDLE_CAKE = register(new Block("gray_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(LIT))); - public static final Block LIGHT_GRAY_CANDLE_CAKE = register(new Block("light_gray_candle_cake", builder().destroyTime(0.5f) + public static final Block LIGHT_GRAY_CANDLE_CAKE = register(new Block("light_gray_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(LIT))); - public static final Block CYAN_CANDLE_CAKE = register(new Block("cyan_candle_cake", builder().destroyTime(0.5f) + public static final Block CYAN_CANDLE_CAKE = register(new Block("cyan_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(LIT))); - public static final Block PURPLE_CANDLE_CAKE = register(new Block("purple_candle_cake", builder().destroyTime(0.5f) + public static final Block PURPLE_CANDLE_CAKE = register(new Block("purple_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(LIT))); - public static final Block BLUE_CANDLE_CAKE = register(new Block("blue_candle_cake", builder().destroyTime(0.5f) + public static final Block BLUE_CANDLE_CAKE = register(new Block("blue_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(LIT))); - public static final Block BROWN_CANDLE_CAKE = register(new Block("brown_candle_cake", builder().destroyTime(0.5f) + public static final Block BROWN_CANDLE_CAKE = register(new Block("brown_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(LIT))); - public static final Block GREEN_CANDLE_CAKE = register(new Block("green_candle_cake", builder().destroyTime(0.5f) + public static final Block GREEN_CANDLE_CAKE = register(new Block("green_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(LIT))); - public static final Block RED_CANDLE_CAKE = register(new Block("red_candle_cake", builder().destroyTime(0.5f) + public static final Block RED_CANDLE_CAKE = register(new Block("red_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(LIT))); - public static final Block BLACK_CANDLE_CAKE = register(new Block("black_candle_cake", builder().destroyTime(0.5f) + public static final Block BLACK_CANDLE_CAKE = register(new Block("black_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(LIT))); public static final Block AMETHYST_BLOCK = register(new Block("amethyst_block", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); - public static final Block BUDDING_AMETHYST = register(new Block("budding_amethyst", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); - public static final Block AMETHYST_CLUSTER = register(new Block("amethyst_cluster", builder().destroyTime(1.5f) + public static final Block BUDDING_AMETHYST = register(new Block("budding_amethyst", builder().requiresCorrectToolForDrops().destroyTime(1.5f).pushReaction(PistonBehavior.DESTROY))); + public static final Block AMETHYST_CLUSTER = register(new Block("amethyst_cluster", builder().destroyTime(1.5f).pushReaction(PistonBehavior.DESTROY) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) .booleanState(WATERLOGGED))); - public static final Block LARGE_AMETHYST_BUD = register(new Block("large_amethyst_bud", builder().destroyTime(1.5f) + public static final Block LARGE_AMETHYST_BUD = register(new Block("large_amethyst_bud", builder().destroyTime(1.5f).pushReaction(PistonBehavior.DESTROY) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) .booleanState(WATERLOGGED))); - public static final Block MEDIUM_AMETHYST_BUD = register(new Block("medium_amethyst_bud", builder().destroyTime(1.5f) + public static final Block MEDIUM_AMETHYST_BUD = register(new Block("medium_amethyst_bud", builder().destroyTime(1.5f).pushReaction(PistonBehavior.DESTROY) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) .booleanState(WATERLOGGED))); - public static final Block SMALL_AMETHYST_BUD = register(new Block("small_amethyst_bud", builder().destroyTime(1.5f) + public static final Block SMALL_AMETHYST_BUD = register(new Block("small_amethyst_bud", builder().destroyTime(1.5f).pushReaction(PistonBehavior.DESTROY) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) .booleanState(WATERLOGGED))); public static final Block TUFF = register(new Block("tuff", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); @@ -2430,7 +2430,7 @@ public final class Blocks { .enumState(SCULK_SENSOR_PHASE, "inactive", "active", "cooldown") .booleanState(WATERLOGGED))); public static final Block SCULK = register(new Block("sculk", builder().destroyTime(0.2f))); - public static final Block SCULK_VEIN = register(new Block("sculk_vein", builder().destroyTime(0.2f) + public static final Block SCULK_VEIN = register(new Block("sculk_vein", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .booleanState(DOWN) .booleanState(EAST) .booleanState(NORTH) @@ -2534,49 +2534,49 @@ public final class Blocks { public static final Block WAXED_CUT_COPPER_SLAB = register(new Block("waxed_cut_copper_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(SLAB_TYPE, "top", "bottom", "double") .booleanState(WATERLOGGED))); - public static final Block COPPER_DOOR = register(new Block("copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f) + public static final Block COPPER_DOOR = register(new DoorBlock("copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block EXPOSED_COPPER_DOOR = register(new Block("exposed_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f) + public static final Block EXPOSED_COPPER_DOOR = register(new DoorBlock("exposed_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block OXIDIZED_COPPER_DOOR = register(new Block("oxidized_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f) + public static final Block OXIDIZED_COPPER_DOOR = register(new DoorBlock("oxidized_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block WEATHERED_COPPER_DOOR = register(new Block("weathered_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f) + public static final Block WEATHERED_COPPER_DOOR = register(new DoorBlock("weathered_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block WAXED_COPPER_DOOR = register(new Block("waxed_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f) + public static final Block WAXED_COPPER_DOOR = register(new DoorBlock("waxed_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block WAXED_EXPOSED_COPPER_DOOR = register(new Block("waxed_exposed_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f) + public static final Block WAXED_EXPOSED_COPPER_DOOR = register(new DoorBlock("waxed_exposed_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block WAXED_OXIDIZED_COPPER_DOOR = register(new Block("waxed_oxidized_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f) + public static final Block WAXED_OXIDIZED_COPPER_DOOR = register(new DoorBlock("waxed_oxidized_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block WAXED_WEATHERED_COPPER_DOOR = register(new Block("waxed_weathered_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f) + public static final Block WAXED_WEATHERED_COPPER_DOOR = register(new DoorBlock("waxed_weathered_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .enumState(DOOR_HINGE, "left", "right") @@ -2674,36 +2674,36 @@ public final class Blocks { .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block POINTED_DRIPSTONE = register(new Block("pointed_dripstone", builder().destroyTime(1.5f) + public static final Block POINTED_DRIPSTONE = register(new Block("pointed_dripstone", builder().destroyTime(1.5f).pushReaction(PistonBehavior.DESTROY) .enumState(DRIPSTONE_THICKNESS, "tip_merge", "tip", "frustum", "middle", "base") .enumState(VERTICAL_DIRECTION, Direction.UP, Direction.DOWN) .booleanState(WATERLOGGED))); public static final Block DRIPSTONE_BLOCK = register(new Block("dripstone_block", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); - public static final Block CAVE_VINES = register(new Block("cave_vines", builder() + public static final Block CAVE_VINES = register(new Block("cave_vines", builder().pushReaction(PistonBehavior.DESTROY) .intState(AGE_25, 0, 25) .booleanState(BERRIES))); - public static final Block CAVE_VINES_PLANT = register(new Block("cave_vines_plant", builder() + public static final Block CAVE_VINES_PLANT = register(new Block("cave_vines_plant", builder().pushReaction(PistonBehavior.DESTROY) .booleanState(BERRIES))); - public static final Block SPORE_BLOSSOM = register(new Block("spore_blossom", builder())); - public static final Block AZALEA = register(new Block("azalea", builder())); - public static final Block FLOWERING_AZALEA = register(new Block("flowering_azalea", builder())); - public static final Block MOSS_CARPET = register(new Block("moss_carpet", builder().destroyTime(0.1f))); - public static final Block PINK_PETALS = register(new Block("pink_petals", builder() + public static final Block SPORE_BLOSSOM = register(new Block("spore_blossom", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block AZALEA = register(new Block("azalea", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block FLOWERING_AZALEA = register(new Block("flowering_azalea", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block MOSS_CARPET = register(new Block("moss_carpet", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY))); + public static final Block PINK_PETALS = register(new Block("pink_petals", builder().pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .intState(FLOWER_AMOUNT, 1, 4))); - public static final Block MOSS_BLOCK = register(new Block("moss_block", builder().destroyTime(0.1f))); - public static final Block BIG_DRIPLEAF = register(new Block("big_dripleaf", builder().destroyTime(0.1f) + public static final Block MOSS_BLOCK = register(new Block("moss_block", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY))); + public static final Block BIG_DRIPLEAF = register(new Block("big_dripleaf", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(TILT, "none", "unstable", "partial", "full") .booleanState(WATERLOGGED))); - public static final Block BIG_DRIPLEAF_STEM = register(new Block("big_dripleaf_stem", builder().destroyTime(0.1f) + public static final Block BIG_DRIPLEAF_STEM = register(new Block("big_dripleaf_stem", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); - public static final Block SMALL_DRIPLEAF = register(new Block("small_dripleaf", builder() + public static final Block SMALL_DRIPLEAF = register(new Block("small_dripleaf", builder().pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") .booleanState(WATERLOGGED))); - public static final Block HANGING_ROOTS = register(new Block("hanging_roots", builder() + public static final Block HANGING_ROOTS = register(new Block("hanging_roots", builder().pushReaction(PistonBehavior.DESTROY) .booleanState(WATERLOGGED))); public static final Block ROOTED_DIRT = register(new Block("rooted_dirt", builder().destroyTime(0.5f))); public static final Block MUD = register(new Block("mud", builder().destroyTime(0.5f))); @@ -2782,17 +2782,17 @@ public final class Blocks { public static final Block RAW_IRON_BLOCK = register(new Block("raw_iron_block", builder().requiresCorrectToolForDrops().destroyTime(5.0f))); public static final Block RAW_COPPER_BLOCK = register(new Block("raw_copper_block", builder().requiresCorrectToolForDrops().destroyTime(5.0f))); public static final Block RAW_GOLD_BLOCK = register(new Block("raw_gold_block", builder().requiresCorrectToolForDrops().destroyTime(5.0f))); - public static final Block POTTED_AZALEA_BUSH = register(new Block("potted_azalea_bush", builder())); - public static final Block POTTED_FLOWERING_AZALEA_BUSH = register(new Block("potted_flowering_azalea_bush", builder())); + public static final Block POTTED_AZALEA_BUSH = register(new FlowerPotBlock("potted_azalea_bush", AZALEA, builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block POTTED_FLOWERING_AZALEA_BUSH = register(new FlowerPotBlock("potted_flowering_azalea_bush", FLOWERING_AZALEA, builder().pushReaction(PistonBehavior.DESTROY))); public static final Block OCHRE_FROGLIGHT = register(new Block("ochre_froglight", builder().destroyTime(0.3f) .enumState(AXIS, Axis.VALUES))); public static final Block VERDANT_FROGLIGHT = register(new Block("verdant_froglight", builder().destroyTime(0.3f) .enumState(AXIS, Axis.VALUES))); public static final Block PEARLESCENT_FROGLIGHT = register(new Block("pearlescent_froglight", builder().destroyTime(0.3f) .enumState(AXIS, Axis.VALUES))); - public static final Block FROGSPAWN = register(new Block("frogspawn", builder())); + public static final Block FROGSPAWN = register(new Block("frogspawn", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block REINFORCED_DEEPSLATE = register(new Block("reinforced_deepslate", builder().destroyTime(55.0f))); - public static final Block DECORATED_POT = register(new Block("decorated_pot", builder().setBlockEntity() + public static final Block DECORATED_POT = register(new Block("decorated_pot", builder().setBlockEntity().pushReaction(PistonBehavior.DESTROY) .booleanState(CRACKED) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); diff --git a/core/src/main/java/org/geysermc/geyser/level/block/property/Properties.java b/core/src/main/java/org/geysermc/geyser/level/block/property/Properties.java index bbb6f8fe3..339d82f96 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/property/Properties.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/property/Properties.java @@ -118,7 +118,7 @@ public final class Properties { public static final Property RESPAWN_ANCHOR_CHARGES = Property.create("charges"); public static final Property ROTATION_16 = Property.create("rotation"); public static final Property BED_PART = Property.create("part"); - public static final Property CHEST_TYPE = Property.create("type"); + public static final Property CHEST_TYPE = Property.create("type"); public static final Property MODE_COMPARATOR = Property.create("mode"); public static final Property DOOR_HINGE = Property.create("hinge"); public static final Property NOTEBLOCK_INSTRUMENT = Property.create("instrument"); diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java b/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java index 84822ca16..3114f31f9 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java @@ -30,8 +30,15 @@ import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.objects.Reference2ObjectArrayMap; import it.unimi.dsi.fastutil.objects.Reference2ObjectMap; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.math.vector.Vector3i; +import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; +import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.level.block.property.Property; +import org.geysermc.geyser.level.physics.PistonBehavior; import org.geysermc.geyser.registry.BlockRegistries; +import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.Identifier; import java.util.*; @@ -44,6 +51,7 @@ public class Block { private final boolean requiresCorrectToolForDrops; private final boolean hasBlockEntity; private final float destroyTime; + private final @NonNull PistonBehavior pushReaction; private int javaId = -1; public Block(String javaIdentifier, Builder builder) { @@ -51,9 +59,76 @@ public class Block { this.requiresCorrectToolForDrops = builder.requiresCorrectToolForDrops; this.hasBlockEntity = builder.hasBlockEntity; this.destroyTime = builder.destroyTime; + this.pushReaction = builder.pushReaction; builder.build(this); } + public void updateBlock(GeyserSession session, BlockState state, Vector3i position) { + BlockDefinition definition = session.getBlockMappings().getBedrockBlock(state); + sendBlockUpdatePacket(session, state, definition, position); + + { + // Extended collision boxes for custom blocks + if (!session.getBlockMappings().getExtendedCollisionBoxes().isEmpty()) { + int aboveBlock = session.getGeyser().getWorldManager().getBlockAt(session, position.getX(), position.getY() + 1, position.getZ()); + BlockDefinition aboveBedrockExtendedCollisionDefinition = session.getBlockMappings().getExtendedCollisionBoxes().get(state.javaId()); + int belowBlock = session.getGeyser().getWorldManager().getBlockAt(session, position.getX(), position.getY() - 1, position.getZ()); + BlockDefinition belowBedrockExtendedCollisionDefinition = session.getBlockMappings().getExtendedCollisionBoxes().get(belowBlock); + if (belowBedrockExtendedCollisionDefinition != null && state.is(Blocks.AIR)) { + UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); + updateBlockPacket.setDataLayer(0); + updateBlockPacket.setBlockPosition(position); + updateBlockPacket.setDefinition(belowBedrockExtendedCollisionDefinition); + updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK); + session.sendUpstreamPacket(updateBlockPacket); + } else if (aboveBedrockExtendedCollisionDefinition != null && aboveBlock == Block.JAVA_AIR_ID) { + UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); + updateBlockPacket.setDataLayer(0); + updateBlockPacket.setBlockPosition(position.add(0, 1, 0)); + updateBlockPacket.setDefinition(aboveBedrockExtendedCollisionDefinition); + updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK); + session.sendUpstreamPacket(updateBlockPacket); + } else if (aboveBlock == Block.JAVA_AIR_ID) { + UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); + updateBlockPacket.setDataLayer(0); + updateBlockPacket.setBlockPosition(position.add(0, 1, 0)); + updateBlockPacket.setDefinition(session.getBlockMappings().getBedrockAir()); + updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK); + session.sendUpstreamPacket(updateBlockPacket); + } + } + } + + handleLecternBlockUpdate(session, state, position); + } + + protected void sendBlockUpdatePacket(GeyserSession session, BlockState state, BlockDefinition definition, Vector3i position) { + UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); + updateBlockPacket.setDataLayer(0); + updateBlockPacket.setBlockPosition(position); + updateBlockPacket.setDefinition(definition); + updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS); + updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK); + session.sendUpstreamPacket(updateBlockPacket); + + UpdateBlockPacket waterPacket = new UpdateBlockPacket(); + waterPacket.setDataLayer(1); + waterPacket.setBlockPosition(position); + if (BlockRegistries.WATERLOGGED.get().get(state.javaId())) { + waterPacket.setDefinition(session.getBlockMappings().getBedrockWater()); + } else { + waterPacket.setDefinition(session.getBlockMappings().getBedrockAir()); + } + session.sendUpstreamPacket(waterPacket); + } + + protected void handleLecternBlockUpdate(GeyserSession session, BlockState state, Vector3i position) { + // Block state is out of bounds of this map - lectern has been destroyed, if it existed + if (!session.getGeyser().getWorldManager().shouldExpectLecternHandled(session)) { + session.getLecternCache().remove(position); + } + } + public String javaIdentifier() { return javaIdentifier; } @@ -70,6 +145,11 @@ public class Block { return destroyTime; } + @NonNull + public PistonBehavior pushReaction() { + return this.pushReaction; + } + public int javaId() { return javaId; } @@ -97,6 +177,7 @@ public class Block { private final Map, List>> states = new LinkedHashMap<>(); private boolean requiresCorrectToolForDrops = false; private boolean hasBlockEntity = false; + private PistonBehavior pushReaction = PistonBehavior.NORMAL; private float destroyTime; /** @@ -143,6 +224,11 @@ public class Block { return this; } + public Builder pushReaction(PistonBehavior pushReaction) { + this.pushReaction = pushReaction; + return this; + } + private void build(Block block) { if (states.isEmpty()) { BlockRegistries.BLOCK_STATES.get().add(new BlockState(block, BlockRegistries.BLOCK_STATES.get().size())); diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java b/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java index 936b711e4..23e89d99f 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java @@ -58,6 +58,10 @@ public final class BlockState { return javaId; } + public boolean is(Block block) { + return this.block == block; + } + public static BlockState of(int javaId) { return BlockRegistries.BLOCK_STATES.get(javaId); } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/CauldronBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/CauldronBlock.java new file mode 100644 index 000000000..d27969af7 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/CauldronBlock.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.type; + +import org.cloudburstmc.math.vector.Vector3i; +import org.cloudburstmc.nbt.NbtList; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtType; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.level.block.entity.BedrockChunkWantsBlockEntityTag; +import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator; + +public class CauldronBlock extends Block implements BedrockChunkWantsBlockEntityTag { + public CauldronBlock(String javaIdentifier, Builder builder) { + super(javaIdentifier, builder); + } + + @Override + public NbtMap createTag(GeyserSession session, Vector3i position, BlockState blockState) { + // As of 1.18.30: this is required to make rendering not look weird on chunk load (lava and snow cauldrons look dim) + return BlockEntityTranslator.getConstantBedrockTag("Cauldron", position.getX(), position.getY(), position.getZ()) + .putByte("isMovable", (byte) 0) + .putShort("PotionId", (short) -1) + .putShort("PotionType", (short) -1) + .putList("Items", NbtType.END, NbtList.EMPTY) + .build(); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/ChestBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/ChestBlock.java new file mode 100644 index 000000000..69132ccfd --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/ChestBlock.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.type; + +import org.cloudburstmc.math.vector.Vector3i; +import org.cloudburstmc.nbt.NbtMapBuilder; +import org.geysermc.geyser.level.block.property.ChestType; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator; +import org.geysermc.geyser.util.BlockEntityUtils; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; + +public class ChestBlock extends Block { + public ChestBlock(String javaIdentifier, Builder builder) { + super(javaIdentifier, builder); + } + + @Override + public void updateBlock(GeyserSession session, BlockState state, Vector3i position) { + super.updateBlock(session, state, position); + + if (state.getValue(Properties.CHEST_TYPE) != ChestType.SINGLE) { + NbtMapBuilder tagBuilder = BlockEntityTranslator.getConstantBedrockTag(BlockEntityType.CHEST, position.getX(), position.getY(), position.getZ()); + BlockEntityUtils.getBlockEntityTranslator(BlockEntityType.CHEST).translateTag(session, tagBuilder, null, state); //TODO + BlockEntityUtils.updateBlockEntity(session, tagBuilder.build(), position); + } + } +} diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/DoorBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/DoorBlock.java new file mode 100644 index 000000000..bfde51a79 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/DoorBlock.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.type; + +import org.cloudburstmc.math.vector.Vector3i; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.util.ChunkUtils; + +public class DoorBlock extends Block { + public DoorBlock(String javaIdentifier, Builder builder) { + super(javaIdentifier, builder); + } + + @Override + public void updateBlock(GeyserSession session, BlockState state, Vector3i position) { + super.updateBlock(session, state, position); + + if (state.getValue(Properties.DOUBLE_BLOCK_HALF).equals("upper")) { + // Update the lower door block as Bedrock client doesn't like door to be closed from the top + // See https://github.com/GeyserMC/Geyser/issues/4358 + Vector3i belowDoorPosition = position.sub(0, 1, 0); + BlockState belowDoorBlockState = session.getGeyser().getWorldManager().blockAt(session, belowDoorPosition.getX(), belowDoorPosition.getY(), belowDoorPosition.getZ()); + ChunkUtils.updateBlock(session, belowDoorBlockState, belowDoorPosition); + } + } +} diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/FlowerPotBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/level/block/type/FlowerPotBlock.java similarity index 60% rename from core/src/main/java/org/geysermc/geyser/translator/level/block/entity/FlowerPotBlockEntityTranslator.java rename to core/src/main/java/org/geysermc/geyser/level/block/type/FlowerPotBlock.java index 0a60b0f32..8c911ad97 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/FlowerPotBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/FlowerPotBlock.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * Copyright (c) 2024 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,65 +23,35 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.geyser.translator.level.block.entity; +package org.geysermc.geyser.level.block.type; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; -import org.geysermc.geyser.level.block.BlockStateValues; -import org.geysermc.geyser.level.block.type.BlockState; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.level.block.entity.BedrockChunkWantsBlockEntityTag; +import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator; import org.geysermc.geyser.util.BlockEntityUtils; -public class FlowerPotBlockEntityTranslator implements BedrockOnlyBlockEntity { - /** - * @param blockState the Java block state of a potential flower pot block - * @return true if the block is a flower pot - */ - public static boolean isFlowerBlock(int blockState) { - return BlockStateValues.getFlowerPotValues().containsKey(blockState); - } +public class FlowerPotBlock extends Block implements BedrockChunkWantsBlockEntityTag { + private final Block flower; - /** - * Get the Nukkit CompoundTag of the flower pot. - * - * @param blockState Java block state of flower pot. - * @param position Bedrock position of flower pot. - * @return Bedrock tag of flower pot. - */ - public static NbtMap getTag(GeyserSession session, int blockState, Vector3i position) { - NbtMapBuilder tagBuilder = NbtMap.builder() - .putInt("x", position.getX()) - .putInt("y", position.getY()) - .putInt("z", position.getZ()) - .putByte("isMovable", (byte) 1) - .putString("id", "FlowerPot"); - // Get the Java name of the plant inside. e.g. minecraft:oak_sapling - String name = BlockStateValues.getFlowerPotValues().get(blockState); - if (name != null) { - // Get the Bedrock CompoundTag of the block. - // This is where we need to store the *Java* name because Bedrock has six minecraft:sapling blocks with different block states. - NbtMap plant = session.getBlockMappings().getFlowerPotBlocks().get(name); - if (plant != null) { - tagBuilder.put("PlantBlock", plant.toBuilder().build()); - } - } - return tagBuilder.build(); + public FlowerPotBlock(String javaIdentifier, Block flower, Builder builder) { + super(javaIdentifier, builder); + this.flower = flower; } @Override - public boolean isBlock(int blockState) { - return isFlowerBlock(blockState); - } + public void updateBlock(GeyserSession session, BlockState state, Vector3i position) { + super.updateBlock(session, state, position); - @Override - public void updateBlock(GeyserSession session, BlockState blockState, Vector3i position) { - NbtMap tag = getTag(session, blockState.javaId(), position); + NbtMap tag = createTag(session, position, state); BlockEntityUtils.updateBlockEntity(session, tag, position); UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); updateBlockPacket.setDataLayer(0); - updateBlockPacket.setDefinition(session.getBlockMappings().getBedrockBlock(blockState.javaId())); + updateBlockPacket.setDefinition(session.getBlockMappings().getBedrockBlock(state)); updateBlockPacket.setBlockPosition(position); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK); @@ -89,4 +59,20 @@ public class FlowerPotBlockEntityTranslator implements BedrockOnlyBlockEntity { session.sendUpstreamPacket(updateBlockPacket); BlockEntityUtils.updateBlockEntity(session, tag, position); } + + @Override + public NbtMap createTag(GeyserSession session, Vector3i position, BlockState blockState) { + NbtMapBuilder tagBuilder = BlockEntityTranslator.getConstantBedrockTag("FlowerPot", position.getX(), position.getY(), position.getZ()) + .putByte("isMovable", (byte) 1); + // Get the Java name of the plant inside. e.g. minecraft:oak_sapling + if (this.flower != Blocks.AIR) { + // Get the Bedrock CompoundTag of the block. + // This is where we need to store the *Java* name because Bedrock has six minecraft:sapling blocks with different block states. + NbtMap plant = session.getBlockMappings().getFlowerPotBlocks().get(this.flower.javaIdentifier()); + if (plant != null) { + tagBuilder.putCompound("PlantBlock", plant.toBuilder().build()); + } + } + return tagBuilder.build(); + } } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/LecternBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/LecternBlock.java new file mode 100644 index 000000000..6b8aa02b5 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/LecternBlock.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.type; + +import org.cloudburstmc.math.vector.Vector3i; +import org.cloudburstmc.nbt.NbtMap; +import org.geysermc.erosion.util.LecternUtils; +import org.geysermc.geyser.level.WorldManager; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.util.BlockEntityUtils; + +public class LecternBlock extends Block { + public LecternBlock(String javaIdentifier, Builder builder) { + super(javaIdentifier, builder); + } + + @Override + protected void handleLecternBlockUpdate(GeyserSession session, BlockState state, Vector3i position) { + WorldManager worldManager = session.getGeyser().getWorldManager(); + if (worldManager.shouldExpectLecternHandled(session)) { + worldManager.sendLecternData(session, position.getX(), position.getY(), position.getZ()); + return; + } + + boolean currentHasBook = state.getValue(Properties.HAS_BOOK); + Boolean previousHasBook = worldManager.blockAt(session, position).getValue(Properties.HAS_BOOK); // Can be null if not a lectern, watch out + if (currentHasBook != previousHasBook) { + if (currentHasBook) { + worldManager.sendLecternData(session, position.getX(), position.getY(), position.getZ()); + } else { + session.getLecternCache().remove(position); + NbtMap newLecternTag = LecternUtils.getBaseLecternTag(position.getX(), position.getY(), position.getZ(), 0).build(); + BlockEntityUtils.updateBlockEntity(session, newLecternTag, position); + } + } + } +} diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/MovingPistonBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/MovingPistonBlock.java new file mode 100644 index 000000000..e4df8d88b --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/MovingPistonBlock.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.type; + +import org.cloudburstmc.math.vector.Vector3i; +import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; +import org.geysermc.geyser.session.GeyserSession; + +public class MovingPistonBlock extends Block { + public MovingPistonBlock(String javaIdentifier, Builder builder) { + super(javaIdentifier, builder); + } + + @Override + protected void sendBlockUpdatePacket(GeyserSession session, BlockState state, BlockDefinition definition, Vector3i position) { + // Prevent moving_piston from being placed + // It's used for extending piston heads, but it isn't needed on Bedrock and causes pistons to flicker + } +} diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/PistonBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/PistonBlock.java new file mode 100644 index 000000000..fc54115eb --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/PistonBlock.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.type; + +import org.cloudburstmc.math.vector.Vector3i; +import org.cloudburstmc.nbt.NbtMap; +import org.geysermc.geyser.level.block.Blocks; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.level.block.entity.BedrockChunkWantsBlockEntityTag; +import org.geysermc.geyser.translator.level.block.entity.PistonBlockEntity; + +public class PistonBlock extends Block implements BedrockChunkWantsBlockEntityTag { + public PistonBlock(String javaIdentifier, Builder builder) { + super(javaIdentifier, builder); + } + + @Override + public NbtMap createTag(GeyserSession session, Vector3i position, BlockState blockState) { + boolean extended = blockState.getValue(Properties.EXTENDED); + boolean sticky = blockState.is(Blocks.STICKY_PISTON); + return PistonBlockEntity.buildStaticPistonTag(position, extended, sticky); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/SkullBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/SkullBlock.java new file mode 100644 index 000000000..01a757eae --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/SkullBlock.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.type; + +import org.cloudburstmc.math.vector.Vector3i; +import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; +import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.session.cache.SkullCache; + +public class SkullBlock extends Block { + public SkullBlock(String javaIdentifier, Builder builder) { + super(javaIdentifier, builder); + } + + @Override + protected void sendBlockUpdatePacket(GeyserSession session, BlockState state, BlockDefinition definition, Vector3i position) { + int skullVariant = BlockStateValues.getSkullVariant(state.javaId()); // TODO + if (skullVariant == -1) { + // Skull is gone + session.getSkullCache().removeSkull(position); + } else if (skullVariant == 3) { + // The changed block was a player skull so check if a custom block was defined for this skull + SkullCache.Skull skull = session.getSkullCache().updateSkull(position, state.javaId()); + if (skull != null && skull.getBlockDefinition() != null) { + definition = skull.getBlockDefinition(); + } + } + super.sendBlockUpdatePacket(session, state, definition, position); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java index 64b466f12..66301cef2 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java @@ -424,39 +424,12 @@ public final class BlockRegistryPopulator { // TODO fix this, (no block should have a null hardness) BlockMapping.BlockMappingBuilder builder = BlockMapping.builder(); - JsonNode hardnessNode = entry.getValue().get("block_hardness"); - if (hardnessNode != null) { - builder.hardness(hardnessNode.floatValue()); - } - - JsonNode canBreakWithHandNode = entry.getValue().get("can_break_with_hand"); - if (canBreakWithHandNode != null) { - builder.canBreakWithHand(canBreakWithHandNode.booleanValue()); - } else { - builder.canBreakWithHand(false); - } - - JsonNode collisionIndexNode = entry.getValue().get("collision_index"); - if (hardnessNode != null) { - builder.collisionIndex(collisionIndexNode.intValue()); - } JsonNode pickItemNode = entry.getValue().get("pick_item"); if (pickItemNode != null) { builder.pickItem(pickItemNode.textValue().intern()); } - if (javaId.equals("minecraft:obsidian") || javaId.equals("minecraft:crying_obsidian") || javaId.startsWith("minecraft:respawn_anchor") || javaId.startsWith("minecraft:reinforced_deepslate")) { - builder.pistonBehavior(PistonBehavior.BLOCK); - } else { - JsonNode pistonBehaviorNode = entry.getValue().get("piston_behavior"); - if (pistonBehaviorNode != null) { - builder.pistonBehavior(PistonBehavior.getByName(pistonBehaviorNode.textValue())); - } else { - builder.pistonBehavior(PistonBehavior.NORMAL); - } - } - JsonNode hasBlockEntityNode = entry.getValue().get("has_block_entity"); if (hasBlockEntityNode != null) { builder.isBlockEntity(hasBlockEntityNode.booleanValue()); @@ -475,7 +448,6 @@ public final class BlockRegistryPopulator { } builder.javaIdentifier(javaId); - builder.javaBlockId(uniqueJavaId); BlockRegistries.JAVA_IDENTIFIER_TO_ID.register(javaId, javaRuntimeId); BlockRegistries.JAVA_BLOCKS.register(javaRuntimeId, builder.build()); @@ -547,26 +519,23 @@ public final class BlockRegistryPopulator { int stateRuntimeId = javaBlockState.javaId(); String pistonBehavior = javaBlockState.pistonBehavior(); BlockMapping blockMapping = BlockMapping.builder() - .canBreakWithHand(javaBlockState.canBreakWithHand()) .pickItem(javaBlockState.pickItem()) .isNonVanilla(true) .javaIdentifier(javaId) - .javaBlockId(javaBlockState.stateGroupId()) - .hardness(javaBlockState.blockHardness()) - .pistonBehavior(pistonBehavior == null ? PistonBehavior.NORMAL : PistonBehavior.getByName(pistonBehavior)) - .isBlockEntity(javaBlockState.hasBlockEntity()) .build(); Block.Builder builder = Block.builder() - .destroyTime(javaBlockState.blockHardness()); + .destroyTime(javaBlockState.blockHardness()) + .pushReaction(pistonBehavior == null ? PistonBehavior.NORMAL : PistonBehavior.getByName(pistonBehavior)); if (!javaBlockState.canBreakWithHand()) { builder.requiresCorrectToolForDrops(); } if (javaBlockState.hasBlockEntity()) { builder.setBlockEntity(); } - String cleanJavaIdentifier = BlockUtils.getCleanIdentifier(javaBlockState.identifier()); + Block block = new Block(cleanJavaIdentifier, builder); + String bedrockIdentifier = customBlockState.block().identifier(); if (!cleanJavaIdentifier.equals(cleanIdentifiers.peekLast())) { @@ -574,6 +543,7 @@ public final class BlockRegistryPopulator { cleanIdentifiers.add(cleanJavaIdentifier.intern()); } + BlockRegistries.JAVA_BLOCKS_TO_RENAME.get().add(javaBlockState.stateGroupId(), block); //TODO don't allow duplicates, allow blanks BlockRegistries.JAVA_IDENTIFIER_TO_ID.register(javaId, stateRuntimeId); BlockRegistries.JAVA_BLOCKS.register(stateRuntimeId, blockMapping); diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/BlockMapping.java b/core/src/main/java/org/geysermc/geyser/registry/type/BlockMapping.java index 0196ac22f..d6ee55965 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/type/BlockMapping.java +++ b/core/src/main/java/org/geysermc/geyser/registry/type/BlockMapping.java @@ -27,32 +27,19 @@ package org.geysermc.geyser.registry.type; import lombok.Builder; import lombok.Value; -import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; -import org.geysermc.geyser.level.physics.PistonBehavior; import org.geysermc.geyser.util.BlockUtils; @Builder @Value public class BlockMapping { - public static BlockMapping DEFAULT = BlockMapping.builder().javaIdentifier("minecraft:air").pistonBehavior(PistonBehavior.NORMAL).build(); + public static BlockMapping DEFAULT = BlockMapping.builder().javaIdentifier("minecraft:air").build(); String javaIdentifier; - /** - * The block ID shared between all different block states of this block. - * NOT the runtime ID! - */ - int javaBlockId; - float hardness; boolean canBreakWithHand; - /** - * The index of this collision in collision.json - */ - int collisionIndex; @Nullable String pickItem; - @NonNull PistonBehavior pistonBehavior; boolean isBlockEntity; boolean isNonVanilla; diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java b/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java index c76f024af..2fe808070 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java +++ b/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java @@ -35,6 +35,7 @@ import org.cloudburstmc.protocol.bedrock.data.BlockPropertyData; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.common.DefinitionRegistry; import org.geysermc.geyser.api.block.custom.CustomBlockState; +import org.geysermc.geyser.level.block.type.BlockState; import java.util.List; import java.util.Map; @@ -78,6 +79,10 @@ public class BlockMappings implements DefinitionRegistry { return this.javaToBedrockBlocks[javaState]; } + public GeyserBedrockBlock getBedrockBlock(BlockState javaState) { + return this.getBedrockBlock(javaState.javaId()); + } + public GeyserBedrockBlock getVanillaBedrockBlock(int javaState) { if (javaState < 0 || javaState >= this.javaToVanillaBedrockBlocks.length) { return bedrockAir; diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java index 6da354646..95f5c1cc3 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java @@ -30,7 +30,6 @@ import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.level.block.type.Block; -import org.geysermc.geyser.registry.type.BlockMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.BlockTag; import org.geysermc.geyser.session.cache.tags.ItemTag; @@ -107,17 +106,6 @@ public final class TagCache { return false; } - /** - * @return true if the block tag is present and contains this block mapping's Java ID. - */ - public boolean is(BlockTag tag, BlockMapping mapping) { - IntList values = this.blocks.get(tag); - if (values != null) { - return values.contains(mapping.getJavaBlockId()); - } - return false; - } - /** * @return true if the item tag is present and contains this item stack's Java ID. */ diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/WorldCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/WorldCache.java index c84126608..44ec7a6b9 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/WorldCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/WorldCache.java @@ -180,7 +180,7 @@ public final class WorldCache { // This block may be out of sync with the server // In 1.19.0 Java, you can verify this by trying to mine in spawn protection Vector3i position = entry.getKey(); - ChunkUtils.updateBlockClientSide(session, session.getGeyser().getWorldManager().getBlockAt(session, position), position); + ChunkUtils.updateBlockClientSide(session, session.getGeyser().getWorldManager().blockAt(session, position), position); it.remove(); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedrockChunkWantsBlockEntityTag.java similarity index 59% rename from core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntityTranslator.java rename to core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedrockChunkWantsBlockEntityTag.java index a55fa8a62..189fb2c65 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedrockChunkWantsBlockEntityTag.java @@ -27,32 +27,18 @@ package org.geysermc.geyser.translator.level.block.entity; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; -import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.type.BlockState; +import org.geysermc.geyser.session.GeyserSession; /** - * Pistons are a special case where they are only a block entity on Bedrock. + * Implemented only if a block is a block entity in Bedrock and not Java Edition. */ -public class PistonBlockEntityTranslator { +public interface BedrockChunkWantsBlockEntityTag extends RequiresBlockState { /** - * Used in ChunkUtils to determine if the block is a piston. - * + * Get the tag of the Bedrock-only block entity. Used during chunk loading. + * @param position Bedrock position of block. * @param blockState Java BlockState of block. - * @return if block is a piston or not. + * @return Bedrock tag */ - public static boolean isBlock(int blockState) { - return BlockStateValues.getPistonValues().containsKey(blockState); - } - - /** - * Calculates the Nukkit CompoundTag to send to the client on chunk - * - * @param blockState Java block state of block. - * @param position Bedrock position of piston. - * @return Bedrock tag of piston. - */ - public static NbtMap getTag(int blockState, Vector3i position) { - boolean extended = BlockStateValues.getPistonValues().get(blockState); - boolean sticky = BlockStateValues.isStickyPiston(blockState); - return PistonBlockEntity.buildStaticPistonTag(position, extended, sticky); - } + NbtMap createTag(GeyserSession session, Vector3i position, BlockState blockState); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedrockOnlyBlockEntity.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedrockOnlyBlockEntity.java deleted file mode 100644 index 01e2d3e74..000000000 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedrockOnlyBlockEntity.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.geyser.translator.level.block.entity; - -import org.checkerframework.checker.nullness.qual.Nullable; -import org.cloudburstmc.math.vector.Vector3i; -import org.cloudburstmc.nbt.NbtList; -import org.cloudburstmc.nbt.NbtMap; -import org.cloudburstmc.nbt.NbtType; -import org.geysermc.geyser.level.block.BlockStateValues; -import org.geysermc.geyser.level.block.type.BlockState; -import org.geysermc.geyser.session.GeyserSession; - -/** - * Implemented only if a block is a block entity in Bedrock and not Java Edition. - */ -public interface BedrockOnlyBlockEntity extends RequiresBlockState { - /** - * Determines if block is part of class - * @param blockState BlockState to be compared - * @return true if part of the class - */ - boolean isBlock(int blockState); - - /** - * Update the block on Bedrock Edition. - * @param session GeyserConnection. - * @param blockState The Java block state. - * @param position The Bedrock block position. - */ - void updateBlock(GeyserSession session, BlockState blockState, Vector3i position); - - /** - * Get the tag of the Bedrock-only block entity - * @param position Bedrock position of block. - * @param blockState Java BlockState of block. - * @return Bedrock tag, or null if not a Bedrock-only Block Entity - */ - static @Nullable NbtMap getTag(GeyserSession session, Vector3i position, int blockState) { - if (FlowerPotBlockEntityTranslator.isFlowerBlock(blockState)) { - return FlowerPotBlockEntityTranslator.getTag(session, blockState, position); - } else if (PistonBlockEntityTranslator.isBlock(blockState)) { - return PistonBlockEntityTranslator.getTag(blockState, position); - } else if (BlockStateValues.isCauldron(blockState)) { - // As of 1.18.30: this is required to make rendering not look weird on chunk load (lava and snow cauldrons look dim) - return NbtMap.builder() - .putString("id", "Cauldron") - .putByte("isMovable", (byte) 0) - .putShort("PotionId", (short) -1) - .putShort("PotionType", (short) -1) - .putList("Items", NbtType.END, NbtList.EMPTY) - .putInt("x", position.getX()) - .putInt("y", position.getY()) - .putInt("z", position.getZ()) - .build(); - } - return null; - } -} diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java index 63c5f71f3..102f4a0e6 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java @@ -25,33 +25,20 @@ package org.geysermc.geyser.translator.level.block.entity; -import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; -import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.property.ChestType; import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.level.physics.Direction; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.util.BlockEntityUtils; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; /** - * Chests have more block entity properties in Bedrock, which is solved by implementing the BedrockOnlyBlockEntity + * Chests have more block entity properties in Bedrock, which is solved by implementing the BedrockChunkWantsBlockEntityTag */ @BlockEntity(type = { BlockEntityType.CHEST, BlockEntityType.TRAPPED_CHEST }) -public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator implements BedrockOnlyBlockEntity { - @Override - public boolean isBlock(int blockState) { - return BlockStateValues.getDoubleChestValues().containsKey(blockState); - } - - @Override - public void updateBlock(GeyserSession session, BlockState blockState, Vector3i position) { - NbtMapBuilder tagBuilder = getConstantBedrockTag(BlockEntityUtils.getBedrockBlockEntityId(BlockEntityType.CHEST), position.getX(), position.getY(), position.getZ()); - translateTag(session, tagBuilder, null, blockState); - BlockEntityUtils.updateBlockEntity(session, tagBuilder.build(), position); - } +public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator { @Override public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) { @@ -71,7 +58,7 @@ public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator impl public static void translateChestValue(NbtMapBuilder builder, BlockState state, int x, int z) { // Calculate the position of the other chest based on the Java block state Direction facing = state.getValue(Properties.HORIZONTAL_FACING); - boolean isLeft = state.getValue(Properties.CHEST_TYPE).equals("left"); //TODO enum + boolean isLeft = state.getValue(Properties.CHEST_TYPE) == ChestType.LEFT; switch (facing) { case EAST -> z = z + (isLeft ? 1 : -1); case WEST -> z = z + (isLeft ? -1 : 1); diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java index e09f6ae42..abe3a197e 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java @@ -25,7 +25,11 @@ package org.geysermc.geyser.translator.level.block.entity; +import it.unimi.dsi.fastutil.objects.*; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.level.block.type.Block; +import org.geysermc.geyser.level.block.type.BlockState; +import org.geysermc.geyser.level.block.type.PistonBlock; import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.PistonValueType; import org.cloudburstmc.math.vector.Vector3d; import org.cloudburstmc.math.vector.Vector3f; @@ -33,9 +37,6 @@ import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; -import it.unimi.dsi.fastutil.objects.Object2IntMap; -import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; -import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import lombok.Getter; import org.geysermc.geyser.api.util.PlatformType; import org.geysermc.geyser.level.block.BlockStateValues; @@ -69,7 +70,7 @@ public class PistonBlockEntity { /** * A map of attached block positions to Java ids. */ - private final Object2IntMap attachedBlocks = new Object2IntOpenHashMap<>(); + private final Object2ObjectMap attachedBlocks = new Object2ObjectOpenHashMap<>(); /** * A flattened array of the positions of attached blocks, stored in XYZ order. */ @@ -158,7 +159,7 @@ public class PistonBlockEntity { BlockEntityUtils.updateBlockEntity(session, buildPistonTag(), position); } - public void setAction(PistonValueType action, Object2IntMap attachedBlocks) { + public void setAction(PistonValueType action, Map attachedBlocks) { // Don't check if this.action == action, since on some Paper versions BlockPistonRetractEvent is called multiple times // with the first 1-2 events being empty. placeFinalBlocks(); @@ -255,13 +256,13 @@ public class PistonBlockEntity { if (!blocksChecked.add(blockPos)) { continue; } - int blockId = session.getGeyser().getWorldManager().getBlockAt(session, blockPos); - if (blockId == Block.JAVA_AIR_ID) { + BlockState state = session.getGeyser().getWorldManager().blockAt(session, blockPos); + if (state.block() == Blocks.AIR) { continue; } - if (BlockStateValues.canPistonMoveBlock(blockId, action == PistonValueType.PUSHING)) { - attachedBlocks.put(blockPos, blockId); - if (BlockStateValues.isBlockSticky(blockId)) { + if (BlockStateValues.canPistonMoveBlock(state, action == PistonValueType.PUSHING)) { + attachedBlocks.put(blockPos, state); + if (BlockStateValues.isBlockSticky(state)) { // For honey blocks and slime blocks check the blocks adjacent to it for (Direction direction : Direction.VALUES) { Vector3i offset = direction.getUnitVector(); @@ -278,13 +279,13 @@ public class PistonBlockEntity { if (action == PistonValueType.PULLING && position.add(directionOffset).equals(adjacentPos)) { continue; } - int adjacentBlockId = session.getGeyser().getWorldManager().getBlockAt(session, adjacentPos); - if (adjacentBlockId != Block.JAVA_AIR_ID && BlockStateValues.isBlockAttached(blockId, adjacentBlockId) && BlockStateValues.canPistonMoveBlock(adjacentBlockId, false)) { + BlockState adjacentBlockState = session.getGeyser().getWorldManager().blockAt(session, adjacentPos); + if (adjacentBlockState.block() != Blocks.AIR && BlockStateValues.isBlockAttached(state, adjacentBlockState) && BlockStateValues.canPistonMoveBlock(adjacentBlockState, false)) { // If it is another slime/honey block we need to check its adjacent blocks - if (BlockStateValues.isBlockSticky(adjacentBlockId)) { + if (BlockStateValues.isBlockSticky(adjacentBlockState)) { blocksToCheck.add(adjacentPos); } else { - attachedBlocks.put(adjacentPos, adjacentBlockId); + attachedBlocks.put(adjacentPos, adjacentBlockState); blocksChecked.add(adjacentPos); blocksToCheck.add(adjacentPos.add(movement)); } @@ -293,7 +294,7 @@ public class PistonBlockEntity { } // Check next block in line blocksToCheck.add(blockPos.add(movement)); - } else if (!BlockStateValues.canPistonDestroyBlock(blockId)) { + } else if (!BlockStateValues.canPistonDestroyBlock(state)) { // Block can't be moved or destroyed, so it blocks all block movement moveBlocks = false; break; @@ -350,24 +351,24 @@ public class PistonBlockEntity { playerBoundingBox.setSizeZ(playerBoundingBox.getSizeZ() - shrink.getZ()); // Resolve collision with the piston head - int pistonHeadId = BlockStateValues.getPistonHead(orientation); + BlockState pistonHeadId = BlockState.of(BlockStateValues.getPistonHead(orientation)); pushPlayerBlock(pistonHeadId, getPistonHeadPos().toDouble(), blockMovement, playerBoundingBox); // Resolve collision with any attached moving blocks, but skip slime blocks // This prevents players from being launched by slime blocks covered by other blocks - for (Object2IntMap.Entry entry : attachedBlocks.object2IntEntrySet()) { - int blockId = entry.getIntValue(); - if (blockId != BlockStateValues.JAVA_SLIME_BLOCK_ID) { + for (Map.Entry entry : Object2ObjectMaps.fastIterable(attachedBlocks)) { + BlockState state = entry.getValue(); + if (!state.is(Blocks.SLIME_BLOCK)) { Vector3d blockPos = entry.getKey().toDouble(); - pushPlayerBlock(blockId, blockPos, blockMovement, playerBoundingBox); + pushPlayerBlock(state, blockPos, blockMovement, playerBoundingBox); } } // Resolve collision with slime blocks - for (Object2IntMap.Entry entry : attachedBlocks.object2IntEntrySet()) { - int blockId = entry.getIntValue(); - if (blockId == BlockStateValues.JAVA_SLIME_BLOCK_ID) { + for (Map.Entry entry : Object2ObjectMaps.fastIterable(attachedBlocks)) { + BlockState state = entry.getValue(); + if (state.is(Blocks.SLIME_BLOCK)) { Vector3d blockPos = entry.getKey().toDouble(); - pushPlayerBlock(blockId, blockPos, blockMovement, playerBoundingBox); + pushPlayerBlock(state, blockPos, blockMovement, playerBoundingBox); } } @@ -463,7 +464,7 @@ public class PistonBlockEntity { return maxIntersection; } - private void pushPlayerBlock(int javaId, Vector3d startingPos, double blockMovement, BoundingBox playerBoundingBox) { + private void pushPlayerBlock(BlockState state, Vector3d startingPos, double blockMovement, BoundingBox playerBoundingBox) { PistonCache pistonCache = session.getPistonCache(); Vector3d movement = getMovement().toDouble(); // Check if the player collides with the movingBlock block entity @@ -471,14 +472,14 @@ public class PistonBlockEntity { if (SOLID_BOUNDING_BOX.checkIntersection(finalBlockPos, playerBoundingBox)) { pistonCache.setPlayerCollided(true); - if (javaId == BlockStateValues.JAVA_SLIME_BLOCK_ID) { + if (state.is(Blocks.SLIME_BLOCK)) { pistonCache.setPlayerSlimeCollision(true); applySlimeBlockMotion(finalBlockPos, Vector3d.from(playerBoundingBox.getMiddleX(), playerBoundingBox.getMiddleY(), playerBoundingBox.getMiddleZ())); } } Vector3d blockPos = startingPos.add(movement.mul(blockMovement)); - if (javaId == BlockStateValues.JAVA_HONEY_BLOCK_ID && isPlayerAttached(blockPos, playerBoundingBox)) { + if (state.is(Blocks.HONEY_BLOCK) && isPlayerAttached(blockPos, playerBoundingBox)) { pistonCache.setPlayerCollided(true); pistonCache.setPlayerAttachedToHoney(true); @@ -486,7 +487,7 @@ public class PistonBlockEntity { pistonCache.displacePlayer(movement.mul(delta)); } else { // Move the player out of collision - BlockCollision blockCollision = BlockRegistries.COLLISIONS.get(javaId); + BlockCollision blockCollision = BlockRegistries.COLLISIONS.get(state.javaId()); if (blockCollision != null) { Vector3d extend = movement.mul(Math.min(1 - blockMovement, 0.5)); Direction movementDirection = orientation; @@ -499,7 +500,7 @@ public class PistonBlockEntity { pistonCache.setPlayerCollided(true); pistonCache.displacePlayer(movement.mul(intersection + 0.01d)); - if (javaId == BlockStateValues.JAVA_SLIME_BLOCK_ID) { + if (state.is(Blocks.SLIME_BLOCK)) { pistonCache.setPlayerSlimeCollision(true); applySlimeBlockMotion(blockPos, Vector3d.from(playerBoundingBox.getMiddleX(), playerBoundingBox.getMiddleY(), playerBoundingBox.getMiddleZ())); } @@ -509,7 +510,7 @@ public class PistonBlockEntity { } private BlockCollision getCollision(Vector3i blockPos) { - return BlockUtils.getCollision(getAttachedBlockId(blockPos)); + return BlockUtils.getCollision(getAttachedBlockId(blockPos).javaId()); } /** @@ -533,7 +534,7 @@ public class PistonBlockEntity { double y = blockPos.getY() + movementVec.getY() * movementProgress; double z = blockPos.getZ() + movementVec.getZ() * movementProgress; double adjustedMovement = blockCollision.computeCollisionOffset(x, y, z, boundingBox, axis, movement); - if (getAttachedBlockId(blockPos) == BlockStateValues.JAVA_SLIME_BLOCK_ID && adjustedMovement != movement) { + if (getAttachedBlockId(blockPos).is(Blocks.SLIME_BLOCK) && adjustedMovement != movement) { session.getPistonCache().setPlayerSlimeCollision(true); } return adjustedMovement; @@ -557,11 +558,11 @@ public class PistonBlockEntity { return false; } - private int getAttachedBlockId(Vector3i blockPos) { + private BlockState getAttachedBlockId(Vector3i blockPos) { if (blockPos.equals(getPistonHeadPos())) { - return BlockStateValues.getPistonHead(orientation); + return BlockState.of(BlockStateValues.getPistonHead(orientation)); } else { - return attachedBlocks.getOrDefault(blockPos, Block.JAVA_AIR_ID); + return attachedBlocks.getOrDefault(blockPos, BlockState.of(Block.JAVA_AIR_ID)); //FIXME } } @@ -582,12 +583,12 @@ public class PistonBlockEntity { playerBoundingBox.setSizeX(playerBoundingBox.getSizeX() + 0.5); playerBoundingBox.setSizeZ(playerBoundingBox.getSizeZ() + 0.5); } - attachedBlocks.forEach((blockPos, javaId) -> { + attachedBlocks.forEach((blockPos, state) -> { Vector3i newPos = blockPos.add(movement); if (SOLID_BOUNDING_BOX.checkIntersection(blockPos.toDouble(), playerBoundingBox) || SOLID_BOUNDING_BOX.checkIntersection(newPos.toDouble(), playerBoundingBox)) { session.getPistonCache().setPlayerCollided(true); - if (javaId == BlockStateValues.JAVA_SLIME_BLOCK_ID) { + if (state.is(Blocks.SLIME_BLOCK)) { session.getPistonCache().setPlayerSlimeCollision(true); } // Don't place moving blocks that collide with the player @@ -603,7 +604,7 @@ public class PistonBlockEntity { updateBlockPacket.setDataLayer(0); session.sendUpstreamPacket(updateBlockPacket); // Update moving block with correct details - BlockEntityUtils.updateBlockEntity(session, buildMovingBlockTag(newPos, javaId, position), newPos); + BlockEntityUtils.updateBlockEntity(session, buildMovingBlockTag(newPos, state, position), newPos); }); } @@ -773,13 +774,13 @@ public class PistonBlockEntity { * Create a moving block tag of a block that will be moved by a piston * * @param position The ending position of the block (The location of the movingBlock block entity) - * @param javaId The Java Id of the block that is moving + * @param state The Java BlockState of the block that is moving * @param pistonPosition The position for the base of the piston that's moving the block * @return A moving block data tag */ - private NbtMap buildMovingBlockTag(Vector3i position, int javaId, Vector3i pistonPosition) { + private NbtMap buildMovingBlockTag(Vector3i position, BlockState state, Vector3i pistonPosition) { // Get Bedrock block state data - NbtMap movingBlock = session.getBlockMappings().getBedrockBlock(javaId).getState(); + NbtMap movingBlock = session.getBlockMappings().getBedrockBlock(state).getState(); NbtMapBuilder builder = NbtMap.builder() .putString("id", "MovingBlock") .putBoolean("expanding", action == PistonValueType.PUSHING) @@ -791,8 +792,8 @@ public class PistonBlockEntity { .putInt("x", position.getX()) .putInt("y", position.getY()) .putInt("z", position.getZ()); - if (PistonBlockEntityTranslator.isBlock(javaId)) { - builder.putCompound("movingEntity", PistonBlockEntityTranslator.getTag(javaId, position)); + if (state.block() instanceof PistonBlock piston) { + builder.putCompound("movingEntity", piston.createTag(session, position, state)); } return builder.build(); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java index 9cb3fb455..507d67ba5 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java @@ -25,13 +25,12 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import org.geysermc.geyser.level.block.type.Block; -import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.packet.BlockPickRequestPacket; import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.type.ItemFrameEntity; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.type.BlockMapping; import org.geysermc.geyser.registry.type.ItemMapping; @@ -39,6 +38,7 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.InventoryUtils; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; @Translator(packet = BlockPickRequestPacket.class) public class BedrockBlockPickRequestTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEventTranslator.java index 36f1d3d65..b7201762f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEventTranslator.java @@ -25,23 +25,25 @@ package org.geysermc.geyser.translator.protocol.java.level; -import org.geysermc.geyser.level.block.type.Block; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.*; -import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundBlockEventPacket; +import it.unimi.dsi.fastutil.objects.Object2ObjectMaps; import org.cloudburstmc.math.vector.Vector3i; -import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.packet.BlockEntityDataPacket; import org.cloudburstmc.protocol.bedrock.packet.BlockEventPacket; -import it.unimi.dsi.fastutil.objects.Object2IntMaps; import org.geysermc.geyser.api.util.PlatformType; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.level.block.type.Block; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.level.physics.Direction; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.PistonCache; +import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator; import org.geysermc.geyser.translator.level.block.entity.PistonBlockEntity; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.*; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundBlockEventPacket; @Translator(packet = ClientboundBlockEventPacket.class) public class JavaBlockEventTranslator extends PacketTranslator { @@ -63,7 +65,7 @@ public class JavaBlockEventTranslator extends PacketTranslator { - blockEventPacket.setEventData(BlockStateValues.getNoteblockPitch(blockState)); + blockEventPacket.setEventData(BlockState.of(blockState).getValue(Properties.NOTE)); session.sendUpstreamPacket(blockEventPacket); }); } else if (value instanceof PistonValue pistonValue) { @@ -90,7 +92,7 @@ public class JavaBlockEventTranslator extends PacketTranslator new PistonBlockEntity(session, pos, direction, true, true)); if (blockEntity.getAction() != action) { - blockEntity.setAction(action, Object2IntMaps.emptyMap()); + blockEntity.setAction(action, Object2ObjectMaps.emptyMap()); } } } else { @@ -110,11 +112,7 @@ public class JavaBlockEventTranslator extends PacketTranslator 0; case WEST -> 1; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java index e54fe5896..bd7096d2b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java @@ -41,7 +41,6 @@ import org.cloudburstmc.protocol.bedrock.packet.LevelChunkPacket; import org.geysermc.erosion.util.LecternUtils; import org.geysermc.geyser.entity.type.ItemFrameEntity; import org.geysermc.geyser.level.BedrockDimension; -import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.level.block.type.BlockState; @@ -53,7 +52,7 @@ import org.geysermc.geyser.level.chunk.bitarray.SingletonBitArray; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.level.BiomeTranslator; -import org.geysermc.geyser.translator.level.block.entity.BedrockOnlyBlockEntity; +import org.geysermc.geyser.translator.level.block.entity.BedrockChunkWantsBlockEntityTag; import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator; import org.geysermc.geyser.translator.level.block.entity.SkullBlockEntityTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; @@ -193,11 +192,12 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator> 8) & 0xF), (packet.getZ() << 4) + ((yzx >> 4) & 0xF)), - javaId + state )); } } @@ -253,7 +253,9 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator> 8) & 0xF), (packet.getZ() << 4) + ((yzx >> 4) & 0xF)), - javaPalette.idToState(paletteId) + state )); } } diff --git a/core/src/main/java/org/geysermc/geyser/util/BlockEntityUtils.java b/core/src/main/java/org/geysermc/geyser/util/BlockEntityUtils.java index ec7f45c8d..1462378e9 100644 --- a/core/src/main/java/org/geysermc/geyser/util/BlockEntityUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/BlockEntityUtils.java @@ -31,25 +31,13 @@ import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.protocol.bedrock.packet.BlockEntityDataPacket; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.translator.level.block.entity.BedrockOnlyBlockEntity; import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator; -import org.geysermc.geyser.translator.level.block.entity.FlowerPotBlockEntityTranslator; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; -import java.util.List; import java.util.Locale; import java.util.Map; public class BlockEntityUtils { - /** - * A list of all block entities that require the Java block state in order to fill out their block entity information. - * This list will be smaller with cache sections on as we don't need to double-cache data - */ - public static final List BEDROCK_ONLY_BLOCK_ENTITIES = List.of( - (BedrockOnlyBlockEntity) Registries.BLOCK_ENTITIES.get().get(BlockEntityType.CHEST), - new FlowerPotBlockEntityTranslator() - ); - /** * Contains a list of irregular block entity name translations that can't be fit into the regex */ diff --git a/core/src/main/java/org/geysermc/geyser/util/ChunkUtils.java b/core/src/main/java/org/geysermc/geyser/util/ChunkUtils.java index a1e956ace..5504d01a8 100644 --- a/core/src/main/java/org/geysermc/geyser/util/ChunkUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/ChunkUtils.java @@ -33,24 +33,19 @@ import lombok.experimental.UtilityClass; import org.cloudburstmc.math.GenericMath; import org.cloudburstmc.math.vector.Vector2i; import org.cloudburstmc.math.vector.Vector3i; -import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.packet.LevelChunkPacket; import org.cloudburstmc.protocol.bedrock.packet.NetworkChunkPublisherUpdatePacket; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; import org.geysermc.geyser.entity.type.ItemFrameEntity; import org.geysermc.geyser.level.BedrockDimension; import org.geysermc.geyser.level.JavaDimension; -import org.geysermc.geyser.level.block.BlockStateValues; -import org.geysermc.geyser.level.block.type.Block; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.level.chunk.BlockStorage; import org.geysermc.geyser.level.chunk.GeyserChunkSection; import org.geysermc.geyser.level.chunk.bitarray.SingletonBitArray; -import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.session.cache.SkullCache; import org.geysermc.geyser.text.GeyserLocale; -import org.geysermc.geyser.translator.level.block.entity.BedrockOnlyBlockEntity; @UtilityClass public class ChunkUtils { @@ -119,18 +114,30 @@ public class ChunkUtils { * @param position the position of the block */ public static void updateBlock(GeyserSession session, int blockState, Vector3i position) { - updateBlockClientSide(session, blockState, position); + updateBlockClientSide(session, BlockState.of(blockState), position); session.getChunkCache().updateBlock(position.getX(), position.getY(), position.getZ(), blockState); } + /** + * Sends a block update to the Bedrock client. If the platform does not have an integrated world manager, this also + * adds that block to the cache. + * @param session the Bedrock session to send/register the block to + * @param blockState the Java block state of the block + * @param position the position of the block + */ + public static void updateBlock(GeyserSession session, BlockState blockState, Vector3i position) { + updateBlockClientSide(session, blockState, position); + session.getChunkCache().updateBlock(position.getX(), position.getY(), position.getZ(), blockState.javaId()); + } + /** * Updates a block, but client-side only. */ - public static void updateBlockClientSide(GeyserSession session, int blockState, Vector3i position) { + public static void updateBlockClientSide(GeyserSession session, BlockState blockState, Vector3i position) { // Checks for item frames so they aren't tripped up and removed ItemFrameEntity itemFrameEntity = ItemFrameEntity.getItemFrameEntity(session, position); if (itemFrameEntity != null) { - if (blockState == Block.JAVA_AIR_ID) { // Item frame is still present and no block overrides that; refresh it + if (blockState.is(Blocks.AIR)) { // Item frame is still present and no block overrides that; refresh it itemFrameEntity.updateBlock(true); // Still update the chunk cache with the new block if updateBlock is called return; @@ -138,91 +145,7 @@ public class ChunkUtils { // Otherwise, let's still store our reference to the item frame, but let the new block take precedence for now } - BlockDefinition definition = session.getBlockMappings().getBedrockBlock(blockState); - - int skullVariant = BlockStateValues.getSkullVariant(blockState); - if (skullVariant == -1) { - // Skull is gone - session.getSkullCache().removeSkull(position); - } else if (skullVariant == 3) { - // The changed block was a player skull so check if a custom block was defined for this skull - SkullCache.Skull skull = session.getSkullCache().updateSkull(position, blockState); - if (skull != null && skull.getBlockDefinition() != null) { - definition = skull.getBlockDefinition(); - } - } - - // Prevent moving_piston from being placed - // It's used for extending piston heads, but it isn't needed on Bedrock and causes pistons to flicker - if (!BlockStateValues.isMovingPiston(blockState)) { - UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); - updateBlockPacket.setDataLayer(0); - updateBlockPacket.setBlockPosition(position); - updateBlockPacket.setDefinition(definition); - updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS); - updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK); - session.sendUpstreamPacket(updateBlockPacket); - - UpdateBlockPacket waterPacket = new UpdateBlockPacket(); - waterPacket.setDataLayer(1); - waterPacket.setBlockPosition(position); - if (BlockRegistries.WATERLOGGED.get().get(blockState)) { - waterPacket.setDefinition(session.getBlockMappings().getBedrockWater()); - } else { - waterPacket.setDefinition(session.getBlockMappings().getBedrockAir()); - } - session.sendUpstreamPacket(waterPacket); - } - - // Extended collision boxes for custom blocks - if (!session.getBlockMappings().getExtendedCollisionBoxes().isEmpty()) { - int aboveBlock = session.getGeyser().getWorldManager().getBlockAt(session, position.getX(), position.getY() + 1, position.getZ()); - BlockDefinition aboveBedrockExtendedCollisionDefinition = session.getBlockMappings().getExtendedCollisionBoxes().get(blockState); - int belowBlock = session.getGeyser().getWorldManager().getBlockAt(session, position.getX(), position.getY() - 1, position.getZ()); - BlockDefinition belowBedrockExtendedCollisionDefinition = session.getBlockMappings().getExtendedCollisionBoxes().get(belowBlock); - if (belowBedrockExtendedCollisionDefinition != null && blockState == Block.JAVA_AIR_ID) { - UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); - updateBlockPacket.setDataLayer(0); - updateBlockPacket.setBlockPosition(position); - updateBlockPacket.setDefinition(belowBedrockExtendedCollisionDefinition); - updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK); - session.sendUpstreamPacket(updateBlockPacket); - } else if (aboveBedrockExtendedCollisionDefinition != null && aboveBlock == Block.JAVA_AIR_ID) { - UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); - updateBlockPacket.setDataLayer(0); - updateBlockPacket.setBlockPosition(position.add(0, 1, 0)); - updateBlockPacket.setDefinition(aboveBedrockExtendedCollisionDefinition); - updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK); - session.sendUpstreamPacket(updateBlockPacket); - } else if (aboveBlock == Block.JAVA_AIR_ID) { - UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); - updateBlockPacket.setDataLayer(0); - updateBlockPacket.setBlockPosition(position.add(0, 1, 0)); - updateBlockPacket.setDefinition(session.getBlockMappings().getBedrockAir()); - updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK); - session.sendUpstreamPacket(updateBlockPacket); - } - } - - BlockStateValues.getLecternBookStates().handleBlockChange(session, blockState, position); - - // Iterates through all Bedrock-only block entity translators and determines if a manual block entity packet - // needs to be sent - for (BedrockOnlyBlockEntity bedrockOnlyBlockEntity : BlockEntityUtils.BEDROCK_ONLY_BLOCK_ENTITIES) { - if (bedrockOnlyBlockEntity.isBlock(blockState)) { - // Flower pots are block entities only in Bedrock and are not updated anywhere else like note blocks - bedrockOnlyBlockEntity.updateBlock(session, BlockState.of(blockState), position); //TODO blockState - break; //No block will be a part of two classes - } - } - - if (BlockStateValues.isUpperDoor(blockState)) { - // Update the lower door block as Bedrock client doesn't like door to be closed from the top - // See https://github.com/GeyserMC/Geyser/issues/4358 - Vector3i belowDoorPosition = position.sub(0, 1, 0); - int belowDoorBlockState = session.getGeyser().getWorldManager().getBlockAt(session, belowDoorPosition.getX(), belowDoorPosition.getY(), belowDoorPosition.getZ()); - updateBlock(session, belowDoorBlockState, belowDoorPosition); - } + blockState.block().updateBlock(session, blockState, position); } public static void sendEmptyChunk(GeyserSession session, int chunkX, int chunkZ, boolean forceUpdate) { From a439f3e3d7a6a9e16f3e6dea9df4dfb0df37b7d4 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Fri, 17 May 2024 21:14:59 -0400 Subject: [PATCH 173/272] Fix compilation for Spigot --- .../spigot/world/GeyserPistonListener.java | 17 ++++++------ .../erosion/GeyserboundPacketHandlerImpl.java | 4 +-- .../geyser/level/block/type/BlockState.java | 10 +++++++ .../block/entity/BlockEntityTranslator.java | 5 ++++ .../level/block/entity/PistonBlockEntity.java | 27 ++++++------------- 5 files changed, 34 insertions(+), 29 deletions(-) diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserPistonListener.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserPistonListener.java index 61c0d5fe8..2a6dc7a81 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserPistonListener.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserPistonListener.java @@ -25,10 +25,8 @@ package org.geysermc.geyser.platform.spigot.world; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.PistonValueType; -import org.cloudburstmc.math.vector.Vector3i; -import it.unimi.dsi.fastutil.objects.Object2IntArrayMap; -import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectMap; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; @@ -40,13 +38,16 @@ import org.bukkit.event.Listener; import org.bukkit.event.block.BlockPistonEvent; import org.bukkit.event.block.BlockPistonExtendEvent; import org.bukkit.event.block.BlockPistonRetractEvent; +import org.cloudburstmc.math.vector.Vector3i; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.level.physics.Direction; import org.geysermc.geyser.platform.spigot.world.manager.GeyserSpigotWorldManager; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.PistonCache; import org.geysermc.geyser.translator.level.block.entity.PistonBlockEntity; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.PistonValueType; import java.util.List; import java.util.Map; @@ -85,7 +86,7 @@ public class GeyserPistonListener implements Listener { PistonValueType type = isExtend ? PistonValueType.PUSHING : PistonValueType.PULLING; boolean sticky = event.isSticky(); - Object2IntMap attachedBlocks = new Object2IntArrayMap<>(); + Object2ObjectMap attachedBlocks = new Object2ObjectArrayMap<>(); boolean blocksFilled = false; for (Map.Entry entry : geyser.getSessionManager().getSessions().entrySet()) { @@ -108,10 +109,10 @@ public class GeyserPistonListener implements Listener { List blocks = isExtend ? ((BlockPistonExtendEvent) event).getBlocks() : ((BlockPistonRetractEvent) event).getBlocks(); for (Block block : blocks) { Location attachedLocation = block.getLocation(); - int blockId = worldManager.getBlockNetworkId(block); + BlockState state = BlockState.of(worldManager.getBlockNetworkId(block)); // Ignore blocks that will be destroyed - if (BlockStateValues.canPistonMoveBlock(blockId, isExtend)) { - attachedBlocks.put(getVector(attachedLocation), blockId); + if (BlockStateValues.canPistonMoveBlock(state, isExtend)) { + attachedBlocks.put(getVector(attachedLocation), state); } } blocksFilled = true; diff --git a/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java b/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java index 6e22fd430..62ecaa1e9 100644 --- a/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java +++ b/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java @@ -30,8 +30,8 @@ import it.unimi.dsi.fastutil.Pair; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; import it.unimi.dsi.fastutil.objects.Object2ObjectMap; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import lombok.Getter; import lombok.Setter; import org.cloudburstmc.math.vector.Vector3i; @@ -157,7 +157,7 @@ public final class GeyserboundPacketHandlerImpl extends AbstractGeyserboundPacke .stream() .map(entry -> Pair.of(entry.getKey(), BlockState.of(entry.getIntValue()))) .filter(pair -> BlockStateValues.canPistonMoveBlock(pair.value(), isExtend)); - Object2ObjectMap attachedBlocks = new Object2ObjectOpenHashMap<>(); + Object2ObjectMap attachedBlocks = new Object2ObjectArrayMap<>(); stream.forEach(pair -> attachedBlocks.put(pair.key(), pair.value())); session.executeInEventLoop(() -> { diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java b/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java index 23e89d99f..de4806efa 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java @@ -62,6 +62,16 @@ public final class BlockState { return this.block == block; } + private String paramsToString() { + StringBuilder builder = new StringBuilder(); + var it = this.states.entrySet().iterator(); + while (it.hasNext()) { + var entry = it.next(); + builder.append(entry.getKey()).append("=").append(entry.getValue()); + } + return builder.toString(); + } + public static BlockState of(int javaId) { return BlockRegistries.BLOCK_STATES.get(javaId); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java index 5def51e01..ae44dd134 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.translator.level.block.entity; import org.checkerframework.checker.nullness.qual.Nullable; +import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.block.type.BlockState; @@ -56,6 +57,10 @@ public abstract class BlockEntityTranslator { return getConstantBedrockTag(BlockEntityUtils.getBedrockBlockEntityId(type), x, y, z); } + public static NbtMapBuilder getConstantBedrockTag(String bedrockId, Vector3i position) { + return getConstantBedrockTag(bedrockId, position.getX(), position.getY(), position.getZ()); + } + public static NbtMapBuilder getConstantBedrockTag(String bedrockId, int x, int y, int z) { return NbtMap.builder() .putInt("x", x) diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java index abe3a197e..14282228b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; +import it.unimi.dsi.fastutil.ints.IntArrays; import it.unimi.dsi.fastutil.objects.*; import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.level.block.type.Block; @@ -74,7 +75,7 @@ public class PistonBlockEntity { /** * A flattened array of the positions of attached blocks, stored in XYZ order. */ - private int[] flattenedAttachedBlocks = new int[0]; + private int[] flattenedAttachedBlocks = IntArrays.EMPTY_ARRAY; private boolean placedFinalBlocks = true; @@ -732,18 +733,14 @@ public class PistonBlockEntity { * @return A piston data tag */ private NbtMap buildPistonTag() { - NbtMapBuilder builder = NbtMap.builder() - .putString("id", "PistonArm") + NbtMapBuilder builder = BlockEntityTranslator.getConstantBedrockTag("PistonArm", position) .putIntArray("AttachedBlocks", flattenedAttachedBlocks) .putFloat("Progress", progress) .putFloat("LastProgress", lastProgress) .putByte("NewState", getState()) .putByte("State", getState()) .putBoolean("Sticky", sticky) - .putBoolean("isMovable", false) - .putInt("x", position.getX()) - .putInt("y", position.getY()) - .putInt("z", position.getZ()); + .putBoolean("isMovable", false); return builder.build(); } @@ -756,17 +753,13 @@ public class PistonBlockEntity { * @return A piston data tag for a fully extended/retracted piston */ public static NbtMap buildStaticPistonTag(Vector3i position, boolean extended, boolean sticky) { - NbtMapBuilder builder = NbtMap.builder() - .putString("id", "PistonArm") + NbtMapBuilder builder = BlockEntityTranslator.getConstantBedrockTag("PistonArm", position) .putFloat("Progress", extended ? 1.0f : 0.0f) .putFloat("LastProgress", extended ? 1.0f : 0.0f) .putByte("NewState", (byte) (extended ? 2 : 0)) .putByte("State", (byte) (extended ? 2 : 0)) .putBoolean("Sticky", sticky) - .putBoolean("isMovable", false) - .putInt("x", position.getX()) - .putInt("y", position.getY()) - .putInt("z", position.getZ()); + .putBoolean("isMovable", false); return builder.build(); } @@ -781,17 +774,13 @@ public class PistonBlockEntity { private NbtMap buildMovingBlockTag(Vector3i position, BlockState state, Vector3i pistonPosition) { // Get Bedrock block state data NbtMap movingBlock = session.getBlockMappings().getBedrockBlock(state).getState(); - NbtMapBuilder builder = NbtMap.builder() - .putString("id", "MovingBlock") + NbtMapBuilder builder = BlockEntityTranslator.getConstantBedrockTag("MovingBlock", position) .putBoolean("expanding", action == PistonValueType.PUSHING) .putCompound("movingBlock", movingBlock) .putBoolean("isMovable", true) .putInt("pistonPosX", pistonPosition.getX()) .putInt("pistonPosY", pistonPosition.getY()) - .putInt("pistonPosZ", pistonPosition.getZ()) - .putInt("x", position.getX()) - .putInt("y", position.getY()) - .putInt("z", position.getZ()); + .putInt("pistonPosZ", pistonPosition.getZ()); if (state.block() instanceof PistonBlock piston) { builder.putCompound("movingEntity", piston.createTag(session, position, state)); } From 8b7703154ef7b7df82e42cd7ce62e0211b14b3d6 Mon Sep 17 00:00:00 2001 From: chris Date: Sat, 18 May 2024 21:13:00 +0200 Subject: [PATCH 174/272] Resolve issue when trying to transfer a Geyser player (#4673) --- .../main/java/org/geysermc/geyser/session/GeyserSession.java | 3 +++ gradle/libs.versions.toml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 617087f71..2b7ec0a97 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -896,6 +896,9 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { this.downstream.getSession().setFlag(BuiltinFlags.ATTEMPT_SRV_RESOLVE, resolveSrv); } + // Disable automatic creation of a new TcpClientSession when transferring - we don't use that functionality. + this.downstream.getSession().setFlag(MinecraftConstants.FOLLOW_TRANSFERS, false); + if (geyser.getConfig().getRemote().isUseProxyProtocol()) { downstream.setFlag(BuiltinFlags.ENABLE_CLIENT_PROXY_PROTOCOL, true); downstream.setFlag(BuiltinFlags.CLIENT_PROXIED_ADDRESS, upstream.getAddress()); diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 65a5e3a52..dee170705 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "e5b0bcc" -mcprotocollib = "42ea4a4" # Revert from jitpack after release +mcprotocollib = "a1b559d" # Revert from jitpack after release adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From 6c904b2378e3e34e215c729001d97c9155c537c5 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 18 May 2024 16:37:06 -0400 Subject: [PATCH 175/272] It's almost done. --- .../java/org/geysermc/geyser/GeyserImpl.java | 8 +- .../entity/type/FurnaceMinecartEntity.java | 8 +- .../entity/type/SpawnerMinecartEntity.java | 4 +- .../erosion/GeyserboundPacketHandlerImpl.java | 2 +- .../holder/BlockInventoryHolder.java | 22 +- .../java/org/geysermc/geyser/item/Items.java | 1851 +++++++++-------- .../geysermc/geyser/item/type/BannerItem.java | 5 +- .../geysermc/geyser/item/type/BlockItem.java | 23 +- .../geyser/item/type/DecoratedPotItem.java | 5 +- .../org/geysermc/geyser/item/type/Item.java | 35 +- .../geyser/item/type/PlayerHeadItem.java | 7 +- .../geyser/item/type/ShulkerBoxItem.java | 5 +- .../geyser/level/block/BlockStateValues.java | 49 - .../geysermc/geyser/level/block/Blocks.java | 14 +- .../geyser/level/block/property/Property.java | 4 + .../geyser/level/block/type/Block.java | 81 +- .../geyser/level/block/type/BlockState.java | 17 +- .../level/block/type/FlowerPotBlock.java | 2 +- .../geyser/level/block/type/FurnaceBlock.java | 56 + .../geyser/level/block/type/HoneyBlock.java | 45 + .../geyser/level/block/type/SpawnerBlock.java | 45 + .../geyser/level/block/type/WaterBlock.java | 41 + .../geyser/registry/BlockRegistries.java | 1 + .../geysermc/geyser/registry/Registries.java | 1 + .../loader/CollisionRegistryLoader.java | 2 +- .../populator/BlockRegistryPopulator.java | 65 +- .../geyser/registry/type/BlockMapping.java | 35 - .../geyser/session/GeyserSession.java | 3 +- .../AbstractBlockInventoryTranslator.java | 5 +- .../inventory/AnvilInventoryTranslator.java | 3 +- .../Generic3X3InventoryTranslator.java | 3 +- .../inventory/ShulkerInventoryTranslator.java | 4 +- .../chest/SingleChestInventoryTranslator.java | 4 +- .../level/block/entity/PistonBlockEntity.java | 7 +- .../BedrockBlockPickRequestTranslator.java | 31 +- ...BedrockInventoryTransactionTranslator.java | 6 +- .../java/level/JavaBlockUpdateTranslator.java | 10 +- .../JavaLevelChunkWithLightTranslator.java | 5 +- .../geysermc/geyser/util/InventoryUtils.java | 32 +- .../geysermc/geyser/util/StatisticsUtils.java | 2 +- 40 files changed, 1359 insertions(+), 1189 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/type/FurnaceBlock.java create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/type/HoneyBlock.java create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/type/SpawnerBlock.java create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/type/WaterBlock.java diff --git a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java index e7237e8bf..7be1fe15b 100644 --- a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java +++ b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java @@ -258,10 +258,10 @@ public class GeyserImpl implements GeyserApi { VersionCheckUtils.checkForOutdatedJava(logger); for (int i = 0; i < BlockRegistries.JAVA_BLOCKS.get().length; i++) { - String cleanIdentifier = BlockRegistries.JAVA_BLOCKS.get(i).getCleanJavaIdentifier(); - String newIdentifier = BlockRegistries.BLOCK_STATES.get(i).block().javaIdentifier(); - if (!cleanIdentifier.equals(newIdentifier)) { - System.out.println("Check block " + BlockRegistries.BLOCK_STATES.get(i).block().javaIdentifier()); + String oldIdentifier = BlockRegistries.JAVA_BLOCKS.get(i).getJavaIdentifier(); + String newIdentifier = BlockRegistries.BLOCK_STATES.get(i).toString(); + if (!oldIdentifier.equals(newIdentifier)) { + System.out.println("Check block " + oldIdentifier + " " + newIdentifier); break; } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/FurnaceMinecartEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/FurnaceMinecartEntity.java index ef584c4fd..0fc5627ed 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/FurnaceMinecartEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/FurnaceMinecartEntity.java @@ -25,14 +25,14 @@ package org.geysermc.geyser.entity.type; -import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.type.FurnaceBlock; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; @@ -51,7 +51,7 @@ public class FurnaceMinecartEntity extends DefaultBlockMinecartEntity { @Override public void updateDefaultBlockMetadata() { - dirtyMetadata.put(EntityDataTypes.DISPLAY_BLOCK_STATE, session.getBlockMappings().getBedrockBlock(hasFuel ? BlockStateValues.JAVA_FURNACE_LIT_ID : BlockStateValues.JAVA_FURNACE_ID)); + dirtyMetadata.put(EntityDataTypes.DISPLAY_BLOCK_STATE, session.getBlockMappings().getBedrockBlock(FurnaceBlock.state(hasFuel))); dirtyMetadata.put(EntityDataTypes.DISPLAY_OFFSET, 6); } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/SpawnerMinecartEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/SpawnerMinecartEntity.java index 49cfc0081..65dfb800b 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/SpawnerMinecartEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/SpawnerMinecartEntity.java @@ -28,7 +28,7 @@ package org.geysermc.geyser.entity.type; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.type.SpawnerBlock; import org.geysermc.geyser.session.GeyserSession; import java.util.UUID; @@ -41,7 +41,7 @@ public class SpawnerMinecartEntity extends DefaultBlockMinecartEntity { @Override public void updateDefaultBlockMetadata() { - dirtyMetadata.put(EntityDataTypes.DISPLAY_BLOCK_STATE, session.getBlockMappings().getBedrockBlock(BlockStateValues.JAVA_SPAWNER_ID)); + dirtyMetadata.put(EntityDataTypes.DISPLAY_BLOCK_STATE, session.getBlockMappings().getBedrockBlock(SpawnerBlock.state())); dirtyMetadata.put(EntityDataTypes.DISPLAY_OFFSET, 6); } } diff --git a/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java b/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java index 62ecaa1e9..9894a4ba2 100644 --- a/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java +++ b/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java @@ -136,7 +136,7 @@ public final class GeyserboundPacketHandlerImpl extends AbstractGeyserboundPacke placeBlockSoundPacket.setIdentifier(":"); session.sendUpstreamPacket(placeBlockSoundPacket); session.setLastBlockPlacePosition(null); - session.setLastBlockPlacedId(null); + session.setLastBlockPlaced(null); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java b/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java index c11505ffb..686fe39ad 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java @@ -36,8 +36,9 @@ import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.Container; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.LecternContainer; +import org.geysermc.geyser.level.block.type.Block; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.registry.BlockRegistries; -import org.geysermc.geyser.registry.type.BlockMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.geyser.util.BlockUtils; @@ -59,12 +60,14 @@ public class BlockInventoryHolder extends InventoryHolder { private final ContainerType containerType; private final Set validBlocks; - public BlockInventoryHolder(String javaBlockIdentifier, ContainerType containerType, String... validBlocks) { + public BlockInventoryHolder(String javaBlockIdentifier, ContainerType containerType, Block... validBlocks) { this.defaultJavaBlockState = BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getInt(javaBlockIdentifier); this.containerType = containerType; if (validBlocks != null) { Set validBlocksTemp = new HashSet<>(validBlocks.length + 1); - Collections.addAll(validBlocksTemp, validBlocks); + for (Block block : validBlocks) { + validBlocksTemp.add(block.javaIdentifier().toString()); + } validBlocksTemp.add(BlockUtils.getCleanIdentifier(javaBlockIdentifier)); this.validBlocks = Set.copyOf(validBlocksTemp); } else { @@ -80,14 +83,15 @@ public class BlockInventoryHolder extends InventoryHolder { if (checkInteractionPosition(session)) { // Then, check to see if the interacted block is valid for this inventory by ensuring the block state identifier is valid // and the bedrock block is vanilla - int javaBlockId = session.getGeyser().getWorldManager().getBlockAt(session, session.getLastInteractionBlockPosition()); - if (!BlockRegistries.CUSTOM_BLOCK_STATE_OVERRIDES.get().containsKey(javaBlockId)) { - String[] javaBlockString = BlockRegistries.JAVA_BLOCKS.getOrDefault(javaBlockId, BlockMapping.DEFAULT).getJavaIdentifier().split("\\["); + BlockState state = session.getGeyser().getWorldManager().blockAt(session, session.getLastInteractionBlockPosition()); + if (!BlockRegistries.CUSTOM_BLOCK_STATE_OVERRIDES.get().containsKey(state.javaId())) { + // TODO TODO TODO + String[] javaBlockString = state.toString().split("\\["); if (isValidBlock(javaBlockString)) { // We can safely use this block inventory.setHolderPosition(session.getLastInteractionBlockPosition()); ((Container) inventory).setUsingRealBlock(true, javaBlockString[0]); - setCustomName(session, session.getLastInteractionBlockPosition(), inventory, javaBlockId); + setCustomName(session, session.getLastInteractionBlockPosition(), inventory, state); return true; } @@ -107,7 +111,7 @@ public class BlockInventoryHolder extends InventoryHolder { session.sendUpstreamPacket(blockPacket); inventory.setHolderPosition(position); - setCustomName(session, position, inventory, defaultJavaBlockState); + setCustomName(session, position, inventory, BlockState.of(defaultJavaBlockState)); return true; } @@ -129,7 +133,7 @@ public class BlockInventoryHolder extends InventoryHolder { return this.validBlocks.contains(javaBlockString[0]); } - protected void setCustomName(GeyserSession session, Vector3i position, Inventory inventory, int javaBlockState) { + protected void setCustomName(GeyserSession session, Vector3i position, Inventory inventory, BlockState javaBlockState) { NbtMap tag = NbtMap.builder() .putInt("x", position.getX()) .putInt("y", position.getY()) diff --git a/core/src/main/java/org/geysermc/geyser/item/Items.java b/core/src/main/java/org/geysermc/geyser/item/Items.java index f13330700..8c271a7bb 100644 --- a/core/src/main/java/org/geysermc/geyser/item/Items.java +++ b/core/src/main/java/org/geysermc/geyser/item/Items.java @@ -27,6 +27,7 @@ package org.geysermc.geyser.item; import org.geysermc.geyser.item.components.ToolTier; import org.geysermc.geyser.item.type.*; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.registry.Registries; import java.util.Collections; @@ -39,770 +40,770 @@ import static org.geysermc.geyser.item.type.Item.builder; @SuppressWarnings("unused") public final class Items { public static final Item AIR = register(new Item("air", builder())); - public static final Item STONE = register(new BlockItem("stone", builder())); - public static final Item GRANITE = register(new BlockItem("granite", builder())); - public static final Item POLISHED_GRANITE = register(new BlockItem("polished_granite", builder())); - public static final Item DIORITE = register(new BlockItem("diorite", builder())); - public static final Item POLISHED_DIORITE = register(new BlockItem("polished_diorite", builder())); - public static final Item ANDESITE = register(new BlockItem("andesite", builder())); - public static final Item POLISHED_ANDESITE = register(new BlockItem("polished_andesite", builder())); - public static final Item DEEPSLATE = register(new BlockItem("deepslate", builder())); - public static final Item COBBLED_DEEPSLATE = register(new BlockItem("cobbled_deepslate", builder())); - public static final Item POLISHED_DEEPSLATE = register(new BlockItem("polished_deepslate", builder())); - public static final Item CALCITE = register(new BlockItem("calcite", builder())); - public static final Item TUFF = register(new BlockItem("tuff", builder())); - public static final Item TUFF_SLAB = register(new BlockItem("tuff_slab", builder())); - public static final Item TUFF_STAIRS = register(new BlockItem("tuff_stairs", builder())); - public static final Item TUFF_WALL = register(new BlockItem("tuff_wall", builder())); - public static final Item CHISELED_TUFF = register(new BlockItem("chiseled_tuff", builder())); - public static final Item POLISHED_TUFF = register(new BlockItem("polished_tuff", builder())); - public static final Item POLISHED_TUFF_SLAB = register(new BlockItem("polished_tuff_slab", builder())); - public static final Item POLISHED_TUFF_STAIRS = register(new BlockItem("polished_tuff_stairs", builder())); - public static final Item POLISHED_TUFF_WALL = register(new BlockItem("polished_tuff_wall", builder())); - public static final Item TUFF_BRICKS = register(new BlockItem("tuff_bricks", builder())); - public static final Item TUFF_BRICK_SLAB = register(new BlockItem("tuff_brick_slab", builder())); - public static final Item TUFF_BRICK_STAIRS = register(new BlockItem("tuff_brick_stairs", builder())); - public static final Item TUFF_BRICK_WALL = register(new BlockItem("tuff_brick_wall", builder())); - public static final Item CHISELED_TUFF_BRICKS = register(new BlockItem("chiseled_tuff_bricks", builder())); - public static final Item DRIPSTONE_BLOCK = register(new BlockItem("dripstone_block", builder())); - public static final Item GRASS_BLOCK = register(new BlockItem("grass_block", builder())); - public static final Item DIRT = register(new BlockItem("dirt", builder())); - public static final Item COARSE_DIRT = register(new BlockItem("coarse_dirt", builder())); - public static final Item PODZOL = register(new BlockItem("podzol", builder())); - public static final Item ROOTED_DIRT = register(new BlockItem("rooted_dirt", builder())); - public static final Item MUD = register(new BlockItem("mud", builder())); - public static final Item CRIMSON_NYLIUM = register(new BlockItem("crimson_nylium", builder())); - public static final Item WARPED_NYLIUM = register(new BlockItem("warped_nylium", builder())); - public static final Item COBBLESTONE = register(new BlockItem("cobblestone", builder())); - public static final Item OAK_PLANKS = register(new BlockItem("oak_planks", builder())); - public static final Item SPRUCE_PLANKS = register(new BlockItem("spruce_planks", builder())); - public static final Item BIRCH_PLANKS = register(new BlockItem("birch_planks", builder())); - public static final Item JUNGLE_PLANKS = register(new BlockItem("jungle_planks", builder())); - public static final Item ACACIA_PLANKS = register(new BlockItem("acacia_planks", builder())); - public static final Item CHERRY_PLANKS = register(new BlockItem("cherry_planks", builder())); - public static final Item DARK_OAK_PLANKS = register(new BlockItem("dark_oak_planks", builder())); - public static final Item MANGROVE_PLANKS = register(new BlockItem("mangrove_planks", builder())); - public static final Item BAMBOO_PLANKS = register(new BlockItem("bamboo_planks", builder())); - public static final Item CRIMSON_PLANKS = register(new BlockItem("crimson_planks", builder())); - public static final Item WARPED_PLANKS = register(new BlockItem("warped_planks", builder())); - public static final Item BAMBOO_MOSAIC = register(new BlockItem("bamboo_mosaic", builder())); - public static final Item OAK_SAPLING = register(new BlockItem("oak_sapling", builder())); - public static final Item SPRUCE_SAPLING = register(new BlockItem("spruce_sapling", builder())); - public static final Item BIRCH_SAPLING = register(new BlockItem("birch_sapling", builder())); - public static final Item JUNGLE_SAPLING = register(new BlockItem("jungle_sapling", builder())); - public static final Item ACACIA_SAPLING = register(new BlockItem("acacia_sapling", builder())); - public static final Item CHERRY_SAPLING = register(new BlockItem("cherry_sapling", builder())); - public static final Item DARK_OAK_SAPLING = register(new BlockItem("dark_oak_sapling", builder())); - public static final Item MANGROVE_PROPAGULE = register(new BlockItem("mangrove_propagule", builder())); - public static final Item BEDROCK = register(new BlockItem("bedrock", builder())); - public static final Item SAND = register(new BlockItem("sand", builder())); - public static final Item SUSPICIOUS_SAND = register(new BlockItem("suspicious_sand", builder())); - public static final Item SUSPICIOUS_GRAVEL = register(new BlockItem("suspicious_gravel", builder())); - public static final Item RED_SAND = register(new BlockItem("red_sand", builder())); - public static final Item GRAVEL = register(new BlockItem("gravel", builder())); - public static final Item COAL_ORE = register(new BlockItem("coal_ore", builder())); - public static final Item DEEPSLATE_COAL_ORE = register(new BlockItem("deepslate_coal_ore", builder())); - public static final Item IRON_ORE = register(new BlockItem("iron_ore", builder())); - public static final Item DEEPSLATE_IRON_ORE = register(new BlockItem("deepslate_iron_ore", builder())); - public static final Item COPPER_ORE = register(new BlockItem("copper_ore", builder())); - public static final Item DEEPSLATE_COPPER_ORE = register(new BlockItem("deepslate_copper_ore", builder())); - public static final Item GOLD_ORE = register(new BlockItem("gold_ore", builder())); - public static final Item DEEPSLATE_GOLD_ORE = register(new BlockItem("deepslate_gold_ore", builder())); - public static final Item REDSTONE_ORE = register(new BlockItem("redstone_ore", builder())); - public static final Item DEEPSLATE_REDSTONE_ORE = register(new BlockItem("deepslate_redstone_ore", builder())); - public static final Item EMERALD_ORE = register(new BlockItem("emerald_ore", builder())); - public static final Item DEEPSLATE_EMERALD_ORE = register(new BlockItem("deepslate_emerald_ore", builder())); - public static final Item LAPIS_ORE = register(new BlockItem("lapis_ore", builder())); - public static final Item DEEPSLATE_LAPIS_ORE = register(new BlockItem("deepslate_lapis_ore", builder())); - public static final Item DIAMOND_ORE = register(new BlockItem("diamond_ore", builder())); - public static final Item DEEPSLATE_DIAMOND_ORE = register(new BlockItem("deepslate_diamond_ore", builder())); - public static final Item NETHER_GOLD_ORE = register(new BlockItem("nether_gold_ore", builder())); - public static final Item NETHER_QUARTZ_ORE = register(new BlockItem("nether_quartz_ore", builder())); - public static final Item ANCIENT_DEBRIS = register(new BlockItem("ancient_debris", builder())); - public static final Item COAL_BLOCK = register(new BlockItem("coal_block", builder())); - public static final Item RAW_IRON_BLOCK = register(new BlockItem("raw_iron_block", builder())); - public static final Item RAW_COPPER_BLOCK = register(new BlockItem("raw_copper_block", builder())); - public static final Item RAW_GOLD_BLOCK = register(new BlockItem("raw_gold_block", builder())); - public static final Item HEAVY_CORE = register(new BlockItem("heavy_core", builder())); - public static final Item AMETHYST_BLOCK = register(new BlockItem("amethyst_block", builder())); - public static final Item BUDDING_AMETHYST = register(new BlockItem("budding_amethyst", builder())); - public static final Item IRON_BLOCK = register(new BlockItem("iron_block", builder())); - public static final Item COPPER_BLOCK = register(new BlockItem("copper_block", builder())); - public static final Item GOLD_BLOCK = register(new BlockItem("gold_block", builder())); - public static final Item DIAMOND_BLOCK = register(new BlockItem("diamond_block", builder())); - public static final Item NETHERITE_BLOCK = register(new BlockItem("netherite_block", builder())); - public static final Item EXPOSED_COPPER = register(new BlockItem("exposed_copper", builder())); - public static final Item WEATHERED_COPPER = register(new BlockItem("weathered_copper", builder())); - public static final Item OXIDIZED_COPPER = register(new BlockItem("oxidized_copper", builder())); - public static final Item CHISELED_COPPER = register(new BlockItem("chiseled_copper", builder())); - public static final Item EXPOSED_CHISELED_COPPER = register(new BlockItem("exposed_chiseled_copper", builder())); - public static final Item WEATHERED_CHISELED_COPPER = register(new BlockItem("weathered_chiseled_copper", builder())); - public static final Item OXIDIZED_CHISELED_COPPER = register(new BlockItem("oxidized_chiseled_copper", builder())); - public static final Item CUT_COPPER = register(new BlockItem("cut_copper", builder())); - public static final Item EXPOSED_CUT_COPPER = register(new BlockItem("exposed_cut_copper", builder())); - public static final Item WEATHERED_CUT_COPPER = register(new BlockItem("weathered_cut_copper", builder())); - public static final Item OXIDIZED_CUT_COPPER = register(new BlockItem("oxidized_cut_copper", builder())); - public static final Item CUT_COPPER_STAIRS = register(new BlockItem("cut_copper_stairs", builder())); - public static final Item EXPOSED_CUT_COPPER_STAIRS = register(new BlockItem("exposed_cut_copper_stairs", builder())); - public static final Item WEATHERED_CUT_COPPER_STAIRS = register(new BlockItem("weathered_cut_copper_stairs", builder())); - public static final Item OXIDIZED_CUT_COPPER_STAIRS = register(new BlockItem("oxidized_cut_copper_stairs", builder())); - public static final Item CUT_COPPER_SLAB = register(new BlockItem("cut_copper_slab", builder())); - public static final Item EXPOSED_CUT_COPPER_SLAB = register(new BlockItem("exposed_cut_copper_slab", builder())); - public static final Item WEATHERED_CUT_COPPER_SLAB = register(new BlockItem("weathered_cut_copper_slab", builder())); - public static final Item OXIDIZED_CUT_COPPER_SLAB = register(new BlockItem("oxidized_cut_copper_slab", builder())); - public static final Item WAXED_COPPER_BLOCK = register(new BlockItem("waxed_copper_block", builder())); - public static final Item WAXED_EXPOSED_COPPER = register(new BlockItem("waxed_exposed_copper", builder())); - public static final Item WAXED_WEATHERED_COPPER = register(new BlockItem("waxed_weathered_copper", builder())); - public static final Item WAXED_OXIDIZED_COPPER = register(new BlockItem("waxed_oxidized_copper", builder())); - public static final Item WAXED_CHISELED_COPPER = register(new BlockItem("waxed_chiseled_copper", builder())); - public static final Item WAXED_EXPOSED_CHISELED_COPPER = register(new BlockItem("waxed_exposed_chiseled_copper", builder())); - public static final Item WAXED_WEATHERED_CHISELED_COPPER = register(new BlockItem("waxed_weathered_chiseled_copper", builder())); - public static final Item WAXED_OXIDIZED_CHISELED_COPPER = register(new BlockItem("waxed_oxidized_chiseled_copper", builder())); - public static final Item WAXED_CUT_COPPER = register(new BlockItem("waxed_cut_copper", builder())); - public static final Item WAXED_EXPOSED_CUT_COPPER = register(new BlockItem("waxed_exposed_cut_copper", builder())); - public static final Item WAXED_WEATHERED_CUT_COPPER = register(new BlockItem("waxed_weathered_cut_copper", builder())); - public static final Item WAXED_OXIDIZED_CUT_COPPER = register(new BlockItem("waxed_oxidized_cut_copper", builder())); - public static final Item WAXED_CUT_COPPER_STAIRS = register(new BlockItem("waxed_cut_copper_stairs", builder())); - public static final Item WAXED_EXPOSED_CUT_COPPER_STAIRS = register(new BlockItem("waxed_exposed_cut_copper_stairs", builder())); - public static final Item WAXED_WEATHERED_CUT_COPPER_STAIRS = register(new BlockItem("waxed_weathered_cut_copper_stairs", builder())); - public static final Item WAXED_OXIDIZED_CUT_COPPER_STAIRS = register(new BlockItem("waxed_oxidized_cut_copper_stairs", builder())); - public static final Item WAXED_CUT_COPPER_SLAB = register(new BlockItem("waxed_cut_copper_slab", builder())); - public static final Item WAXED_EXPOSED_CUT_COPPER_SLAB = register(new BlockItem("waxed_exposed_cut_copper_slab", builder())); - public static final Item WAXED_WEATHERED_CUT_COPPER_SLAB = register(new BlockItem("waxed_weathered_cut_copper_slab", builder())); - public static final Item WAXED_OXIDIZED_CUT_COPPER_SLAB = register(new BlockItem("waxed_oxidized_cut_copper_slab", builder())); - public static final Item OAK_LOG = register(new BlockItem("oak_log", builder())); - public static final Item SPRUCE_LOG = register(new BlockItem("spruce_log", builder())); - public static final Item BIRCH_LOG = register(new BlockItem("birch_log", builder())); - public static final Item JUNGLE_LOG = register(new BlockItem("jungle_log", builder())); - public static final Item ACACIA_LOG = register(new BlockItem("acacia_log", builder())); - public static final Item CHERRY_LOG = register(new BlockItem("cherry_log", builder())); - public static final Item DARK_OAK_LOG = register(new BlockItem("dark_oak_log", builder())); - public static final Item MANGROVE_LOG = register(new BlockItem("mangrove_log", builder())); - public static final Item MANGROVE_ROOTS = register(new BlockItem("mangrove_roots", builder())); - public static final Item MUDDY_MANGROVE_ROOTS = register(new BlockItem("muddy_mangrove_roots", builder())); - public static final Item CRIMSON_STEM = register(new BlockItem("crimson_stem", builder())); - public static final Item WARPED_STEM = register(new BlockItem("warped_stem", builder())); - public static final Item BAMBOO_BLOCK = register(new BlockItem("bamboo_block", builder())); - public static final Item STRIPPED_OAK_LOG = register(new BlockItem("stripped_oak_log", builder())); - public static final Item STRIPPED_SPRUCE_LOG = register(new BlockItem("stripped_spruce_log", builder())); - public static final Item STRIPPED_BIRCH_LOG = register(new BlockItem("stripped_birch_log", builder())); - public static final Item STRIPPED_JUNGLE_LOG = register(new BlockItem("stripped_jungle_log", builder())); - public static final Item STRIPPED_ACACIA_LOG = register(new BlockItem("stripped_acacia_log", builder())); - public static final Item STRIPPED_CHERRY_LOG = register(new BlockItem("stripped_cherry_log", builder())); - public static final Item STRIPPED_DARK_OAK_LOG = register(new BlockItem("stripped_dark_oak_log", builder())); - public static final Item STRIPPED_MANGROVE_LOG = register(new BlockItem("stripped_mangrove_log", builder())); - public static final Item STRIPPED_CRIMSON_STEM = register(new BlockItem("stripped_crimson_stem", builder())); - public static final Item STRIPPED_WARPED_STEM = register(new BlockItem("stripped_warped_stem", builder())); - public static final Item STRIPPED_OAK_WOOD = register(new BlockItem("stripped_oak_wood", builder())); - public static final Item STRIPPED_SPRUCE_WOOD = register(new BlockItem("stripped_spruce_wood", builder())); - public static final Item STRIPPED_BIRCH_WOOD = register(new BlockItem("stripped_birch_wood", builder())); - public static final Item STRIPPED_JUNGLE_WOOD = register(new BlockItem("stripped_jungle_wood", builder())); - public static final Item STRIPPED_ACACIA_WOOD = register(new BlockItem("stripped_acacia_wood", builder())); - public static final Item STRIPPED_CHERRY_WOOD = register(new BlockItem("stripped_cherry_wood", builder())); - public static final Item STRIPPED_DARK_OAK_WOOD = register(new BlockItem("stripped_dark_oak_wood", builder())); - public static final Item STRIPPED_MANGROVE_WOOD = register(new BlockItem("stripped_mangrove_wood", builder())); - public static final Item STRIPPED_CRIMSON_HYPHAE = register(new BlockItem("stripped_crimson_hyphae", builder())); - public static final Item STRIPPED_WARPED_HYPHAE = register(new BlockItem("stripped_warped_hyphae", builder())); - public static final Item STRIPPED_BAMBOO_BLOCK = register(new BlockItem("stripped_bamboo_block", builder())); - public static final Item OAK_WOOD = register(new BlockItem("oak_wood", builder())); - public static final Item SPRUCE_WOOD = register(new BlockItem("spruce_wood", builder())); - public static final Item BIRCH_WOOD = register(new BlockItem("birch_wood", builder())); - public static final Item JUNGLE_WOOD = register(new BlockItem("jungle_wood", builder())); - public static final Item ACACIA_WOOD = register(new BlockItem("acacia_wood", builder())); - public static final Item CHERRY_WOOD = register(new BlockItem("cherry_wood", builder())); - public static final Item DARK_OAK_WOOD = register(new BlockItem("dark_oak_wood", builder())); - public static final Item MANGROVE_WOOD = register(new BlockItem("mangrove_wood", builder())); - public static final Item CRIMSON_HYPHAE = register(new BlockItem("crimson_hyphae", builder())); - public static final Item WARPED_HYPHAE = register(new BlockItem("warped_hyphae", builder())); - public static final Item OAK_LEAVES = register(new BlockItem("oak_leaves", builder())); - public static final Item SPRUCE_LEAVES = register(new BlockItem("spruce_leaves", builder())); - public static final Item BIRCH_LEAVES = register(new BlockItem("birch_leaves", builder())); - public static final Item JUNGLE_LEAVES = register(new BlockItem("jungle_leaves", builder())); - public static final Item ACACIA_LEAVES = register(new BlockItem("acacia_leaves", builder())); - public static final Item CHERRY_LEAVES = register(new BlockItem("cherry_leaves", builder())); - public static final Item DARK_OAK_LEAVES = register(new BlockItem("dark_oak_leaves", builder())); - public static final Item MANGROVE_LEAVES = register(new BlockItem("mangrove_leaves", builder())); - public static final Item AZALEA_LEAVES = register(new BlockItem("azalea_leaves", builder())); - public static final Item FLOWERING_AZALEA_LEAVES = register(new BlockItem("flowering_azalea_leaves", builder())); - public static final Item SPONGE = register(new BlockItem("sponge", builder())); - public static final Item WET_SPONGE = register(new BlockItem("wet_sponge", builder())); - public static final Item GLASS = register(new BlockItem("glass", builder())); - public static final Item TINTED_GLASS = register(new BlockItem("tinted_glass", builder())); - public static final Item LAPIS_BLOCK = register(new BlockItem("lapis_block", builder())); - public static final Item SANDSTONE = register(new BlockItem("sandstone", builder())); - public static final Item CHISELED_SANDSTONE = register(new BlockItem("chiseled_sandstone", builder())); - public static final Item CUT_SANDSTONE = register(new BlockItem("cut_sandstone", builder())); - public static final Item COBWEB = register(new BlockItem("cobweb", builder())); - public static final Item SHORT_GRASS = register(new BlockItem("short_grass", builder())); - public static final Item FERN = register(new BlockItem("fern", builder())); - public static final Item AZALEA = register(new BlockItem("azalea", builder())); - public static final Item FLOWERING_AZALEA = register(new BlockItem("flowering_azalea", builder())); - public static final Item DEAD_BUSH = register(new BlockItem("dead_bush", builder())); - public static final Item SEAGRASS = register(new BlockItem("seagrass", builder())); - public static final Item SEA_PICKLE = register(new BlockItem("sea_pickle", builder())); - public static final Item WHITE_WOOL = register(new BlockItem("white_wool", builder())); - public static final Item ORANGE_WOOL = register(new BlockItem("orange_wool", builder())); - public static final Item MAGENTA_WOOL = register(new BlockItem("magenta_wool", builder())); - public static final Item LIGHT_BLUE_WOOL = register(new BlockItem("light_blue_wool", builder())); - public static final Item YELLOW_WOOL = register(new BlockItem("yellow_wool", builder())); - public static final Item LIME_WOOL = register(new BlockItem("lime_wool", builder())); - public static final Item PINK_WOOL = register(new BlockItem("pink_wool", builder())); - public static final Item GRAY_WOOL = register(new BlockItem("gray_wool", builder())); - public static final Item LIGHT_GRAY_WOOL = register(new BlockItem("light_gray_wool", builder())); - public static final Item CYAN_WOOL = register(new BlockItem("cyan_wool", builder())); - public static final Item PURPLE_WOOL = register(new BlockItem("purple_wool", builder())); - public static final Item BLUE_WOOL = register(new BlockItem("blue_wool", builder())); - public static final Item BROWN_WOOL = register(new BlockItem("brown_wool", builder())); - public static final Item GREEN_WOOL = register(new BlockItem("green_wool", builder())); - public static final Item RED_WOOL = register(new BlockItem("red_wool", builder())); - public static final Item BLACK_WOOL = register(new BlockItem("black_wool", builder())); - public static final Item DANDELION = register(new BlockItem("dandelion", builder())); - public static final Item POPPY = register(new BlockItem("poppy", builder())); - public static final Item BLUE_ORCHID = register(new BlockItem("blue_orchid", builder())); - public static final Item ALLIUM = register(new BlockItem("allium", builder())); - public static final Item AZURE_BLUET = register(new BlockItem("azure_bluet", builder())); - public static final Item RED_TULIP = register(new BlockItem("red_tulip", builder())); - public static final Item ORANGE_TULIP = register(new BlockItem("orange_tulip", builder())); - public static final Item WHITE_TULIP = register(new BlockItem("white_tulip", builder())); - public static final Item PINK_TULIP = register(new BlockItem("pink_tulip", builder())); - public static final Item OXEYE_DAISY = register(new BlockItem("oxeye_daisy", builder())); - public static final Item CORNFLOWER = register(new BlockItem("cornflower", builder())); - public static final Item LILY_OF_THE_VALLEY = register(new BlockItem("lily_of_the_valley", builder())); - public static final Item WITHER_ROSE = register(new BlockItem("wither_rose", builder())); - public static final Item TORCHFLOWER = register(new BlockItem("torchflower", builder())); - public static final Item PITCHER_PLANT = register(new BlockItem("pitcher_plant", builder())); - public static final Item SPORE_BLOSSOM = register(new BlockItem("spore_blossom", builder())); - public static final Item BROWN_MUSHROOM = register(new BlockItem("brown_mushroom", builder())); - public static final Item RED_MUSHROOM = register(new BlockItem("red_mushroom", builder())); - public static final Item CRIMSON_FUNGUS = register(new BlockItem("crimson_fungus", builder())); - public static final Item WARPED_FUNGUS = register(new BlockItem("warped_fungus", builder())); - public static final Item CRIMSON_ROOTS = register(new BlockItem("crimson_roots", builder())); - public static final Item WARPED_ROOTS = register(new BlockItem("warped_roots", builder())); - public static final Item NETHER_SPROUTS = register(new BlockItem("nether_sprouts", builder())); - public static final Item WEEPING_VINES = register(new BlockItem("weeping_vines", builder())); - public static final Item TWISTING_VINES = register(new BlockItem("twisting_vines", builder())); - public static final Item SUGAR_CANE = register(new BlockItem("sugar_cane", builder())); - public static final Item KELP = register(new BlockItem("kelp", builder())); - public static final Item MOSS_CARPET = register(new BlockItem("moss_carpet", builder())); - public static final Item PINK_PETALS = register(new BlockItem("pink_petals", builder())); - public static final Item MOSS_BLOCK = register(new BlockItem("moss_block", builder())); - public static final Item HANGING_ROOTS = register(new BlockItem("hanging_roots", builder())); - public static final Item BIG_DRIPLEAF = register(new BlockItem("big_dripleaf", builder())); - public static final Item SMALL_DRIPLEAF = register(new BlockItem("small_dripleaf", builder())); - public static final Item BAMBOO = register(new BlockItem("bamboo", builder())); - public static final Item OAK_SLAB = register(new BlockItem("oak_slab", builder())); - public static final Item SPRUCE_SLAB = register(new BlockItem("spruce_slab", builder())); - public static final Item BIRCH_SLAB = register(new BlockItem("birch_slab", builder())); - public static final Item JUNGLE_SLAB = register(new BlockItem("jungle_slab", builder())); - public static final Item ACACIA_SLAB = register(new BlockItem("acacia_slab", builder())); - public static final Item CHERRY_SLAB = register(new BlockItem("cherry_slab", builder())); - public static final Item DARK_OAK_SLAB = register(new BlockItem("dark_oak_slab", builder())); - public static final Item MANGROVE_SLAB = register(new BlockItem("mangrove_slab", builder())); - public static final Item BAMBOO_SLAB = register(new BlockItem("bamboo_slab", builder())); - public static final Item BAMBOO_MOSAIC_SLAB = register(new BlockItem("bamboo_mosaic_slab", builder())); - public static final Item CRIMSON_SLAB = register(new BlockItem("crimson_slab", builder())); - public static final Item WARPED_SLAB = register(new BlockItem("warped_slab", builder())); - public static final Item STONE_SLAB = register(new BlockItem("stone_slab", builder())); - public static final Item SMOOTH_STONE_SLAB = register(new BlockItem("smooth_stone_slab", builder())); - public static final Item SANDSTONE_SLAB = register(new BlockItem("sandstone_slab", builder())); - public static final Item CUT_SANDSTONE_SLAB = register(new BlockItem("cut_sandstone_slab", builder())); - public static final Item PETRIFIED_OAK_SLAB = register(new BlockItem("petrified_oak_slab", builder())); - public static final Item COBBLESTONE_SLAB = register(new BlockItem("cobblestone_slab", builder())); - public static final Item BRICK_SLAB = register(new BlockItem("brick_slab", builder())); - public static final Item STONE_BRICK_SLAB = register(new BlockItem("stone_brick_slab", builder())); - public static final Item MUD_BRICK_SLAB = register(new BlockItem("mud_brick_slab", builder())); - public static final Item NETHER_BRICK_SLAB = register(new BlockItem("nether_brick_slab", builder())); - public static final Item QUARTZ_SLAB = register(new BlockItem("quartz_slab", builder())); - public static final Item RED_SANDSTONE_SLAB = register(new BlockItem("red_sandstone_slab", builder())); - public static final Item CUT_RED_SANDSTONE_SLAB = register(new BlockItem("cut_red_sandstone_slab", builder())); - public static final Item PURPUR_SLAB = register(new BlockItem("purpur_slab", builder())); - public static final Item PRISMARINE_SLAB = register(new BlockItem("prismarine_slab", builder())); - public static final Item PRISMARINE_BRICK_SLAB = register(new BlockItem("prismarine_brick_slab", builder())); - public static final Item DARK_PRISMARINE_SLAB = register(new BlockItem("dark_prismarine_slab", builder())); - public static final Item SMOOTH_QUARTZ = register(new BlockItem("smooth_quartz", builder())); - public static final Item SMOOTH_RED_SANDSTONE = register(new BlockItem("smooth_red_sandstone", builder())); - public static final Item SMOOTH_SANDSTONE = register(new BlockItem("smooth_sandstone", builder())); - public static final Item SMOOTH_STONE = register(new BlockItem("smooth_stone", builder())); - public static final Item BRICKS = register(new BlockItem("bricks", builder())); - public static final Item BOOKSHELF = register(new BlockItem("bookshelf", builder())); - public static final Item CHISELED_BOOKSHELF = register(new BlockItem("chiseled_bookshelf", builder())); - public static final Item DECORATED_POT = register(new DecoratedPotItem("decorated_pot", builder())); - public static final Item MOSSY_COBBLESTONE = register(new BlockItem("mossy_cobblestone", builder())); - public static final Item OBSIDIAN = register(new BlockItem("obsidian", builder())); - public static final Item TORCH = register(new BlockItem("torch", builder())); - public static final Item END_ROD = register(new BlockItem("end_rod", builder())); - public static final Item CHORUS_PLANT = register(new BlockItem("chorus_plant", builder())); - public static final Item CHORUS_FLOWER = register(new BlockItem("chorus_flower", builder())); - public static final Item PURPUR_BLOCK = register(new BlockItem("purpur_block", builder())); - public static final Item PURPUR_PILLAR = register(new BlockItem("purpur_pillar", builder())); - public static final Item PURPUR_STAIRS = register(new BlockItem("purpur_stairs", builder())); - public static final Item SPAWNER = register(new BlockItem("spawner", builder())); - public static final Item CHEST = register(new BlockItem("chest", builder())); - public static final Item CRAFTING_TABLE = register(new BlockItem("crafting_table", builder())); - public static final Item FARMLAND = register(new BlockItem("farmland", builder())); - public static final Item FURNACE = register(new BlockItem("furnace", builder())); - public static final Item LADDER = register(new BlockItem("ladder", builder())); - public static final Item COBBLESTONE_STAIRS = register(new BlockItem("cobblestone_stairs", builder())); - public static final Item SNOW = register(new BlockItem("snow", builder())); - public static final Item ICE = register(new BlockItem("ice", builder())); - public static final Item SNOW_BLOCK = register(new BlockItem("snow_block", builder())); - public static final Item CACTUS = register(new BlockItem("cactus", builder())); - public static final Item CLAY = register(new BlockItem("clay", builder())); - public static final Item JUKEBOX = register(new BlockItem("jukebox", builder())); - public static final Item OAK_FENCE = register(new BlockItem("oak_fence", builder())); - public static final Item SPRUCE_FENCE = register(new BlockItem("spruce_fence", builder())); - public static final Item BIRCH_FENCE = register(new BlockItem("birch_fence", builder())); - public static final Item JUNGLE_FENCE = register(new BlockItem("jungle_fence", builder())); - public static final Item ACACIA_FENCE = register(new BlockItem("acacia_fence", builder())); - public static final Item CHERRY_FENCE = register(new BlockItem("cherry_fence", builder())); - public static final Item DARK_OAK_FENCE = register(new BlockItem("dark_oak_fence", builder())); - public static final Item MANGROVE_FENCE = register(new BlockItem("mangrove_fence", builder())); - public static final Item BAMBOO_FENCE = register(new BlockItem("bamboo_fence", builder())); - public static final Item CRIMSON_FENCE = register(new BlockItem("crimson_fence", builder())); - public static final Item WARPED_FENCE = register(new BlockItem("warped_fence", builder())); - public static final Item PUMPKIN = register(new BlockItem("pumpkin", builder())); - public static final Item CARVED_PUMPKIN = register(new BlockItem("carved_pumpkin", builder())); - public static final Item JACK_O_LANTERN = register(new BlockItem("jack_o_lantern", builder())); - public static final Item NETHERRACK = register(new BlockItem("netherrack", builder())); - public static final Item SOUL_SAND = register(new BlockItem("soul_sand", builder())); - public static final Item SOUL_SOIL = register(new BlockItem("soul_soil", builder())); - public static final Item BASALT = register(new BlockItem("basalt", builder())); - public static final Item POLISHED_BASALT = register(new BlockItem("polished_basalt", builder())); - public static final Item SMOOTH_BASALT = register(new BlockItem("smooth_basalt", builder())); - public static final Item SOUL_TORCH = register(new BlockItem("soul_torch", builder())); - public static final Item GLOWSTONE = register(new BlockItem("glowstone", builder())); - public static final Item INFESTED_STONE = register(new BlockItem("infested_stone", builder())); - public static final Item INFESTED_COBBLESTONE = register(new BlockItem("infested_cobblestone", builder())); - public static final Item INFESTED_STONE_BRICKS = register(new BlockItem("infested_stone_bricks", builder())); - public static final Item INFESTED_MOSSY_STONE_BRICKS = register(new BlockItem("infested_mossy_stone_bricks", builder())); - public static final Item INFESTED_CRACKED_STONE_BRICKS = register(new BlockItem("infested_cracked_stone_bricks", builder())); - public static final Item INFESTED_CHISELED_STONE_BRICKS = register(new BlockItem("infested_chiseled_stone_bricks", builder())); - public static final Item INFESTED_DEEPSLATE = register(new BlockItem("infested_deepslate", builder())); - public static final Item STONE_BRICKS = register(new BlockItem("stone_bricks", builder())); - public static final Item MOSSY_STONE_BRICKS = register(new BlockItem("mossy_stone_bricks", builder())); - public static final Item CRACKED_STONE_BRICKS = register(new BlockItem("cracked_stone_bricks", builder())); - public static final Item CHISELED_STONE_BRICKS = register(new BlockItem("chiseled_stone_bricks", builder())); - public static final Item PACKED_MUD = register(new BlockItem("packed_mud", builder())); - public static final Item MUD_BRICKS = register(new BlockItem("mud_bricks", builder())); - public static final Item DEEPSLATE_BRICKS = register(new BlockItem("deepslate_bricks", builder())); - public static final Item CRACKED_DEEPSLATE_BRICKS = register(new BlockItem("cracked_deepslate_bricks", builder())); - public static final Item DEEPSLATE_TILES = register(new BlockItem("deepslate_tiles", builder())); - public static final Item CRACKED_DEEPSLATE_TILES = register(new BlockItem("cracked_deepslate_tiles", builder())); - public static final Item CHISELED_DEEPSLATE = register(new BlockItem("chiseled_deepslate", builder())); - public static final Item REINFORCED_DEEPSLATE = register(new BlockItem("reinforced_deepslate", builder())); - public static final Item BROWN_MUSHROOM_BLOCK = register(new BlockItem("brown_mushroom_block", builder())); - public static final Item RED_MUSHROOM_BLOCK = register(new BlockItem("red_mushroom_block", builder())); - public static final Item MUSHROOM_STEM = register(new BlockItem("mushroom_stem", builder())); - public static final Item IRON_BARS = register(new BlockItem("iron_bars", builder())); - public static final Item CHAIN = register(new BlockItem("chain", builder())); - public static final Item GLASS_PANE = register(new BlockItem("glass_pane", builder())); - public static final Item MELON = register(new BlockItem("melon", builder())); - public static final Item VINE = register(new BlockItem("vine", builder())); - public static final Item GLOW_LICHEN = register(new BlockItem("glow_lichen", builder())); - public static final Item BRICK_STAIRS = register(new BlockItem("brick_stairs", builder())); - public static final Item STONE_BRICK_STAIRS = register(new BlockItem("stone_brick_stairs", builder())); - public static final Item MUD_BRICK_STAIRS = register(new BlockItem("mud_brick_stairs", builder())); - public static final Item MYCELIUM = register(new BlockItem("mycelium", builder())); - public static final Item LILY_PAD = register(new BlockItem("lily_pad", builder())); - public static final Item NETHER_BRICKS = register(new BlockItem("nether_bricks", builder())); - public static final Item CRACKED_NETHER_BRICKS = register(new BlockItem("cracked_nether_bricks", builder())); - public static final Item CHISELED_NETHER_BRICKS = register(new BlockItem("chiseled_nether_bricks", builder())); - public static final Item NETHER_BRICK_FENCE = register(new BlockItem("nether_brick_fence", builder())); - public static final Item NETHER_BRICK_STAIRS = register(new BlockItem("nether_brick_stairs", builder())); - public static final Item SCULK = register(new BlockItem("sculk", builder())); - public static final Item SCULK_VEIN = register(new BlockItem("sculk_vein", builder())); - public static final Item SCULK_CATALYST = register(new BlockItem("sculk_catalyst", builder())); - public static final Item SCULK_SHRIEKER = register(new BlockItem("sculk_shrieker", builder())); - public static final Item ENCHANTING_TABLE = register(new BlockItem("enchanting_table", builder())); - public static final Item END_PORTAL_FRAME = register(new BlockItem("end_portal_frame", builder())); - public static final Item END_STONE = register(new BlockItem("end_stone", builder())); - public static final Item END_STONE_BRICKS = register(new BlockItem("end_stone_bricks", builder())); - public static final Item DRAGON_EGG = register(new BlockItem("dragon_egg", builder())); - public static final Item SANDSTONE_STAIRS = register(new BlockItem("sandstone_stairs", builder())); - public static final Item ENDER_CHEST = register(new BlockItem("ender_chest", builder())); - public static final Item EMERALD_BLOCK = register(new BlockItem("emerald_block", builder())); - public static final Item OAK_STAIRS = register(new BlockItem("oak_stairs", builder())); - public static final Item SPRUCE_STAIRS = register(new BlockItem("spruce_stairs", builder())); - public static final Item BIRCH_STAIRS = register(new BlockItem("birch_stairs", builder())); - public static final Item JUNGLE_STAIRS = register(new BlockItem("jungle_stairs", builder())); - public static final Item ACACIA_STAIRS = register(new BlockItem("acacia_stairs", builder())); - public static final Item CHERRY_STAIRS = register(new BlockItem("cherry_stairs", builder())); - public static final Item DARK_OAK_STAIRS = register(new BlockItem("dark_oak_stairs", builder())); - public static final Item MANGROVE_STAIRS = register(new BlockItem("mangrove_stairs", builder())); - public static final Item BAMBOO_STAIRS = register(new BlockItem("bamboo_stairs", builder())); - public static final Item BAMBOO_MOSAIC_STAIRS = register(new BlockItem("bamboo_mosaic_stairs", builder())); - public static final Item CRIMSON_STAIRS = register(new BlockItem("crimson_stairs", builder())); - public static final Item WARPED_STAIRS = register(new BlockItem("warped_stairs", builder())); - public static final Item COMMAND_BLOCK = register(new BlockItem("command_block", builder())); - public static final Item BEACON = register(new BlockItem("beacon", builder())); - public static final Item COBBLESTONE_WALL = register(new BlockItem("cobblestone_wall", builder())); - public static final Item MOSSY_COBBLESTONE_WALL = register(new BlockItem("mossy_cobblestone_wall", builder())); - public static final Item BRICK_WALL = register(new BlockItem("brick_wall", builder())); - public static final Item PRISMARINE_WALL = register(new BlockItem("prismarine_wall", builder())); - public static final Item RED_SANDSTONE_WALL = register(new BlockItem("red_sandstone_wall", builder())); - public static final Item MOSSY_STONE_BRICK_WALL = register(new BlockItem("mossy_stone_brick_wall", builder())); - public static final Item GRANITE_WALL = register(new BlockItem("granite_wall", builder())); - public static final Item STONE_BRICK_WALL = register(new BlockItem("stone_brick_wall", builder())); - public static final Item MUD_BRICK_WALL = register(new BlockItem("mud_brick_wall", builder())); - public static final Item NETHER_BRICK_WALL = register(new BlockItem("nether_brick_wall", builder())); - public static final Item ANDESITE_WALL = register(new BlockItem("andesite_wall", builder())); - public static final Item RED_NETHER_BRICK_WALL = register(new BlockItem("red_nether_brick_wall", builder())); - public static final Item SANDSTONE_WALL = register(new BlockItem("sandstone_wall", builder())); - public static final Item END_STONE_BRICK_WALL = register(new BlockItem("end_stone_brick_wall", builder())); - public static final Item DIORITE_WALL = register(new BlockItem("diorite_wall", builder())); - public static final Item BLACKSTONE_WALL = register(new BlockItem("blackstone_wall", builder())); - public static final Item POLISHED_BLACKSTONE_WALL = register(new BlockItem("polished_blackstone_wall", builder())); - public static final Item POLISHED_BLACKSTONE_BRICK_WALL = register(new BlockItem("polished_blackstone_brick_wall", builder())); - public static final Item COBBLED_DEEPSLATE_WALL = register(new BlockItem("cobbled_deepslate_wall", builder())); - public static final Item POLISHED_DEEPSLATE_WALL = register(new BlockItem("polished_deepslate_wall", builder())); - public static final Item DEEPSLATE_BRICK_WALL = register(new BlockItem("deepslate_brick_wall", builder())); - public static final Item DEEPSLATE_TILE_WALL = register(new BlockItem("deepslate_tile_wall", builder())); - public static final Item ANVIL = register(new BlockItem("anvil", builder())); - public static final Item CHIPPED_ANVIL = register(new BlockItem("chipped_anvil", builder())); - public static final Item DAMAGED_ANVIL = register(new BlockItem("damaged_anvil", builder())); - public static final Item CHISELED_QUARTZ_BLOCK = register(new BlockItem("chiseled_quartz_block", builder())); - public static final Item QUARTZ_BLOCK = register(new BlockItem("quartz_block", builder())); - public static final Item QUARTZ_BRICKS = register(new BlockItem("quartz_bricks", builder())); - public static final Item QUARTZ_PILLAR = register(new BlockItem("quartz_pillar", builder())); - public static final Item QUARTZ_STAIRS = register(new BlockItem("quartz_stairs", builder())); - public static final Item WHITE_TERRACOTTA = register(new BlockItem("white_terracotta", builder())); - public static final Item ORANGE_TERRACOTTA = register(new BlockItem("orange_terracotta", builder())); - public static final Item MAGENTA_TERRACOTTA = register(new BlockItem("magenta_terracotta", builder())); - public static final Item LIGHT_BLUE_TERRACOTTA = register(new BlockItem("light_blue_terracotta", builder())); - public static final Item YELLOW_TERRACOTTA = register(new BlockItem("yellow_terracotta", builder())); - public static final Item LIME_TERRACOTTA = register(new BlockItem("lime_terracotta", builder())); - public static final Item PINK_TERRACOTTA = register(new BlockItem("pink_terracotta", builder())); - public static final Item GRAY_TERRACOTTA = register(new BlockItem("gray_terracotta", builder())); - public static final Item LIGHT_GRAY_TERRACOTTA = register(new BlockItem("light_gray_terracotta", builder())); - public static final Item CYAN_TERRACOTTA = register(new BlockItem("cyan_terracotta", builder())); - public static final Item PURPLE_TERRACOTTA = register(new BlockItem("purple_terracotta", builder())); - public static final Item BLUE_TERRACOTTA = register(new BlockItem("blue_terracotta", builder())); - public static final Item BROWN_TERRACOTTA = register(new BlockItem("brown_terracotta", builder())); - public static final Item GREEN_TERRACOTTA = register(new BlockItem("green_terracotta", builder())); - public static final Item RED_TERRACOTTA = register(new BlockItem("red_terracotta", builder())); - public static final Item BLACK_TERRACOTTA = register(new BlockItem("black_terracotta", builder())); - public static final Item BARRIER = register(new BlockItem("barrier", builder())); - public static final Item LIGHT = register(new BlockItem("light", builder())); - public static final Item HAY_BLOCK = register(new BlockItem("hay_block", builder())); - public static final Item WHITE_CARPET = register(new BlockItem("white_carpet", builder())); - public static final Item ORANGE_CARPET = register(new BlockItem("orange_carpet", builder())); - public static final Item MAGENTA_CARPET = register(new BlockItem("magenta_carpet", builder())); - public static final Item LIGHT_BLUE_CARPET = register(new BlockItem("light_blue_carpet", builder())); - public static final Item YELLOW_CARPET = register(new BlockItem("yellow_carpet", builder())); - public static final Item LIME_CARPET = register(new BlockItem("lime_carpet", builder())); - public static final Item PINK_CARPET = register(new BlockItem("pink_carpet", builder())); - public static final Item GRAY_CARPET = register(new BlockItem("gray_carpet", builder())); - public static final Item LIGHT_GRAY_CARPET = register(new BlockItem("light_gray_carpet", builder())); - public static final Item CYAN_CARPET = register(new BlockItem("cyan_carpet", builder())); - public static final Item PURPLE_CARPET = register(new BlockItem("purple_carpet", builder())); - public static final Item BLUE_CARPET = register(new BlockItem("blue_carpet", builder())); - public static final Item BROWN_CARPET = register(new BlockItem("brown_carpet", builder())); - public static final Item GREEN_CARPET = register(new BlockItem("green_carpet", builder())); - public static final Item RED_CARPET = register(new BlockItem("red_carpet", builder())); - public static final Item BLACK_CARPET = register(new BlockItem("black_carpet", builder())); - public static final Item TERRACOTTA = register(new BlockItem("terracotta", builder())); - public static final Item PACKED_ICE = register(new BlockItem("packed_ice", builder())); - public static final Item DIRT_PATH = register(new BlockItem("dirt_path", builder())); - public static final Item SUNFLOWER = register(new BlockItem("sunflower", builder())); - public static final Item LILAC = register(new BlockItem("lilac", builder())); - public static final Item ROSE_BUSH = register(new BlockItem("rose_bush", builder())); - public static final Item PEONY = register(new BlockItem("peony", builder())); - public static final Item TALL_GRASS = register(new BlockItem("tall_grass", builder())); - public static final Item LARGE_FERN = register(new BlockItem("large_fern", builder())); - public static final Item WHITE_STAINED_GLASS = register(new BlockItem("white_stained_glass", builder())); - public static final Item ORANGE_STAINED_GLASS = register(new BlockItem("orange_stained_glass", builder())); - public static final Item MAGENTA_STAINED_GLASS = register(new BlockItem("magenta_stained_glass", builder())); - public static final Item LIGHT_BLUE_STAINED_GLASS = register(new BlockItem("light_blue_stained_glass", builder())); - public static final Item YELLOW_STAINED_GLASS = register(new BlockItem("yellow_stained_glass", builder())); - public static final Item LIME_STAINED_GLASS = register(new BlockItem("lime_stained_glass", builder())); - public static final Item PINK_STAINED_GLASS = register(new BlockItem("pink_stained_glass", builder())); - public static final Item GRAY_STAINED_GLASS = register(new BlockItem("gray_stained_glass", builder())); - public static final Item LIGHT_GRAY_STAINED_GLASS = register(new BlockItem("light_gray_stained_glass", builder())); - public static final Item CYAN_STAINED_GLASS = register(new BlockItem("cyan_stained_glass", builder())); - public static final Item PURPLE_STAINED_GLASS = register(new BlockItem("purple_stained_glass", builder())); - public static final Item BLUE_STAINED_GLASS = register(new BlockItem("blue_stained_glass", builder())); - public static final Item BROWN_STAINED_GLASS = register(new BlockItem("brown_stained_glass", builder())); - public static final Item GREEN_STAINED_GLASS = register(new BlockItem("green_stained_glass", builder())); - public static final Item RED_STAINED_GLASS = register(new BlockItem("red_stained_glass", builder())); - public static final Item BLACK_STAINED_GLASS = register(new BlockItem("black_stained_glass", builder())); - public static final Item WHITE_STAINED_GLASS_PANE = register(new BlockItem("white_stained_glass_pane", builder())); - public static final Item ORANGE_STAINED_GLASS_PANE = register(new BlockItem("orange_stained_glass_pane", builder())); - public static final Item MAGENTA_STAINED_GLASS_PANE = register(new BlockItem("magenta_stained_glass_pane", builder())); - public static final Item LIGHT_BLUE_STAINED_GLASS_PANE = register(new BlockItem("light_blue_stained_glass_pane", builder())); - public static final Item YELLOW_STAINED_GLASS_PANE = register(new BlockItem("yellow_stained_glass_pane", builder())); - public static final Item LIME_STAINED_GLASS_PANE = register(new BlockItem("lime_stained_glass_pane", builder())); - public static final Item PINK_STAINED_GLASS_PANE = register(new BlockItem("pink_stained_glass_pane", builder())); - public static final Item GRAY_STAINED_GLASS_PANE = register(new BlockItem("gray_stained_glass_pane", builder())); - public static final Item LIGHT_GRAY_STAINED_GLASS_PANE = register(new BlockItem("light_gray_stained_glass_pane", builder())); - public static final Item CYAN_STAINED_GLASS_PANE = register(new BlockItem("cyan_stained_glass_pane", builder())); - public static final Item PURPLE_STAINED_GLASS_PANE = register(new BlockItem("purple_stained_glass_pane", builder())); - public static final Item BLUE_STAINED_GLASS_PANE = register(new BlockItem("blue_stained_glass_pane", builder())); - public static final Item BROWN_STAINED_GLASS_PANE = register(new BlockItem("brown_stained_glass_pane", builder())); - public static final Item GREEN_STAINED_GLASS_PANE = register(new BlockItem("green_stained_glass_pane", builder())); - public static final Item RED_STAINED_GLASS_PANE = register(new BlockItem("red_stained_glass_pane", builder())); - public static final Item BLACK_STAINED_GLASS_PANE = register(new BlockItem("black_stained_glass_pane", builder())); - public static final Item PRISMARINE = register(new BlockItem("prismarine", builder())); - public static final Item PRISMARINE_BRICKS = register(new BlockItem("prismarine_bricks", builder())); - public static final Item DARK_PRISMARINE = register(new BlockItem("dark_prismarine", builder())); - public static final Item PRISMARINE_STAIRS = register(new BlockItem("prismarine_stairs", builder())); - public static final Item PRISMARINE_BRICK_STAIRS = register(new BlockItem("prismarine_brick_stairs", builder())); - public static final Item DARK_PRISMARINE_STAIRS = register(new BlockItem("dark_prismarine_stairs", builder())); - public static final Item SEA_LANTERN = register(new BlockItem("sea_lantern", builder())); - public static final Item RED_SANDSTONE = register(new BlockItem("red_sandstone", builder())); - public static final Item CHISELED_RED_SANDSTONE = register(new BlockItem("chiseled_red_sandstone", builder())); - public static final Item CUT_RED_SANDSTONE = register(new BlockItem("cut_red_sandstone", builder())); - public static final Item RED_SANDSTONE_STAIRS = register(new BlockItem("red_sandstone_stairs", builder())); - public static final Item REPEATING_COMMAND_BLOCK = register(new BlockItem("repeating_command_block", builder())); - public static final Item CHAIN_COMMAND_BLOCK = register(new BlockItem("chain_command_block", builder())); - public static final Item MAGMA_BLOCK = register(new BlockItem("magma_block", builder())); - public static final Item NETHER_WART_BLOCK = register(new BlockItem("nether_wart_block", builder())); - public static final Item WARPED_WART_BLOCK = register(new BlockItem("warped_wart_block", builder())); - public static final Item RED_NETHER_BRICKS = register(new BlockItem("red_nether_bricks", builder())); - public static final Item BONE_BLOCK = register(new BlockItem("bone_block", builder())); - public static final Item STRUCTURE_VOID = register(new BlockItem("structure_void", builder())); - public static final Item SHULKER_BOX = register(new ShulkerBoxItem("shulker_box", builder().stackSize(1))); - public static final Item WHITE_SHULKER_BOX = register(new ShulkerBoxItem("white_shulker_box", builder().stackSize(1))); - public static final Item ORANGE_SHULKER_BOX = register(new ShulkerBoxItem("orange_shulker_box", builder().stackSize(1))); - public static final Item MAGENTA_SHULKER_BOX = register(new ShulkerBoxItem("magenta_shulker_box", builder().stackSize(1))); - public static final Item LIGHT_BLUE_SHULKER_BOX = register(new ShulkerBoxItem("light_blue_shulker_box", builder().stackSize(1))); - public static final Item YELLOW_SHULKER_BOX = register(new ShulkerBoxItem("yellow_shulker_box", builder().stackSize(1))); - public static final Item LIME_SHULKER_BOX = register(new ShulkerBoxItem("lime_shulker_box", builder().stackSize(1))); - public static final Item PINK_SHULKER_BOX = register(new ShulkerBoxItem("pink_shulker_box", builder().stackSize(1))); - public static final Item GRAY_SHULKER_BOX = register(new ShulkerBoxItem("gray_shulker_box", builder().stackSize(1))); - public static final Item LIGHT_GRAY_SHULKER_BOX = register(new ShulkerBoxItem("light_gray_shulker_box", builder().stackSize(1))); - public static final Item CYAN_SHULKER_BOX = register(new ShulkerBoxItem("cyan_shulker_box", builder().stackSize(1))); - public static final Item PURPLE_SHULKER_BOX = register(new ShulkerBoxItem("purple_shulker_box", builder().stackSize(1))); - public static final Item BLUE_SHULKER_BOX = register(new ShulkerBoxItem("blue_shulker_box", builder().stackSize(1))); - public static final Item BROWN_SHULKER_BOX = register(new ShulkerBoxItem("brown_shulker_box", builder().stackSize(1))); - public static final Item GREEN_SHULKER_BOX = register(new ShulkerBoxItem("green_shulker_box", builder().stackSize(1))); - public static final Item RED_SHULKER_BOX = register(new ShulkerBoxItem("red_shulker_box", builder().stackSize(1))); - public static final Item BLACK_SHULKER_BOX = register(new ShulkerBoxItem("black_shulker_box", builder().stackSize(1))); - public static final Item WHITE_GLAZED_TERRACOTTA = register(new BlockItem("white_glazed_terracotta", builder())); - public static final Item ORANGE_GLAZED_TERRACOTTA = register(new BlockItem("orange_glazed_terracotta", builder())); - public static final Item MAGENTA_GLAZED_TERRACOTTA = register(new BlockItem("magenta_glazed_terracotta", builder())); - public static final Item LIGHT_BLUE_GLAZED_TERRACOTTA = register(new BlockItem("light_blue_glazed_terracotta", builder())); - public static final Item YELLOW_GLAZED_TERRACOTTA = register(new BlockItem("yellow_glazed_terracotta", builder())); - public static final Item LIME_GLAZED_TERRACOTTA = register(new BlockItem("lime_glazed_terracotta", builder())); - public static final Item PINK_GLAZED_TERRACOTTA = register(new BlockItem("pink_glazed_terracotta", builder())); - public static final Item GRAY_GLAZED_TERRACOTTA = register(new BlockItem("gray_glazed_terracotta", builder())); - public static final Item LIGHT_GRAY_GLAZED_TERRACOTTA = register(new BlockItem("light_gray_glazed_terracotta", builder())); - public static final Item CYAN_GLAZED_TERRACOTTA = register(new BlockItem("cyan_glazed_terracotta", builder())); - public static final Item PURPLE_GLAZED_TERRACOTTA = register(new BlockItem("purple_glazed_terracotta", builder())); - public static final Item BLUE_GLAZED_TERRACOTTA = register(new BlockItem("blue_glazed_terracotta", builder())); - public static final Item BROWN_GLAZED_TERRACOTTA = register(new BlockItem("brown_glazed_terracotta", builder())); - public static final Item GREEN_GLAZED_TERRACOTTA = register(new BlockItem("green_glazed_terracotta", builder())); - public static final Item RED_GLAZED_TERRACOTTA = register(new BlockItem("red_glazed_terracotta", builder())); - public static final Item BLACK_GLAZED_TERRACOTTA = register(new BlockItem("black_glazed_terracotta", builder())); - public static final Item WHITE_CONCRETE = register(new BlockItem("white_concrete", builder())); - public static final Item ORANGE_CONCRETE = register(new BlockItem("orange_concrete", builder())); - public static final Item MAGENTA_CONCRETE = register(new BlockItem("magenta_concrete", builder())); - public static final Item LIGHT_BLUE_CONCRETE = register(new BlockItem("light_blue_concrete", builder())); - public static final Item YELLOW_CONCRETE = register(new BlockItem("yellow_concrete", builder())); - public static final Item LIME_CONCRETE = register(new BlockItem("lime_concrete", builder())); - public static final Item PINK_CONCRETE = register(new BlockItem("pink_concrete", builder())); - public static final Item GRAY_CONCRETE = register(new BlockItem("gray_concrete", builder())); - public static final Item LIGHT_GRAY_CONCRETE = register(new BlockItem("light_gray_concrete", builder())); - public static final Item CYAN_CONCRETE = register(new BlockItem("cyan_concrete", builder())); - public static final Item PURPLE_CONCRETE = register(new BlockItem("purple_concrete", builder())); - public static final Item BLUE_CONCRETE = register(new BlockItem("blue_concrete", builder())); - public static final Item BROWN_CONCRETE = register(new BlockItem("brown_concrete", builder())); - public static final Item GREEN_CONCRETE = register(new BlockItem("green_concrete", builder())); - public static final Item RED_CONCRETE = register(new BlockItem("red_concrete", builder())); - public static final Item BLACK_CONCRETE = register(new BlockItem("black_concrete", builder())); - public static final Item WHITE_CONCRETE_POWDER = register(new BlockItem("white_concrete_powder", builder())); - public static final Item ORANGE_CONCRETE_POWDER = register(new BlockItem("orange_concrete_powder", builder())); - public static final Item MAGENTA_CONCRETE_POWDER = register(new BlockItem("magenta_concrete_powder", builder())); - public static final Item LIGHT_BLUE_CONCRETE_POWDER = register(new BlockItem("light_blue_concrete_powder", builder())); - public static final Item YELLOW_CONCRETE_POWDER = register(new BlockItem("yellow_concrete_powder", builder())); - public static final Item LIME_CONCRETE_POWDER = register(new BlockItem("lime_concrete_powder", builder())); - public static final Item PINK_CONCRETE_POWDER = register(new BlockItem("pink_concrete_powder", builder())); - public static final Item GRAY_CONCRETE_POWDER = register(new BlockItem("gray_concrete_powder", builder())); - public static final Item LIGHT_GRAY_CONCRETE_POWDER = register(new BlockItem("light_gray_concrete_powder", builder())); - public static final Item CYAN_CONCRETE_POWDER = register(new BlockItem("cyan_concrete_powder", builder())); - public static final Item PURPLE_CONCRETE_POWDER = register(new BlockItem("purple_concrete_powder", builder())); - public static final Item BLUE_CONCRETE_POWDER = register(new BlockItem("blue_concrete_powder", builder())); - public static final Item BROWN_CONCRETE_POWDER = register(new BlockItem("brown_concrete_powder", builder())); - public static final Item GREEN_CONCRETE_POWDER = register(new BlockItem("green_concrete_powder", builder())); - public static final Item RED_CONCRETE_POWDER = register(new BlockItem("red_concrete_powder", builder())); - public static final Item BLACK_CONCRETE_POWDER = register(new BlockItem("black_concrete_powder", builder())); - public static final Item TURTLE_EGG = register(new BlockItem("turtle_egg", builder())); - public static final Item SNIFFER_EGG = register(new BlockItem("sniffer_egg", builder())); - public static final Item DEAD_TUBE_CORAL_BLOCK = register(new BlockItem("dead_tube_coral_block", builder())); - public static final Item DEAD_BRAIN_CORAL_BLOCK = register(new BlockItem("dead_brain_coral_block", builder())); - public static final Item DEAD_BUBBLE_CORAL_BLOCK = register(new BlockItem("dead_bubble_coral_block", builder())); - public static final Item DEAD_FIRE_CORAL_BLOCK = register(new BlockItem("dead_fire_coral_block", builder())); - public static final Item DEAD_HORN_CORAL_BLOCK = register(new BlockItem("dead_horn_coral_block", builder())); - public static final Item TUBE_CORAL_BLOCK = register(new BlockItem("tube_coral_block", builder())); - public static final Item BRAIN_CORAL_BLOCK = register(new BlockItem("brain_coral_block", builder())); - public static final Item BUBBLE_CORAL_BLOCK = register(new BlockItem("bubble_coral_block", builder())); - public static final Item FIRE_CORAL_BLOCK = register(new BlockItem("fire_coral_block", builder())); - public static final Item HORN_CORAL_BLOCK = register(new BlockItem("horn_coral_block", builder())); - public static final Item TUBE_CORAL = register(new BlockItem("tube_coral", builder())); - public static final Item BRAIN_CORAL = register(new BlockItem("brain_coral", builder())); - public static final Item BUBBLE_CORAL = register(new BlockItem("bubble_coral", builder())); - public static final Item FIRE_CORAL = register(new BlockItem("fire_coral", builder())); - public static final Item HORN_CORAL = register(new BlockItem("horn_coral", builder())); - public static final Item DEAD_BRAIN_CORAL = register(new BlockItem("dead_brain_coral", builder())); - public static final Item DEAD_BUBBLE_CORAL = register(new BlockItem("dead_bubble_coral", builder())); - public static final Item DEAD_FIRE_CORAL = register(new BlockItem("dead_fire_coral", builder())); - public static final Item DEAD_HORN_CORAL = register(new BlockItem("dead_horn_coral", builder())); - public static final Item DEAD_TUBE_CORAL = register(new BlockItem("dead_tube_coral", builder())); - public static final Item TUBE_CORAL_FAN = register(new BlockItem("tube_coral_fan", builder())); - public static final Item BRAIN_CORAL_FAN = register(new BlockItem("brain_coral_fan", builder())); - public static final Item BUBBLE_CORAL_FAN = register(new BlockItem("bubble_coral_fan", builder())); - public static final Item FIRE_CORAL_FAN = register(new BlockItem("fire_coral_fan", builder())); - public static final Item HORN_CORAL_FAN = register(new BlockItem("horn_coral_fan", builder())); - public static final Item DEAD_TUBE_CORAL_FAN = register(new BlockItem("dead_tube_coral_fan", builder())); - public static final Item DEAD_BRAIN_CORAL_FAN = register(new BlockItem("dead_brain_coral_fan", builder())); - public static final Item DEAD_BUBBLE_CORAL_FAN = register(new BlockItem("dead_bubble_coral_fan", builder())); - public static final Item DEAD_FIRE_CORAL_FAN = register(new BlockItem("dead_fire_coral_fan", builder())); - public static final Item DEAD_HORN_CORAL_FAN = register(new BlockItem("dead_horn_coral_fan", builder())); - public static final Item BLUE_ICE = register(new BlockItem("blue_ice", builder())); - public static final Item CONDUIT = register(new BlockItem("conduit", builder())); - public static final Item POLISHED_GRANITE_STAIRS = register(new BlockItem("polished_granite_stairs", builder())); - public static final Item SMOOTH_RED_SANDSTONE_STAIRS = register(new BlockItem("smooth_red_sandstone_stairs", builder())); - public static final Item MOSSY_STONE_BRICK_STAIRS = register(new BlockItem("mossy_stone_brick_stairs", builder())); - public static final Item POLISHED_DIORITE_STAIRS = register(new BlockItem("polished_diorite_stairs", builder())); - public static final Item MOSSY_COBBLESTONE_STAIRS = register(new BlockItem("mossy_cobblestone_stairs", builder())); - public static final Item END_STONE_BRICK_STAIRS = register(new BlockItem("end_stone_brick_stairs", builder())); - public static final Item STONE_STAIRS = register(new BlockItem("stone_stairs", builder())); - public static final Item SMOOTH_SANDSTONE_STAIRS = register(new BlockItem("smooth_sandstone_stairs", builder())); - public static final Item SMOOTH_QUARTZ_STAIRS = register(new BlockItem("smooth_quartz_stairs", builder())); - public static final Item GRANITE_STAIRS = register(new BlockItem("granite_stairs", builder())); - public static final Item ANDESITE_STAIRS = register(new BlockItem("andesite_stairs", builder())); - public static final Item RED_NETHER_BRICK_STAIRS = register(new BlockItem("red_nether_brick_stairs", builder())); - public static final Item POLISHED_ANDESITE_STAIRS = register(new BlockItem("polished_andesite_stairs", builder())); - public static final Item DIORITE_STAIRS = register(new BlockItem("diorite_stairs", builder())); - public static final Item COBBLED_DEEPSLATE_STAIRS = register(new BlockItem("cobbled_deepslate_stairs", builder())); - public static final Item POLISHED_DEEPSLATE_STAIRS = register(new BlockItem("polished_deepslate_stairs", builder())); - public static final Item DEEPSLATE_BRICK_STAIRS = register(new BlockItem("deepslate_brick_stairs", builder())); - public static final Item DEEPSLATE_TILE_STAIRS = register(new BlockItem("deepslate_tile_stairs", builder())); - public static final Item POLISHED_GRANITE_SLAB = register(new BlockItem("polished_granite_slab", builder())); - public static final Item SMOOTH_RED_SANDSTONE_SLAB = register(new BlockItem("smooth_red_sandstone_slab", builder())); - public static final Item MOSSY_STONE_BRICK_SLAB = register(new BlockItem("mossy_stone_brick_slab", builder())); - public static final Item POLISHED_DIORITE_SLAB = register(new BlockItem("polished_diorite_slab", builder())); - public static final Item MOSSY_COBBLESTONE_SLAB = register(new BlockItem("mossy_cobblestone_slab", builder())); - public static final Item END_STONE_BRICK_SLAB = register(new BlockItem("end_stone_brick_slab", builder())); - public static final Item SMOOTH_SANDSTONE_SLAB = register(new BlockItem("smooth_sandstone_slab", builder())); - public static final Item SMOOTH_QUARTZ_SLAB = register(new BlockItem("smooth_quartz_slab", builder())); - public static final Item GRANITE_SLAB = register(new BlockItem("granite_slab", builder())); - public static final Item ANDESITE_SLAB = register(new BlockItem("andesite_slab", builder())); - public static final Item RED_NETHER_BRICK_SLAB = register(new BlockItem("red_nether_brick_slab", builder())); - public static final Item POLISHED_ANDESITE_SLAB = register(new BlockItem("polished_andesite_slab", builder())); - public static final Item DIORITE_SLAB = register(new BlockItem("diorite_slab", builder())); - public static final Item COBBLED_DEEPSLATE_SLAB = register(new BlockItem("cobbled_deepslate_slab", builder())); - public static final Item POLISHED_DEEPSLATE_SLAB = register(new BlockItem("polished_deepslate_slab", builder())); - public static final Item DEEPSLATE_BRICK_SLAB = register(new BlockItem("deepslate_brick_slab", builder())); - public static final Item DEEPSLATE_TILE_SLAB = register(new BlockItem("deepslate_tile_slab", builder())); - public static final Item SCAFFOLDING = register(new BlockItem("scaffolding", builder())); - public static final Item REDSTONE = register(new BlockItem("redstone", builder())); - public static final Item REDSTONE_TORCH = register(new BlockItem("redstone_torch", builder())); - public static final Item REDSTONE_BLOCK = register(new BlockItem("redstone_block", builder())); - public static final Item REPEATER = register(new BlockItem("repeater", builder())); - public static final Item COMPARATOR = register(new BlockItem("comparator", builder())); - public static final Item PISTON = register(new BlockItem("piston", builder())); - public static final Item STICKY_PISTON = register(new BlockItem("sticky_piston", builder())); - public static final Item SLIME_BLOCK = register(new BlockItem("slime_block", builder())); - public static final Item HONEY_BLOCK = register(new BlockItem("honey_block", builder())); - public static final Item OBSERVER = register(new BlockItem("observer", builder())); - public static final Item HOPPER = register(new BlockItem("hopper", builder())); - public static final Item DISPENSER = register(new BlockItem("dispenser", builder())); - public static final Item DROPPER = register(new BlockItem("dropper", builder())); - public static final Item LECTERN = register(new BlockItem("lectern", builder())); - public static final Item TARGET = register(new BlockItem("target", builder())); - public static final Item LEVER = register(new BlockItem("lever", builder())); - public static final Item LIGHTNING_ROD = register(new BlockItem("lightning_rod", builder())); - public static final Item DAYLIGHT_DETECTOR = register(new BlockItem("daylight_detector", builder())); - public static final Item SCULK_SENSOR = register(new BlockItem("sculk_sensor", builder())); - public static final Item CALIBRATED_SCULK_SENSOR = register(new BlockItem("calibrated_sculk_sensor", builder())); - public static final Item TRIPWIRE_HOOK = register(new BlockItem("tripwire_hook", builder())); - public static final Item TRAPPED_CHEST = register(new BlockItem("trapped_chest", builder())); - public static final Item TNT = register(new BlockItem("tnt", builder())); - public static final Item REDSTONE_LAMP = register(new BlockItem("redstone_lamp", builder())); - public static final Item NOTE_BLOCK = register(new BlockItem("note_block", builder())); - public static final Item STONE_BUTTON = register(new BlockItem("stone_button", builder())); - public static final Item POLISHED_BLACKSTONE_BUTTON = register(new BlockItem("polished_blackstone_button", builder())); - public static final Item OAK_BUTTON = register(new BlockItem("oak_button", builder())); - public static final Item SPRUCE_BUTTON = register(new BlockItem("spruce_button", builder())); - public static final Item BIRCH_BUTTON = register(new BlockItem("birch_button", builder())); - public static final Item JUNGLE_BUTTON = register(new BlockItem("jungle_button", builder())); - public static final Item ACACIA_BUTTON = register(new BlockItem("acacia_button", builder())); - public static final Item CHERRY_BUTTON = register(new BlockItem("cherry_button", builder())); - public static final Item DARK_OAK_BUTTON = register(new BlockItem("dark_oak_button", builder())); - public static final Item MANGROVE_BUTTON = register(new BlockItem("mangrove_button", builder())); - public static final Item BAMBOO_BUTTON = register(new BlockItem("bamboo_button", builder())); - public static final Item CRIMSON_BUTTON = register(new BlockItem("crimson_button", builder())); - public static final Item WARPED_BUTTON = register(new BlockItem("warped_button", builder())); - public static final Item STONE_PRESSURE_PLATE = register(new BlockItem("stone_pressure_plate", builder())); - public static final Item POLISHED_BLACKSTONE_PRESSURE_PLATE = register(new BlockItem("polished_blackstone_pressure_plate", builder())); - public static final Item LIGHT_WEIGHTED_PRESSURE_PLATE = register(new BlockItem("light_weighted_pressure_plate", builder())); - public static final Item HEAVY_WEIGHTED_PRESSURE_PLATE = register(new BlockItem("heavy_weighted_pressure_plate", builder())); - public static final Item OAK_PRESSURE_PLATE = register(new BlockItem("oak_pressure_plate", builder())); - public static final Item SPRUCE_PRESSURE_PLATE = register(new BlockItem("spruce_pressure_plate", builder())); - public static final Item BIRCH_PRESSURE_PLATE = register(new BlockItem("birch_pressure_plate", builder())); - public static final Item JUNGLE_PRESSURE_PLATE = register(new BlockItem("jungle_pressure_plate", builder())); - public static final Item ACACIA_PRESSURE_PLATE = register(new BlockItem("acacia_pressure_plate", builder())); - public static final Item CHERRY_PRESSURE_PLATE = register(new BlockItem("cherry_pressure_plate", builder())); - public static final Item DARK_OAK_PRESSURE_PLATE = register(new BlockItem("dark_oak_pressure_plate", builder())); - public static final Item MANGROVE_PRESSURE_PLATE = register(new BlockItem("mangrove_pressure_plate", builder())); - public static final Item BAMBOO_PRESSURE_PLATE = register(new BlockItem("bamboo_pressure_plate", builder())); - public static final Item CRIMSON_PRESSURE_PLATE = register(new BlockItem("crimson_pressure_plate", builder())); - public static final Item WARPED_PRESSURE_PLATE = register(new BlockItem("warped_pressure_plate", builder())); - public static final Item IRON_DOOR = register(new BlockItem("iron_door", builder())); - public static final Item OAK_DOOR = register(new BlockItem("oak_door", builder())); - public static final Item SPRUCE_DOOR = register(new BlockItem("spruce_door", builder())); - public static final Item BIRCH_DOOR = register(new BlockItem("birch_door", builder())); - public static final Item JUNGLE_DOOR = register(new BlockItem("jungle_door", builder())); - public static final Item ACACIA_DOOR = register(new BlockItem("acacia_door", builder())); - public static final Item CHERRY_DOOR = register(new BlockItem("cherry_door", builder())); - public static final Item DARK_OAK_DOOR = register(new BlockItem("dark_oak_door", builder())); - public static final Item MANGROVE_DOOR = register(new BlockItem("mangrove_door", builder())); - public static final Item BAMBOO_DOOR = register(new BlockItem("bamboo_door", builder())); - public static final Item CRIMSON_DOOR = register(new BlockItem("crimson_door", builder())); - public static final Item WARPED_DOOR = register(new BlockItem("warped_door", builder())); - public static final Item COPPER_DOOR = register(new BlockItem("copper_door", builder())); - public static final Item EXPOSED_COPPER_DOOR = register(new BlockItem("exposed_copper_door", builder())); - public static final Item WEATHERED_COPPER_DOOR = register(new BlockItem("weathered_copper_door", builder())); - public static final Item OXIDIZED_COPPER_DOOR = register(new BlockItem("oxidized_copper_door", builder())); - public static final Item WAXED_COPPER_DOOR = register(new BlockItem("waxed_copper_door", builder())); - public static final Item WAXED_EXPOSED_COPPER_DOOR = register(new BlockItem("waxed_exposed_copper_door", builder())); - public static final Item WAXED_WEATHERED_COPPER_DOOR = register(new BlockItem("waxed_weathered_copper_door", builder())); - public static final Item WAXED_OXIDIZED_COPPER_DOOR = register(new BlockItem("waxed_oxidized_copper_door", builder())); - public static final Item IRON_TRAPDOOR = register(new BlockItem("iron_trapdoor", builder())); - public static final Item OAK_TRAPDOOR = register(new BlockItem("oak_trapdoor", builder())); - public static final Item SPRUCE_TRAPDOOR = register(new BlockItem("spruce_trapdoor", builder())); - public static final Item BIRCH_TRAPDOOR = register(new BlockItem("birch_trapdoor", builder())); - public static final Item JUNGLE_TRAPDOOR = register(new BlockItem("jungle_trapdoor", builder())); - public static final Item ACACIA_TRAPDOOR = register(new BlockItem("acacia_trapdoor", builder())); - public static final Item CHERRY_TRAPDOOR = register(new BlockItem("cherry_trapdoor", builder())); - public static final Item DARK_OAK_TRAPDOOR = register(new BlockItem("dark_oak_trapdoor", builder())); - public static final Item MANGROVE_TRAPDOOR = register(new BlockItem("mangrove_trapdoor", builder())); - public static final Item BAMBOO_TRAPDOOR = register(new BlockItem("bamboo_trapdoor", builder())); - public static final Item CRIMSON_TRAPDOOR = register(new BlockItem("crimson_trapdoor", builder())); - public static final Item WARPED_TRAPDOOR = register(new BlockItem("warped_trapdoor", builder())); - public static final Item COPPER_TRAPDOOR = register(new BlockItem("copper_trapdoor", builder())); - public static final Item EXPOSED_COPPER_TRAPDOOR = register(new BlockItem("exposed_copper_trapdoor", builder())); - public static final Item WEATHERED_COPPER_TRAPDOOR = register(new BlockItem("weathered_copper_trapdoor", builder())); - public static final Item OXIDIZED_COPPER_TRAPDOOR = register(new BlockItem("oxidized_copper_trapdoor", builder())); - public static final Item WAXED_COPPER_TRAPDOOR = register(new BlockItem("waxed_copper_trapdoor", builder())); - public static final Item WAXED_EXPOSED_COPPER_TRAPDOOR = register(new BlockItem("waxed_exposed_copper_trapdoor", builder())); - public static final Item WAXED_WEATHERED_COPPER_TRAPDOOR = register(new BlockItem("waxed_weathered_copper_trapdoor", builder())); - public static final Item WAXED_OXIDIZED_COPPER_TRAPDOOR = register(new BlockItem("waxed_oxidized_copper_trapdoor", builder())); - public static final Item OAK_FENCE_GATE = register(new BlockItem("oak_fence_gate", builder())); - public static final Item SPRUCE_FENCE_GATE = register(new BlockItem("spruce_fence_gate", builder())); - public static final Item BIRCH_FENCE_GATE = register(new BlockItem("birch_fence_gate", builder())); - public static final Item JUNGLE_FENCE_GATE = register(new BlockItem("jungle_fence_gate", builder())); - public static final Item ACACIA_FENCE_GATE = register(new BlockItem("acacia_fence_gate", builder())); - public static final Item CHERRY_FENCE_GATE = register(new BlockItem("cherry_fence_gate", builder())); - public static final Item DARK_OAK_FENCE_GATE = register(new BlockItem("dark_oak_fence_gate", builder())); - public static final Item MANGROVE_FENCE_GATE = register(new BlockItem("mangrove_fence_gate", builder())); - public static final Item BAMBOO_FENCE_GATE = register(new BlockItem("bamboo_fence_gate", builder())); - public static final Item CRIMSON_FENCE_GATE = register(new BlockItem("crimson_fence_gate", builder())); - public static final Item WARPED_FENCE_GATE = register(new BlockItem("warped_fence_gate", builder())); - public static final Item POWERED_RAIL = register(new BlockItem("powered_rail", builder())); - public static final Item DETECTOR_RAIL = register(new BlockItem("detector_rail", builder())); - public static final Item RAIL = register(new BlockItem("rail", builder())); - public static final Item ACTIVATOR_RAIL = register(new BlockItem("activator_rail", builder())); + public static final Item STONE = register(new BlockItem(builder(), Blocks.STONE)); + public static final Item GRANITE = register(new BlockItem(builder(), Blocks.GRANITE)); + public static final Item POLISHED_GRANITE = register(new BlockItem(builder(), Blocks.POLISHED_GRANITE)); + public static final Item DIORITE = register(new BlockItem(builder(), Blocks.DIORITE)); + public static final Item POLISHED_DIORITE = register(new BlockItem(builder(), Blocks.POLISHED_DIORITE)); + public static final Item ANDESITE = register(new BlockItem(builder(), Blocks.ANDESITE)); + public static final Item POLISHED_ANDESITE = register(new BlockItem(builder(), Blocks.POLISHED_ANDESITE)); + public static final Item DEEPSLATE = register(new BlockItem(builder(), Blocks.DEEPSLATE)); + public static final Item COBBLED_DEEPSLATE = register(new BlockItem(builder(), Blocks.COBBLED_DEEPSLATE)); + public static final Item POLISHED_DEEPSLATE = register(new BlockItem(builder(), Blocks.POLISHED_DEEPSLATE)); + public static final Item CALCITE = register(new BlockItem(builder(), Blocks.CALCITE)); + public static final Item TUFF = register(new BlockItem(builder(), Blocks.TUFF)); + public static final Item TUFF_SLAB = register(new BlockItem(builder(), Blocks.TUFF_SLAB)); + public static final Item TUFF_STAIRS = register(new BlockItem(builder(), Blocks.TUFF_STAIRS)); + public static final Item TUFF_WALL = register(new BlockItem(builder(), Blocks.TUFF_WALL)); + public static final Item CHISELED_TUFF = register(new BlockItem(builder(), Blocks.CHISELED_TUFF)); + public static final Item POLISHED_TUFF = register(new BlockItem(builder(), Blocks.POLISHED_TUFF)); + public static final Item POLISHED_TUFF_SLAB = register(new BlockItem(builder(), Blocks.POLISHED_TUFF_SLAB)); + public static final Item POLISHED_TUFF_STAIRS = register(new BlockItem(builder(), Blocks.POLISHED_TUFF_STAIRS)); + public static final Item POLISHED_TUFF_WALL = register(new BlockItem(builder(), Blocks.POLISHED_TUFF_WALL)); + public static final Item TUFF_BRICKS = register(new BlockItem(builder(), Blocks.TUFF_BRICKS)); + public static final Item TUFF_BRICK_SLAB = register(new BlockItem(builder(), Blocks.TUFF_BRICK_SLAB)); + public static final Item TUFF_BRICK_STAIRS = register(new BlockItem(builder(), Blocks.TUFF_BRICK_STAIRS)); + public static final Item TUFF_BRICK_WALL = register(new BlockItem(builder(), Blocks.TUFF_BRICK_WALL)); + public static final Item CHISELED_TUFF_BRICKS = register(new BlockItem(builder(), Blocks.CHISELED_TUFF_BRICKS)); + public static final Item DRIPSTONE_BLOCK = register(new BlockItem(builder(), Blocks.DRIPSTONE_BLOCK)); + public static final Item GRASS_BLOCK = register(new BlockItem(builder(), Blocks.GRASS_BLOCK)); + public static final Item DIRT = register(new BlockItem(builder(), Blocks.DIRT)); + public static final Item COARSE_DIRT = register(new BlockItem(builder(), Blocks.COARSE_DIRT)); + public static final Item PODZOL = register(new BlockItem(builder(), Blocks.PODZOL)); + public static final Item ROOTED_DIRT = register(new BlockItem(builder(), Blocks.ROOTED_DIRT)); + public static final Item MUD = register(new BlockItem(builder(), Blocks.MUD)); + public static final Item CRIMSON_NYLIUM = register(new BlockItem(builder(), Blocks.CRIMSON_NYLIUM)); + public static final Item WARPED_NYLIUM = register(new BlockItem(builder(), Blocks.WARPED_NYLIUM)); + public static final Item COBBLESTONE = register(new BlockItem(builder(), Blocks.COBBLESTONE)); + public static final Item OAK_PLANKS = register(new BlockItem(builder(), Blocks.OAK_PLANKS)); + public static final Item SPRUCE_PLANKS = register(new BlockItem(builder(), Blocks.SPRUCE_PLANKS)); + public static final Item BIRCH_PLANKS = register(new BlockItem(builder(), Blocks.BIRCH_PLANKS)); + public static final Item JUNGLE_PLANKS = register(new BlockItem(builder(), Blocks.JUNGLE_PLANKS)); + public static final Item ACACIA_PLANKS = register(new BlockItem(builder(), Blocks.ACACIA_PLANKS)); + public static final Item CHERRY_PLANKS = register(new BlockItem(builder(), Blocks.CHERRY_PLANKS)); + public static final Item DARK_OAK_PLANKS = register(new BlockItem(builder(), Blocks.DARK_OAK_PLANKS)); + public static final Item MANGROVE_PLANKS = register(new BlockItem(builder(), Blocks.MANGROVE_PLANKS)); + public static final Item BAMBOO_PLANKS = register(new BlockItem(builder(), Blocks.BAMBOO_PLANKS)); + public static final Item CRIMSON_PLANKS = register(new BlockItem(builder(), Blocks.CRIMSON_PLANKS)); + public static final Item WARPED_PLANKS = register(new BlockItem(builder(), Blocks.WARPED_PLANKS)); + public static final Item BAMBOO_MOSAIC = register(new BlockItem(builder(), Blocks.BAMBOO_MOSAIC)); + public static final Item OAK_SAPLING = register(new BlockItem(builder(), Blocks.OAK_SAPLING)); + public static final Item SPRUCE_SAPLING = register(new BlockItem(builder(), Blocks.SPRUCE_SAPLING)); + public static final Item BIRCH_SAPLING = register(new BlockItem(builder(), Blocks.BIRCH_SAPLING)); + public static final Item JUNGLE_SAPLING = register(new BlockItem(builder(), Blocks.JUNGLE_SAPLING)); + public static final Item ACACIA_SAPLING = register(new BlockItem(builder(), Blocks.ACACIA_SAPLING)); + public static final Item CHERRY_SAPLING = register(new BlockItem(builder(), Blocks.CHERRY_SAPLING)); + public static final Item DARK_OAK_SAPLING = register(new BlockItem(builder(), Blocks.DARK_OAK_SAPLING)); + public static final Item MANGROVE_PROPAGULE = register(new BlockItem(builder(), Blocks.MANGROVE_PROPAGULE)); + public static final Item BEDROCK = register(new BlockItem(builder(), Blocks.BEDROCK)); + public static final Item SAND = register(new BlockItem(builder(), Blocks.SAND)); + public static final Item SUSPICIOUS_SAND = register(new BlockItem(builder(), Blocks.SUSPICIOUS_SAND)); + public static final Item SUSPICIOUS_GRAVEL = register(new BlockItem(builder(), Blocks.SUSPICIOUS_GRAVEL)); + public static final Item RED_SAND = register(new BlockItem(builder(), Blocks.RED_SAND)); + public static final Item GRAVEL = register(new BlockItem(builder(), Blocks.GRAVEL)); + public static final Item COAL_ORE = register(new BlockItem(builder(), Blocks.COAL_ORE)); + public static final Item DEEPSLATE_COAL_ORE = register(new BlockItem(builder(), Blocks.DEEPSLATE_COAL_ORE)); + public static final Item IRON_ORE = register(new BlockItem(builder(), Blocks.IRON_ORE)); + public static final Item DEEPSLATE_IRON_ORE = register(new BlockItem(builder(), Blocks.DEEPSLATE_IRON_ORE)); + public static final Item COPPER_ORE = register(new BlockItem(builder(), Blocks.COPPER_ORE)); + public static final Item DEEPSLATE_COPPER_ORE = register(new BlockItem(builder(), Blocks.DEEPSLATE_COPPER_ORE)); + public static final Item GOLD_ORE = register(new BlockItem(builder(), Blocks.GOLD_ORE)); + public static final Item DEEPSLATE_GOLD_ORE = register(new BlockItem(builder(), Blocks.DEEPSLATE_GOLD_ORE)); + public static final Item REDSTONE_ORE = register(new BlockItem(builder(), Blocks.REDSTONE_ORE)); + public static final Item DEEPSLATE_REDSTONE_ORE = register(new BlockItem(builder(), Blocks.DEEPSLATE_REDSTONE_ORE)); + public static final Item EMERALD_ORE = register(new BlockItem(builder(), Blocks.EMERALD_ORE)); + public static final Item DEEPSLATE_EMERALD_ORE = register(new BlockItem(builder(), Blocks.DEEPSLATE_EMERALD_ORE)); + public static final Item LAPIS_ORE = register(new BlockItem(builder(), Blocks.LAPIS_ORE)); + public static final Item DEEPSLATE_LAPIS_ORE = register(new BlockItem(builder(), Blocks.DEEPSLATE_LAPIS_ORE)); + public static final Item DIAMOND_ORE = register(new BlockItem(builder(), Blocks.DIAMOND_ORE)); + public static final Item DEEPSLATE_DIAMOND_ORE = register(new BlockItem(builder(), Blocks.DEEPSLATE_DIAMOND_ORE)); + public static final Item NETHER_GOLD_ORE = register(new BlockItem(builder(), Blocks.NETHER_GOLD_ORE)); + public static final Item NETHER_QUARTZ_ORE = register(new BlockItem(builder(), Blocks.NETHER_QUARTZ_ORE)); + public static final Item ANCIENT_DEBRIS = register(new BlockItem(builder(), Blocks.ANCIENT_DEBRIS)); + public static final Item COAL_BLOCK = register(new BlockItem(builder(), Blocks.COAL_BLOCK)); + public static final Item RAW_IRON_BLOCK = register(new BlockItem(builder(), Blocks.RAW_IRON_BLOCK)); + public static final Item RAW_COPPER_BLOCK = register(new BlockItem(builder(), Blocks.RAW_COPPER_BLOCK)); + public static final Item RAW_GOLD_BLOCK = register(new BlockItem(builder(), Blocks.RAW_GOLD_BLOCK)); + public static final Item HEAVY_CORE = register(new BlockItem(builder(), Blocks.HEAVY_CORE)); + public static final Item AMETHYST_BLOCK = register(new BlockItem(builder(), Blocks.AMETHYST_BLOCK)); + public static final Item BUDDING_AMETHYST = register(new BlockItem(builder(), Blocks.BUDDING_AMETHYST)); + public static final Item IRON_BLOCK = register(new BlockItem(builder(), Blocks.IRON_BLOCK)); + public static final Item COPPER_BLOCK = register(new BlockItem(builder(), Blocks.COPPER_BLOCK)); + public static final Item GOLD_BLOCK = register(new BlockItem(builder(), Blocks.GOLD_BLOCK)); + public static final Item DIAMOND_BLOCK = register(new BlockItem(builder(), Blocks.DIAMOND_BLOCK)); + public static final Item NETHERITE_BLOCK = register(new BlockItem(builder(), Blocks.NETHERITE_BLOCK)); + public static final Item EXPOSED_COPPER = register(new BlockItem(builder(), Blocks.EXPOSED_COPPER)); + public static final Item WEATHERED_COPPER = register(new BlockItem(builder(), Blocks.WEATHERED_COPPER)); + public static final Item OXIDIZED_COPPER = register(new BlockItem(builder(), Blocks.OXIDIZED_COPPER)); + public static final Item CHISELED_COPPER = register(new BlockItem(builder(), Blocks.CHISELED_COPPER)); + public static final Item EXPOSED_CHISELED_COPPER = register(new BlockItem(builder(), Blocks.EXPOSED_CHISELED_COPPER)); + public static final Item WEATHERED_CHISELED_COPPER = register(new BlockItem(builder(), Blocks.WEATHERED_CHISELED_COPPER)); + public static final Item OXIDIZED_CHISELED_COPPER = register(new BlockItem(builder(), Blocks.OXIDIZED_CHISELED_COPPER)); + public static final Item CUT_COPPER = register(new BlockItem(builder(), Blocks.CUT_COPPER)); + public static final Item EXPOSED_CUT_COPPER = register(new BlockItem(builder(), Blocks.EXPOSED_CUT_COPPER)); + public static final Item WEATHERED_CUT_COPPER = register(new BlockItem(builder(), Blocks.WEATHERED_CUT_COPPER)); + public static final Item OXIDIZED_CUT_COPPER = register(new BlockItem(builder(), Blocks.OXIDIZED_CUT_COPPER)); + public static final Item CUT_COPPER_STAIRS = register(new BlockItem(builder(), Blocks.CUT_COPPER_STAIRS)); + public static final Item EXPOSED_CUT_COPPER_STAIRS = register(new BlockItem(builder(), Blocks.EXPOSED_CUT_COPPER_STAIRS)); + public static final Item WEATHERED_CUT_COPPER_STAIRS = register(new BlockItem(builder(), Blocks.WEATHERED_CUT_COPPER_STAIRS)); + public static final Item OXIDIZED_CUT_COPPER_STAIRS = register(new BlockItem(builder(), Blocks.OXIDIZED_CUT_COPPER_STAIRS)); + public static final Item CUT_COPPER_SLAB = register(new BlockItem(builder(), Blocks.CUT_COPPER_SLAB)); + public static final Item EXPOSED_CUT_COPPER_SLAB = register(new BlockItem(builder(), Blocks.EXPOSED_CUT_COPPER_SLAB)); + public static final Item WEATHERED_CUT_COPPER_SLAB = register(new BlockItem(builder(), Blocks.WEATHERED_CUT_COPPER_SLAB)); + public static final Item OXIDIZED_CUT_COPPER_SLAB = register(new BlockItem(builder(), Blocks.OXIDIZED_CUT_COPPER_SLAB)); + public static final Item WAXED_COPPER_BLOCK = register(new BlockItem(builder(), Blocks.WAXED_COPPER_BLOCK)); + public static final Item WAXED_EXPOSED_COPPER = register(new BlockItem(builder(), Blocks.WAXED_EXPOSED_COPPER)); + public static final Item WAXED_WEATHERED_COPPER = register(new BlockItem(builder(), Blocks.WAXED_WEATHERED_COPPER)); + public static final Item WAXED_OXIDIZED_COPPER = register(new BlockItem(builder(), Blocks.WAXED_OXIDIZED_COPPER)); + public static final Item WAXED_CHISELED_COPPER = register(new BlockItem(builder(), Blocks.WAXED_CHISELED_COPPER)); + public static final Item WAXED_EXPOSED_CHISELED_COPPER = register(new BlockItem(builder(), Blocks.WAXED_EXPOSED_CHISELED_COPPER)); + public static final Item WAXED_WEATHERED_CHISELED_COPPER = register(new BlockItem(builder(), Blocks.WAXED_WEATHERED_CHISELED_COPPER)); + public static final Item WAXED_OXIDIZED_CHISELED_COPPER = register(new BlockItem(builder(), Blocks.WAXED_OXIDIZED_CHISELED_COPPER)); + public static final Item WAXED_CUT_COPPER = register(new BlockItem(builder(), Blocks.WAXED_CUT_COPPER)); + public static final Item WAXED_EXPOSED_CUT_COPPER = register(new BlockItem(builder(), Blocks.WAXED_EXPOSED_CUT_COPPER)); + public static final Item WAXED_WEATHERED_CUT_COPPER = register(new BlockItem(builder(), Blocks.WAXED_WEATHERED_CUT_COPPER)); + public static final Item WAXED_OXIDIZED_CUT_COPPER = register(new BlockItem(builder(), Blocks.WAXED_OXIDIZED_CUT_COPPER)); + public static final Item WAXED_CUT_COPPER_STAIRS = register(new BlockItem(builder(), Blocks.WAXED_CUT_COPPER_STAIRS)); + public static final Item WAXED_EXPOSED_CUT_COPPER_STAIRS = register(new BlockItem(builder(), Blocks.WAXED_EXPOSED_CUT_COPPER_STAIRS)); + public static final Item WAXED_WEATHERED_CUT_COPPER_STAIRS = register(new BlockItem(builder(), Blocks.WAXED_WEATHERED_CUT_COPPER_STAIRS)); + public static final Item WAXED_OXIDIZED_CUT_COPPER_STAIRS = register(new BlockItem(builder(), Blocks.WAXED_OXIDIZED_CUT_COPPER_STAIRS)); + public static final Item WAXED_CUT_COPPER_SLAB = register(new BlockItem(builder(), Blocks.WAXED_CUT_COPPER_SLAB)); + public static final Item WAXED_EXPOSED_CUT_COPPER_SLAB = register(new BlockItem(builder(), Blocks.WAXED_EXPOSED_CUT_COPPER_SLAB)); + public static final Item WAXED_WEATHERED_CUT_COPPER_SLAB = register(new BlockItem(builder(), Blocks.WAXED_WEATHERED_CUT_COPPER_SLAB)); + public static final Item WAXED_OXIDIZED_CUT_COPPER_SLAB = register(new BlockItem(builder(), Blocks.WAXED_OXIDIZED_CUT_COPPER_SLAB)); + public static final Item OAK_LOG = register(new BlockItem(builder(), Blocks.OAK_LOG)); + public static final Item SPRUCE_LOG = register(new BlockItem(builder(), Blocks.SPRUCE_LOG)); + public static final Item BIRCH_LOG = register(new BlockItem(builder(), Blocks.BIRCH_LOG)); + public static final Item JUNGLE_LOG = register(new BlockItem(builder(), Blocks.JUNGLE_LOG)); + public static final Item ACACIA_LOG = register(new BlockItem(builder(), Blocks.ACACIA_LOG)); + public static final Item CHERRY_LOG = register(new BlockItem(builder(), Blocks.CHERRY_LOG)); + public static final Item DARK_OAK_LOG = register(new BlockItem(builder(), Blocks.DARK_OAK_LOG)); + public static final Item MANGROVE_LOG = register(new BlockItem(builder(), Blocks.MANGROVE_LOG)); + public static final Item MANGROVE_ROOTS = register(new BlockItem(builder(), Blocks.MANGROVE_ROOTS)); + public static final Item MUDDY_MANGROVE_ROOTS = register(new BlockItem(builder(), Blocks.MUDDY_MANGROVE_ROOTS)); + public static final Item CRIMSON_STEM = register(new BlockItem(builder(), Blocks.CRIMSON_STEM)); + public static final Item WARPED_STEM = register(new BlockItem(builder(), Blocks.WARPED_STEM)); + public static final Item BAMBOO_BLOCK = register(new BlockItem(builder(), Blocks.BAMBOO_BLOCK)); + public static final Item STRIPPED_OAK_LOG = register(new BlockItem(builder(), Blocks.STRIPPED_OAK_LOG)); + public static final Item STRIPPED_SPRUCE_LOG = register(new BlockItem(builder(), Blocks.STRIPPED_SPRUCE_LOG)); + public static final Item STRIPPED_BIRCH_LOG = register(new BlockItem(builder(), Blocks.STRIPPED_BIRCH_LOG)); + public static final Item STRIPPED_JUNGLE_LOG = register(new BlockItem(builder(), Blocks.STRIPPED_JUNGLE_LOG)); + public static final Item STRIPPED_ACACIA_LOG = register(new BlockItem(builder(), Blocks.STRIPPED_ACACIA_LOG)); + public static final Item STRIPPED_CHERRY_LOG = register(new BlockItem(builder(), Blocks.STRIPPED_CHERRY_LOG)); + public static final Item STRIPPED_DARK_OAK_LOG = register(new BlockItem(builder(), Blocks.STRIPPED_DARK_OAK_LOG)); + public static final Item STRIPPED_MANGROVE_LOG = register(new BlockItem(builder(), Blocks.STRIPPED_MANGROVE_LOG)); + public static final Item STRIPPED_CRIMSON_STEM = register(new BlockItem(builder(), Blocks.STRIPPED_CRIMSON_STEM)); + public static final Item STRIPPED_WARPED_STEM = register(new BlockItem(builder(), Blocks.STRIPPED_WARPED_STEM)); + public static final Item STRIPPED_OAK_WOOD = register(new BlockItem(builder(), Blocks.STRIPPED_OAK_WOOD)); + public static final Item STRIPPED_SPRUCE_WOOD = register(new BlockItem(builder(), Blocks.STRIPPED_SPRUCE_WOOD)); + public static final Item STRIPPED_BIRCH_WOOD = register(new BlockItem(builder(), Blocks.STRIPPED_BIRCH_WOOD)); + public static final Item STRIPPED_JUNGLE_WOOD = register(new BlockItem(builder(), Blocks.STRIPPED_JUNGLE_WOOD)); + public static final Item STRIPPED_ACACIA_WOOD = register(new BlockItem(builder(), Blocks.STRIPPED_ACACIA_WOOD)); + public static final Item STRIPPED_CHERRY_WOOD = register(new BlockItem(builder(), Blocks.STRIPPED_CHERRY_WOOD)); + public static final Item STRIPPED_DARK_OAK_WOOD = register(new BlockItem(builder(), Blocks.STRIPPED_DARK_OAK_WOOD)); + public static final Item STRIPPED_MANGROVE_WOOD = register(new BlockItem(builder(), Blocks.STRIPPED_MANGROVE_WOOD)); + public static final Item STRIPPED_CRIMSON_HYPHAE = register(new BlockItem(builder(), Blocks.STRIPPED_CRIMSON_HYPHAE)); + public static final Item STRIPPED_WARPED_HYPHAE = register(new BlockItem(builder(), Blocks.STRIPPED_WARPED_HYPHAE)); + public static final Item STRIPPED_BAMBOO_BLOCK = register(new BlockItem(builder(), Blocks.STRIPPED_BAMBOO_BLOCK)); + public static final Item OAK_WOOD = register(new BlockItem(builder(), Blocks.OAK_WOOD)); + public static final Item SPRUCE_WOOD = register(new BlockItem(builder(), Blocks.SPRUCE_WOOD)); + public static final Item BIRCH_WOOD = register(new BlockItem(builder(), Blocks.BIRCH_WOOD)); + public static final Item JUNGLE_WOOD = register(new BlockItem(builder(), Blocks.JUNGLE_WOOD)); + public static final Item ACACIA_WOOD = register(new BlockItem(builder(), Blocks.ACACIA_WOOD)); + public static final Item CHERRY_WOOD = register(new BlockItem(builder(), Blocks.CHERRY_WOOD)); + public static final Item DARK_OAK_WOOD = register(new BlockItem(builder(), Blocks.DARK_OAK_WOOD)); + public static final Item MANGROVE_WOOD = register(new BlockItem(builder(), Blocks.MANGROVE_WOOD)); + public static final Item CRIMSON_HYPHAE = register(new BlockItem(builder(), Blocks.CRIMSON_HYPHAE)); + public static final Item WARPED_HYPHAE = register(new BlockItem(builder(), Blocks.WARPED_HYPHAE)); + public static final Item OAK_LEAVES = register(new BlockItem(builder(), Blocks.OAK_LEAVES)); + public static final Item SPRUCE_LEAVES = register(new BlockItem(builder(), Blocks.SPRUCE_LEAVES)); + public static final Item BIRCH_LEAVES = register(new BlockItem(builder(), Blocks.BIRCH_LEAVES)); + public static final Item JUNGLE_LEAVES = register(new BlockItem(builder(), Blocks.JUNGLE_LEAVES)); + public static final Item ACACIA_LEAVES = register(new BlockItem(builder(), Blocks.ACACIA_LEAVES)); + public static final Item CHERRY_LEAVES = register(new BlockItem(builder(), Blocks.CHERRY_LEAVES)); + public static final Item DARK_OAK_LEAVES = register(new BlockItem(builder(), Blocks.DARK_OAK_LEAVES)); + public static final Item MANGROVE_LEAVES = register(new BlockItem(builder(), Blocks.MANGROVE_LEAVES)); + public static final Item AZALEA_LEAVES = register(new BlockItem(builder(), Blocks.AZALEA_LEAVES)); + public static final Item FLOWERING_AZALEA_LEAVES = register(new BlockItem(builder(), Blocks.FLOWERING_AZALEA_LEAVES)); + public static final Item SPONGE = register(new BlockItem(builder(), Blocks.SPONGE)); + public static final Item WET_SPONGE = register(new BlockItem(builder(), Blocks.WET_SPONGE)); + public static final Item GLASS = register(new BlockItem(builder(), Blocks.GLASS)); + public static final Item TINTED_GLASS = register(new BlockItem(builder(), Blocks.TINTED_GLASS)); + public static final Item LAPIS_BLOCK = register(new BlockItem(builder(), Blocks.LAPIS_BLOCK)); + public static final Item SANDSTONE = register(new BlockItem(builder(), Blocks.SANDSTONE)); + public static final Item CHISELED_SANDSTONE = register(new BlockItem(builder(), Blocks.CHISELED_SANDSTONE)); + public static final Item CUT_SANDSTONE = register(new BlockItem(builder(), Blocks.CUT_SANDSTONE)); + public static final Item COBWEB = register(new BlockItem(builder(), Blocks.COBWEB)); + public static final Item SHORT_GRASS = register(new BlockItem(builder(), Blocks.SHORT_GRASS)); + public static final Item FERN = register(new BlockItem(builder(), Blocks.FERN)); + public static final Item AZALEA = register(new BlockItem(builder(), Blocks.AZALEA)); + public static final Item FLOWERING_AZALEA = register(new BlockItem(builder(), Blocks.FLOWERING_AZALEA)); + public static final Item DEAD_BUSH = register(new BlockItem(builder(), Blocks.DEAD_BUSH)); + public static final Item SEAGRASS = register(new BlockItem(builder(), Blocks.SEAGRASS)); + public static final Item SEA_PICKLE = register(new BlockItem(builder(), Blocks.SEA_PICKLE)); + public static final Item WHITE_WOOL = register(new BlockItem(builder(), Blocks.WHITE_WOOL)); + public static final Item ORANGE_WOOL = register(new BlockItem(builder(), Blocks.ORANGE_WOOL)); + public static final Item MAGENTA_WOOL = register(new BlockItem(builder(), Blocks.MAGENTA_WOOL)); + public static final Item LIGHT_BLUE_WOOL = register(new BlockItem(builder(), Blocks.LIGHT_BLUE_WOOL)); + public static final Item YELLOW_WOOL = register(new BlockItem(builder(), Blocks.YELLOW_WOOL)); + public static final Item LIME_WOOL = register(new BlockItem(builder(), Blocks.LIME_WOOL)); + public static final Item PINK_WOOL = register(new BlockItem(builder(), Blocks.PINK_WOOL)); + public static final Item GRAY_WOOL = register(new BlockItem(builder(), Blocks.GRAY_WOOL)); + public static final Item LIGHT_GRAY_WOOL = register(new BlockItem(builder(), Blocks.LIGHT_GRAY_WOOL)); + public static final Item CYAN_WOOL = register(new BlockItem(builder(), Blocks.CYAN_WOOL)); + public static final Item PURPLE_WOOL = register(new BlockItem(builder(), Blocks.PURPLE_WOOL)); + public static final Item BLUE_WOOL = register(new BlockItem(builder(), Blocks.BLUE_WOOL)); + public static final Item BROWN_WOOL = register(new BlockItem(builder(), Blocks.BROWN_WOOL)); + public static final Item GREEN_WOOL = register(new BlockItem(builder(), Blocks.GREEN_WOOL)); + public static final Item RED_WOOL = register(new BlockItem(builder(), Blocks.RED_WOOL)); + public static final Item BLACK_WOOL = register(new BlockItem(builder(), Blocks.BLACK_WOOL)); + public static final Item DANDELION = register(new BlockItem(builder(), Blocks.DANDELION)); + public static final Item POPPY = register(new BlockItem(builder(), Blocks.POPPY)); + public static final Item BLUE_ORCHID = register(new BlockItem(builder(), Blocks.BLUE_ORCHID)); + public static final Item ALLIUM = register(new BlockItem(builder(), Blocks.ALLIUM)); + public static final Item AZURE_BLUET = register(new BlockItem(builder(), Blocks.AZURE_BLUET)); + public static final Item RED_TULIP = register(new BlockItem(builder(), Blocks.RED_TULIP)); + public static final Item ORANGE_TULIP = register(new BlockItem(builder(), Blocks.ORANGE_TULIP)); + public static final Item WHITE_TULIP = register(new BlockItem(builder(), Blocks.WHITE_TULIP)); + public static final Item PINK_TULIP = register(new BlockItem(builder(), Blocks.PINK_TULIP)); + public static final Item OXEYE_DAISY = register(new BlockItem(builder(), Blocks.OXEYE_DAISY)); + public static final Item CORNFLOWER = register(new BlockItem(builder(), Blocks.CORNFLOWER)); + public static final Item LILY_OF_THE_VALLEY = register(new BlockItem(builder(), Blocks.LILY_OF_THE_VALLEY)); + public static final Item WITHER_ROSE = register(new BlockItem(builder(), Blocks.WITHER_ROSE)); + public static final Item TORCHFLOWER = register(new BlockItem(builder(), Blocks.TORCHFLOWER)); + public static final Item PITCHER_PLANT = register(new BlockItem(builder(), Blocks.PITCHER_PLANT)); + public static final Item SPORE_BLOSSOM = register(new BlockItem(builder(), Blocks.SPORE_BLOSSOM)); + public static final Item BROWN_MUSHROOM = register(new BlockItem(builder(), Blocks.BROWN_MUSHROOM)); + public static final Item RED_MUSHROOM = register(new BlockItem(builder(), Blocks.RED_MUSHROOM)); + public static final Item CRIMSON_FUNGUS = register(new BlockItem(builder(), Blocks.CRIMSON_FUNGUS)); + public static final Item WARPED_FUNGUS = register(new BlockItem(builder(), Blocks.WARPED_FUNGUS)); + public static final Item CRIMSON_ROOTS = register(new BlockItem(builder(), Blocks.CRIMSON_ROOTS)); + public static final Item WARPED_ROOTS = register(new BlockItem(builder(), Blocks.WARPED_ROOTS)); + public static final Item NETHER_SPROUTS = register(new BlockItem(builder(), Blocks.NETHER_SPROUTS)); + public static final Item WEEPING_VINES = register(new BlockItem(builder(), Blocks.WEEPING_VINES)); + public static final Item TWISTING_VINES = register(new BlockItem(builder(), Blocks.TWISTING_VINES)); + public static final Item SUGAR_CANE = register(new BlockItem(builder(), Blocks.SUGAR_CANE)); + public static final Item KELP = register(new BlockItem(builder(), Blocks.KELP)); + public static final Item MOSS_CARPET = register(new BlockItem(builder(), Blocks.MOSS_CARPET)); + public static final Item PINK_PETALS = register(new BlockItem(builder(), Blocks.PINK_PETALS)); + public static final Item MOSS_BLOCK = register(new BlockItem(builder(), Blocks.MOSS_BLOCK)); + public static final Item HANGING_ROOTS = register(new BlockItem(builder(), Blocks.HANGING_ROOTS)); + public static final Item BIG_DRIPLEAF = register(new BlockItem(builder(), Blocks.BIG_DRIPLEAF, Blocks.BIG_DRIPLEAF_STEM)); + public static final Item SMALL_DRIPLEAF = register(new BlockItem(builder(), Blocks.SMALL_DRIPLEAF)); + public static final Item BAMBOO = register(new BlockItem(builder(), Blocks.BAMBOO)); + public static final Item OAK_SLAB = register(new BlockItem(builder(), Blocks.OAK_SLAB)); + public static final Item SPRUCE_SLAB = register(new BlockItem(builder(), Blocks.SPRUCE_SLAB)); + public static final Item BIRCH_SLAB = register(new BlockItem(builder(), Blocks.BIRCH_SLAB)); + public static final Item JUNGLE_SLAB = register(new BlockItem(builder(), Blocks.JUNGLE_SLAB)); + public static final Item ACACIA_SLAB = register(new BlockItem(builder(), Blocks.ACACIA_SLAB)); + public static final Item CHERRY_SLAB = register(new BlockItem(builder(), Blocks.CHERRY_SLAB)); + public static final Item DARK_OAK_SLAB = register(new BlockItem(builder(), Blocks.DARK_OAK_SLAB)); + public static final Item MANGROVE_SLAB = register(new BlockItem(builder(), Blocks.MANGROVE_SLAB)); + public static final Item BAMBOO_SLAB = register(new BlockItem(builder(), Blocks.BAMBOO_SLAB)); + public static final Item BAMBOO_MOSAIC_SLAB = register(new BlockItem(builder(), Blocks.BAMBOO_MOSAIC_SLAB)); + public static final Item CRIMSON_SLAB = register(new BlockItem(builder(), Blocks.CRIMSON_SLAB)); + public static final Item WARPED_SLAB = register(new BlockItem(builder(), Blocks.WARPED_SLAB)); + public static final Item STONE_SLAB = register(new BlockItem(builder(), Blocks.STONE_SLAB)); + public static final Item SMOOTH_STONE_SLAB = register(new BlockItem(builder(), Blocks.SMOOTH_STONE_SLAB)); + public static final Item SANDSTONE_SLAB = register(new BlockItem(builder(), Blocks.SANDSTONE_SLAB)); + public static final Item CUT_SANDSTONE_SLAB = register(new BlockItem(builder(), Blocks.CUT_SANDSTONE_SLAB)); + public static final Item PETRIFIED_OAK_SLAB = register(new BlockItem(builder(), Blocks.PETRIFIED_OAK_SLAB)); + public static final Item COBBLESTONE_SLAB = register(new BlockItem(builder(), Blocks.COBBLESTONE_SLAB)); + public static final Item BRICK_SLAB = register(new BlockItem(builder(), Blocks.BRICK_SLAB)); + public static final Item STONE_BRICK_SLAB = register(new BlockItem(builder(), Blocks.STONE_BRICK_SLAB)); + public static final Item MUD_BRICK_SLAB = register(new BlockItem(builder(), Blocks.MUD_BRICK_SLAB)); + public static final Item NETHER_BRICK_SLAB = register(new BlockItem(builder(), Blocks.NETHER_BRICK_SLAB)); + public static final Item QUARTZ_SLAB = register(new BlockItem(builder(), Blocks.QUARTZ_SLAB)); + public static final Item RED_SANDSTONE_SLAB = register(new BlockItem(builder(), Blocks.RED_SANDSTONE_SLAB)); + public static final Item CUT_RED_SANDSTONE_SLAB = register(new BlockItem(builder(), Blocks.CUT_RED_SANDSTONE_SLAB)); + public static final Item PURPUR_SLAB = register(new BlockItem(builder(), Blocks.PURPUR_SLAB)); + public static final Item PRISMARINE_SLAB = register(new BlockItem(builder(), Blocks.PRISMARINE_SLAB)); + public static final Item PRISMARINE_BRICK_SLAB = register(new BlockItem(builder(), Blocks.PRISMARINE_BRICK_SLAB)); + public static final Item DARK_PRISMARINE_SLAB = register(new BlockItem(builder(), Blocks.DARK_PRISMARINE_SLAB)); + public static final Item SMOOTH_QUARTZ = register(new BlockItem(builder(), Blocks.SMOOTH_QUARTZ)); + public static final Item SMOOTH_RED_SANDSTONE = register(new BlockItem(builder(), Blocks.SMOOTH_RED_SANDSTONE)); + public static final Item SMOOTH_SANDSTONE = register(new BlockItem(builder(), Blocks.SMOOTH_SANDSTONE)); + public static final Item SMOOTH_STONE = register(new BlockItem(builder(), Blocks.SMOOTH_STONE)); + public static final Item BRICKS = register(new BlockItem(builder(), Blocks.BRICKS)); + public static final Item BOOKSHELF = register(new BlockItem(builder(), Blocks.BOOKSHELF)); + public static final Item CHISELED_BOOKSHELF = register(new BlockItem(builder(), Blocks.CHISELED_BOOKSHELF)); + public static final Item DECORATED_POT = register(new DecoratedPotItem(builder(), Blocks.DECORATED_POT)); + public static final Item MOSSY_COBBLESTONE = register(new BlockItem(builder(), Blocks.MOSSY_COBBLESTONE)); + public static final Item OBSIDIAN = register(new BlockItem(builder(), Blocks.OBSIDIAN)); + public static final Item TORCH = register(new BlockItem(builder(), Blocks.TORCH, Blocks.WALL_TORCH)); + public static final Item END_ROD = register(new BlockItem(builder(), Blocks.END_ROD)); + public static final Item CHORUS_PLANT = register(new BlockItem(builder(), Blocks.CHORUS_PLANT)); + public static final Item CHORUS_FLOWER = register(new BlockItem(builder(), Blocks.CHORUS_FLOWER)); + public static final Item PURPUR_BLOCK = register(new BlockItem(builder(), Blocks.PURPUR_BLOCK)); + public static final Item PURPUR_PILLAR = register(new BlockItem(builder(), Blocks.PURPUR_PILLAR)); + public static final Item PURPUR_STAIRS = register(new BlockItem(builder(), Blocks.PURPUR_STAIRS)); + public static final Item SPAWNER = register(new BlockItem(builder(), Blocks.SPAWNER)); + public static final Item CHEST = register(new BlockItem(builder(), Blocks.CHEST)); + public static final Item CRAFTING_TABLE = register(new BlockItem(builder(), Blocks.CRAFTING_TABLE)); + public static final Item FARMLAND = register(new BlockItem(builder(), Blocks.FARMLAND)); + public static final Item FURNACE = register(new BlockItem(builder(), Blocks.FURNACE)); + public static final Item LADDER = register(new BlockItem(builder(), Blocks.LADDER)); + public static final Item COBBLESTONE_STAIRS = register(new BlockItem(builder(), Blocks.COBBLESTONE_STAIRS)); + public static final Item SNOW = register(new BlockItem(builder(), Blocks.SNOW)); + public static final Item ICE = register(new BlockItem(builder(), Blocks.ICE)); + public static final Item SNOW_BLOCK = register(new BlockItem(builder(), Blocks.SNOW_BLOCK)); + public static final Item CACTUS = register(new BlockItem(builder(), Blocks.CACTUS)); + public static final Item CLAY = register(new BlockItem(builder(), Blocks.CLAY)); + public static final Item JUKEBOX = register(new BlockItem(builder(), Blocks.JUKEBOX)); + public static final Item OAK_FENCE = register(new BlockItem(builder(), Blocks.OAK_FENCE)); + public static final Item SPRUCE_FENCE = register(new BlockItem(builder(), Blocks.SPRUCE_FENCE)); + public static final Item BIRCH_FENCE = register(new BlockItem(builder(), Blocks.BIRCH_FENCE)); + public static final Item JUNGLE_FENCE = register(new BlockItem(builder(), Blocks.JUNGLE_FENCE)); + public static final Item ACACIA_FENCE = register(new BlockItem(builder(), Blocks.ACACIA_FENCE)); + public static final Item CHERRY_FENCE = register(new BlockItem(builder(), Blocks.CHERRY_FENCE)); + public static final Item DARK_OAK_FENCE = register(new BlockItem(builder(), Blocks.DARK_OAK_FENCE)); + public static final Item MANGROVE_FENCE = register(new BlockItem(builder(), Blocks.MANGROVE_FENCE)); + public static final Item BAMBOO_FENCE = register(new BlockItem(builder(), Blocks.BAMBOO_FENCE)); + public static final Item CRIMSON_FENCE = register(new BlockItem(builder(), Blocks.CRIMSON_FENCE)); + public static final Item WARPED_FENCE = register(new BlockItem(builder(), Blocks.WARPED_FENCE)); + public static final Item PUMPKIN = register(new BlockItem(builder(), Blocks.PUMPKIN)); + public static final Item CARVED_PUMPKIN = register(new BlockItem(builder(), Blocks.CARVED_PUMPKIN)); + public static final Item JACK_O_LANTERN = register(new BlockItem(builder(), Blocks.JACK_O_LANTERN)); + public static final Item NETHERRACK = register(new BlockItem(builder(), Blocks.NETHERRACK)); + public static final Item SOUL_SAND = register(new BlockItem(builder(), Blocks.SOUL_SAND)); + public static final Item SOUL_SOIL = register(new BlockItem(builder(), Blocks.SOUL_SOIL)); + public static final Item BASALT = register(new BlockItem(builder(), Blocks.BASALT)); + public static final Item POLISHED_BASALT = register(new BlockItem(builder(), Blocks.POLISHED_BASALT)); + public static final Item SMOOTH_BASALT = register(new BlockItem(builder(), Blocks.SMOOTH_BASALT)); + public static final Item SOUL_TORCH = register(new BlockItem(builder(), Blocks.SOUL_TORCH, Blocks.SOUL_WALL_TORCH)); + public static final Item GLOWSTONE = register(new BlockItem(builder(), Blocks.GLOWSTONE)); + public static final Item INFESTED_STONE = register(new BlockItem(builder(), Blocks.INFESTED_STONE)); + public static final Item INFESTED_COBBLESTONE = register(new BlockItem(builder(), Blocks.INFESTED_COBBLESTONE)); + public static final Item INFESTED_STONE_BRICKS = register(new BlockItem(builder(), Blocks.INFESTED_STONE_BRICKS)); + public static final Item INFESTED_MOSSY_STONE_BRICKS = register(new BlockItem(builder(), Blocks.INFESTED_MOSSY_STONE_BRICKS)); + public static final Item INFESTED_CRACKED_STONE_BRICKS = register(new BlockItem(builder(), Blocks.INFESTED_CRACKED_STONE_BRICKS)); + public static final Item INFESTED_CHISELED_STONE_BRICKS = register(new BlockItem(builder(), Blocks.INFESTED_CHISELED_STONE_BRICKS)); + public static final Item INFESTED_DEEPSLATE = register(new BlockItem(builder(), Blocks.INFESTED_DEEPSLATE)); + public static final Item STONE_BRICKS = register(new BlockItem(builder(), Blocks.STONE_BRICKS)); + public static final Item MOSSY_STONE_BRICKS = register(new BlockItem(builder(), Blocks.MOSSY_STONE_BRICKS)); + public static final Item CRACKED_STONE_BRICKS = register(new BlockItem(builder(), Blocks.CRACKED_STONE_BRICKS)); + public static final Item CHISELED_STONE_BRICKS = register(new BlockItem(builder(), Blocks.CHISELED_STONE_BRICKS)); + public static final Item PACKED_MUD = register(new BlockItem(builder(), Blocks.PACKED_MUD)); + public static final Item MUD_BRICKS = register(new BlockItem(builder(), Blocks.MUD_BRICKS)); + public static final Item DEEPSLATE_BRICKS = register(new BlockItem(builder(), Blocks.DEEPSLATE_BRICKS)); + public static final Item CRACKED_DEEPSLATE_BRICKS = register(new BlockItem(builder(), Blocks.CRACKED_DEEPSLATE_BRICKS)); + public static final Item DEEPSLATE_TILES = register(new BlockItem(builder(), Blocks.DEEPSLATE_TILES)); + public static final Item CRACKED_DEEPSLATE_TILES = register(new BlockItem(builder(), Blocks.CRACKED_DEEPSLATE_TILES)); + public static final Item CHISELED_DEEPSLATE = register(new BlockItem(builder(), Blocks.CHISELED_DEEPSLATE)); + public static final Item REINFORCED_DEEPSLATE = register(new BlockItem(builder(), Blocks.REINFORCED_DEEPSLATE)); + public static final Item BROWN_MUSHROOM_BLOCK = register(new BlockItem(builder(), Blocks.BROWN_MUSHROOM_BLOCK)); + public static final Item RED_MUSHROOM_BLOCK = register(new BlockItem(builder(), Blocks.RED_MUSHROOM_BLOCK)); + public static final Item MUSHROOM_STEM = register(new BlockItem(builder(), Blocks.MUSHROOM_STEM)); + public static final Item IRON_BARS = register(new BlockItem(builder(), Blocks.IRON_BARS)); + public static final Item CHAIN = register(new BlockItem(builder(), Blocks.CHAIN)); + public static final Item GLASS_PANE = register(new BlockItem(builder(), Blocks.GLASS_PANE)); + public static final Item MELON = register(new BlockItem(builder(), Blocks.MELON)); + public static final Item VINE = register(new BlockItem(builder(), Blocks.VINE)); + public static final Item GLOW_LICHEN = register(new BlockItem(builder(), Blocks.GLOW_LICHEN)); + public static final Item BRICK_STAIRS = register(new BlockItem(builder(), Blocks.BRICK_STAIRS)); + public static final Item STONE_BRICK_STAIRS = register(new BlockItem(builder(), Blocks.STONE_BRICK_STAIRS)); + public static final Item MUD_BRICK_STAIRS = register(new BlockItem(builder(), Blocks.MUD_BRICK_STAIRS)); + public static final Item MYCELIUM = register(new BlockItem(builder(), Blocks.MYCELIUM)); + public static final Item LILY_PAD = register(new BlockItem(builder(), Blocks.LILY_PAD)); + public static final Item NETHER_BRICKS = register(new BlockItem(builder(), Blocks.NETHER_BRICKS)); + public static final Item CRACKED_NETHER_BRICKS = register(new BlockItem(builder(), Blocks.CRACKED_NETHER_BRICKS)); + public static final Item CHISELED_NETHER_BRICKS = register(new BlockItem(builder(), Blocks.CHISELED_NETHER_BRICKS)); + public static final Item NETHER_BRICK_FENCE = register(new BlockItem(builder(), Blocks.NETHER_BRICK_FENCE)); + public static final Item NETHER_BRICK_STAIRS = register(new BlockItem(builder(), Blocks.NETHER_BRICK_STAIRS)); + public static final Item SCULK = register(new BlockItem(builder(), Blocks.SCULK)); + public static final Item SCULK_VEIN = register(new BlockItem(builder(), Blocks.SCULK_VEIN)); + public static final Item SCULK_CATALYST = register(new BlockItem(builder(), Blocks.SCULK_CATALYST)); + public static final Item SCULK_SHRIEKER = register(new BlockItem(builder(), Blocks.SCULK_SHRIEKER)); + public static final Item ENCHANTING_TABLE = register(new BlockItem(builder(), Blocks.ENCHANTING_TABLE)); + public static final Item END_PORTAL_FRAME = register(new BlockItem(builder(), Blocks.END_PORTAL_FRAME)); + public static final Item END_STONE = register(new BlockItem(builder(), Blocks.END_STONE)); + public static final Item END_STONE_BRICKS = register(new BlockItem(builder(), Blocks.END_STONE_BRICKS)); + public static final Item DRAGON_EGG = register(new BlockItem(builder(), Blocks.DRAGON_EGG)); + public static final Item SANDSTONE_STAIRS = register(new BlockItem(builder(), Blocks.SANDSTONE_STAIRS)); + public static final Item ENDER_CHEST = register(new BlockItem(builder(), Blocks.ENDER_CHEST)); + public static final Item EMERALD_BLOCK = register(new BlockItem(builder(), Blocks.EMERALD_BLOCK)); + public static final Item OAK_STAIRS = register(new BlockItem(builder(), Blocks.OAK_STAIRS)); + public static final Item SPRUCE_STAIRS = register(new BlockItem(builder(), Blocks.SPRUCE_STAIRS)); + public static final Item BIRCH_STAIRS = register(new BlockItem(builder(), Blocks.BIRCH_STAIRS)); + public static final Item JUNGLE_STAIRS = register(new BlockItem(builder(), Blocks.JUNGLE_STAIRS)); + public static final Item ACACIA_STAIRS = register(new BlockItem(builder(), Blocks.ACACIA_STAIRS)); + public static final Item CHERRY_STAIRS = register(new BlockItem(builder(), Blocks.CHERRY_STAIRS)); + public static final Item DARK_OAK_STAIRS = register(new BlockItem(builder(), Blocks.DARK_OAK_STAIRS)); + public static final Item MANGROVE_STAIRS = register(new BlockItem(builder(), Blocks.MANGROVE_STAIRS)); + public static final Item BAMBOO_STAIRS = register(new BlockItem(builder(), Blocks.BAMBOO_STAIRS)); + public static final Item BAMBOO_MOSAIC_STAIRS = register(new BlockItem(builder(), Blocks.BAMBOO_MOSAIC_STAIRS)); + public static final Item CRIMSON_STAIRS = register(new BlockItem(builder(), Blocks.CRIMSON_STAIRS)); + public static final Item WARPED_STAIRS = register(new BlockItem(builder(), Blocks.WARPED_STAIRS)); + public static final Item COMMAND_BLOCK = register(new BlockItem(builder(), Blocks.COMMAND_BLOCK)); + public static final Item BEACON = register(new BlockItem(builder(), Blocks.BEACON)); + public static final Item COBBLESTONE_WALL = register(new BlockItem(builder(), Blocks.COBBLESTONE_WALL)); + public static final Item MOSSY_COBBLESTONE_WALL = register(new BlockItem(builder(), Blocks.MOSSY_COBBLESTONE_WALL)); + public static final Item BRICK_WALL = register(new BlockItem(builder(), Blocks.BRICK_WALL)); + public static final Item PRISMARINE_WALL = register(new BlockItem(builder(), Blocks.PRISMARINE_WALL)); + public static final Item RED_SANDSTONE_WALL = register(new BlockItem(builder(), Blocks.RED_SANDSTONE_WALL)); + public static final Item MOSSY_STONE_BRICK_WALL = register(new BlockItem(builder(), Blocks.MOSSY_STONE_BRICK_WALL)); + public static final Item GRANITE_WALL = register(new BlockItem(builder(), Blocks.GRANITE_WALL)); + public static final Item STONE_BRICK_WALL = register(new BlockItem(builder(), Blocks.STONE_BRICK_WALL)); + public static final Item MUD_BRICK_WALL = register(new BlockItem(builder(), Blocks.MUD_BRICK_WALL)); + public static final Item NETHER_BRICK_WALL = register(new BlockItem(builder(), Blocks.NETHER_BRICK_WALL)); + public static final Item ANDESITE_WALL = register(new BlockItem(builder(), Blocks.ANDESITE_WALL)); + public static final Item RED_NETHER_BRICK_WALL = register(new BlockItem(builder(), Blocks.RED_NETHER_BRICK_WALL)); + public static final Item SANDSTONE_WALL = register(new BlockItem(builder(), Blocks.SANDSTONE_WALL)); + public static final Item END_STONE_BRICK_WALL = register(new BlockItem(builder(), Blocks.END_STONE_BRICK_WALL)); + public static final Item DIORITE_WALL = register(new BlockItem(builder(), Blocks.DIORITE_WALL)); + public static final Item BLACKSTONE_WALL = register(new BlockItem(builder(), Blocks.BLACKSTONE_WALL)); + public static final Item POLISHED_BLACKSTONE_WALL = register(new BlockItem(builder(), Blocks.POLISHED_BLACKSTONE_WALL)); + public static final Item POLISHED_BLACKSTONE_BRICK_WALL = register(new BlockItem(builder(), Blocks.POLISHED_BLACKSTONE_BRICK_WALL)); + public static final Item COBBLED_DEEPSLATE_WALL = register(new BlockItem(builder(), Blocks.COBBLED_DEEPSLATE_WALL)); + public static final Item POLISHED_DEEPSLATE_WALL = register(new BlockItem(builder(), Blocks.POLISHED_DEEPSLATE_WALL)); + public static final Item DEEPSLATE_BRICK_WALL = register(new BlockItem(builder(), Blocks.DEEPSLATE_BRICK_WALL)); + public static final Item DEEPSLATE_TILE_WALL = register(new BlockItem(builder(), Blocks.DEEPSLATE_TILE_WALL)); + public static final Item ANVIL = register(new BlockItem(builder(), Blocks.ANVIL)); + public static final Item CHIPPED_ANVIL = register(new BlockItem(builder(), Blocks.CHIPPED_ANVIL)); + public static final Item DAMAGED_ANVIL = register(new BlockItem(builder(), Blocks.DAMAGED_ANVIL)); + public static final Item CHISELED_QUARTZ_BLOCK = register(new BlockItem(builder(), Blocks.CHISELED_QUARTZ_BLOCK)); + public static final Item QUARTZ_BLOCK = register(new BlockItem(builder(), Blocks.QUARTZ_BLOCK)); + public static final Item QUARTZ_BRICKS = register(new BlockItem(builder(), Blocks.QUARTZ_BRICKS)); + public static final Item QUARTZ_PILLAR = register(new BlockItem(builder(), Blocks.QUARTZ_PILLAR)); + public static final Item QUARTZ_STAIRS = register(new BlockItem(builder(), Blocks.QUARTZ_STAIRS)); + public static final Item WHITE_TERRACOTTA = register(new BlockItem(builder(), Blocks.WHITE_TERRACOTTA)); + public static final Item ORANGE_TERRACOTTA = register(new BlockItem(builder(), Blocks.ORANGE_TERRACOTTA)); + public static final Item MAGENTA_TERRACOTTA = register(new BlockItem(builder(), Blocks.MAGENTA_TERRACOTTA)); + public static final Item LIGHT_BLUE_TERRACOTTA = register(new BlockItem(builder(), Blocks.LIGHT_BLUE_TERRACOTTA)); + public static final Item YELLOW_TERRACOTTA = register(new BlockItem(builder(), Blocks.YELLOW_TERRACOTTA)); + public static final Item LIME_TERRACOTTA = register(new BlockItem(builder(), Blocks.LIME_TERRACOTTA)); + public static final Item PINK_TERRACOTTA = register(new BlockItem(builder(), Blocks.PINK_TERRACOTTA)); + public static final Item GRAY_TERRACOTTA = register(new BlockItem(builder(), Blocks.GRAY_TERRACOTTA)); + public static final Item LIGHT_GRAY_TERRACOTTA = register(new BlockItem(builder(), Blocks.LIGHT_GRAY_TERRACOTTA)); + public static final Item CYAN_TERRACOTTA = register(new BlockItem(builder(), Blocks.CYAN_TERRACOTTA)); + public static final Item PURPLE_TERRACOTTA = register(new BlockItem(builder(), Blocks.PURPLE_TERRACOTTA)); + public static final Item BLUE_TERRACOTTA = register(new BlockItem(builder(), Blocks.BLUE_TERRACOTTA)); + public static final Item BROWN_TERRACOTTA = register(new BlockItem(builder(), Blocks.BROWN_TERRACOTTA)); + public static final Item GREEN_TERRACOTTA = register(new BlockItem(builder(), Blocks.GREEN_TERRACOTTA)); + public static final Item RED_TERRACOTTA = register(new BlockItem(builder(), Blocks.RED_TERRACOTTA)); + public static final Item BLACK_TERRACOTTA = register(new BlockItem(builder(), Blocks.BLACK_TERRACOTTA)); + public static final Item BARRIER = register(new BlockItem(builder(), Blocks.BARRIER)); + public static final Item LIGHT = register(new BlockItem(builder(), Blocks.LIGHT)); + public static final Item HAY_BLOCK = register(new BlockItem(builder(), Blocks.HAY_BLOCK)); + public static final Item WHITE_CARPET = register(new BlockItem(builder(), Blocks.WHITE_CARPET)); + public static final Item ORANGE_CARPET = register(new BlockItem(builder(), Blocks.ORANGE_CARPET)); + public static final Item MAGENTA_CARPET = register(new BlockItem(builder(), Blocks.MAGENTA_CARPET)); + public static final Item LIGHT_BLUE_CARPET = register(new BlockItem(builder(), Blocks.LIGHT_BLUE_CARPET)); + public static final Item YELLOW_CARPET = register(new BlockItem(builder(), Blocks.YELLOW_CARPET)); + public static final Item LIME_CARPET = register(new BlockItem(builder(), Blocks.LIME_CARPET)); + public static final Item PINK_CARPET = register(new BlockItem(builder(), Blocks.PINK_CARPET)); + public static final Item GRAY_CARPET = register(new BlockItem(builder(), Blocks.GRAY_CARPET)); + public static final Item LIGHT_GRAY_CARPET = register(new BlockItem(builder(), Blocks.LIGHT_GRAY_CARPET)); + public static final Item CYAN_CARPET = register(new BlockItem(builder(), Blocks.CYAN_CARPET)); + public static final Item PURPLE_CARPET = register(new BlockItem(builder(), Blocks.PURPLE_CARPET)); + public static final Item BLUE_CARPET = register(new BlockItem(builder(), Blocks.BLUE_CARPET)); + public static final Item BROWN_CARPET = register(new BlockItem(builder(), Blocks.BROWN_CARPET)); + public static final Item GREEN_CARPET = register(new BlockItem(builder(), Blocks.GREEN_CARPET)); + public static final Item RED_CARPET = register(new BlockItem(builder(), Blocks.RED_CARPET)); + public static final Item BLACK_CARPET = register(new BlockItem(builder(), Blocks.BLACK_CARPET)); + public static final Item TERRACOTTA = register(new BlockItem(builder(), Blocks.TERRACOTTA)); + public static final Item PACKED_ICE = register(new BlockItem(builder(), Blocks.PACKED_ICE)); + public static final Item DIRT_PATH = register(new BlockItem(builder(), Blocks.DIRT_PATH)); + public static final Item SUNFLOWER = register(new BlockItem(builder(), Blocks.SUNFLOWER)); + public static final Item LILAC = register(new BlockItem(builder(), Blocks.LILAC)); + public static final Item ROSE_BUSH = register(new BlockItem(builder(), Blocks.ROSE_BUSH)); + public static final Item PEONY = register(new BlockItem(builder(), Blocks.PEONY)); + public static final Item TALL_GRASS = register(new BlockItem(builder(), Blocks.TALL_GRASS)); + public static final Item LARGE_FERN = register(new BlockItem(builder(), Blocks.LARGE_FERN)); + public static final Item WHITE_STAINED_GLASS = register(new BlockItem(builder(), Blocks.WHITE_STAINED_GLASS)); + public static final Item ORANGE_STAINED_GLASS = register(new BlockItem(builder(), Blocks.ORANGE_STAINED_GLASS)); + public static final Item MAGENTA_STAINED_GLASS = register(new BlockItem(builder(), Blocks.MAGENTA_STAINED_GLASS)); + public static final Item LIGHT_BLUE_STAINED_GLASS = register(new BlockItem(builder(), Blocks.LIGHT_BLUE_STAINED_GLASS)); + public static final Item YELLOW_STAINED_GLASS = register(new BlockItem(builder(), Blocks.YELLOW_STAINED_GLASS)); + public static final Item LIME_STAINED_GLASS = register(new BlockItem(builder(), Blocks.LIME_STAINED_GLASS)); + public static final Item PINK_STAINED_GLASS = register(new BlockItem(builder(), Blocks.PINK_STAINED_GLASS)); + public static final Item GRAY_STAINED_GLASS = register(new BlockItem(builder(), Blocks.GRAY_STAINED_GLASS)); + public static final Item LIGHT_GRAY_STAINED_GLASS = register(new BlockItem(builder(), Blocks.LIGHT_GRAY_STAINED_GLASS)); + public static final Item CYAN_STAINED_GLASS = register(new BlockItem(builder(), Blocks.CYAN_STAINED_GLASS)); + public static final Item PURPLE_STAINED_GLASS = register(new BlockItem(builder(), Blocks.PURPLE_STAINED_GLASS)); + public static final Item BLUE_STAINED_GLASS = register(new BlockItem(builder(), Blocks.BLUE_STAINED_GLASS)); + public static final Item BROWN_STAINED_GLASS = register(new BlockItem(builder(), Blocks.BROWN_STAINED_GLASS)); + public static final Item GREEN_STAINED_GLASS = register(new BlockItem(builder(), Blocks.GREEN_STAINED_GLASS)); + public static final Item RED_STAINED_GLASS = register(new BlockItem(builder(), Blocks.RED_STAINED_GLASS)); + public static final Item BLACK_STAINED_GLASS = register(new BlockItem(builder(), Blocks.BLACK_STAINED_GLASS)); + public static final Item WHITE_STAINED_GLASS_PANE = register(new BlockItem(builder(), Blocks.WHITE_STAINED_GLASS_PANE)); + public static final Item ORANGE_STAINED_GLASS_PANE = register(new BlockItem(builder(), Blocks.ORANGE_STAINED_GLASS_PANE)); + public static final Item MAGENTA_STAINED_GLASS_PANE = register(new BlockItem(builder(), Blocks.MAGENTA_STAINED_GLASS_PANE)); + public static final Item LIGHT_BLUE_STAINED_GLASS_PANE = register(new BlockItem(builder(), Blocks.LIGHT_BLUE_STAINED_GLASS_PANE)); + public static final Item YELLOW_STAINED_GLASS_PANE = register(new BlockItem(builder(), Blocks.YELLOW_STAINED_GLASS_PANE)); + public static final Item LIME_STAINED_GLASS_PANE = register(new BlockItem(builder(), Blocks.LIME_STAINED_GLASS_PANE)); + public static final Item PINK_STAINED_GLASS_PANE = register(new BlockItem(builder(), Blocks.PINK_STAINED_GLASS_PANE)); + public static final Item GRAY_STAINED_GLASS_PANE = register(new BlockItem(builder(), Blocks.GRAY_STAINED_GLASS_PANE)); + public static final Item LIGHT_GRAY_STAINED_GLASS_PANE = register(new BlockItem(builder(), Blocks.LIGHT_GRAY_STAINED_GLASS_PANE)); + public static final Item CYAN_STAINED_GLASS_PANE = register(new BlockItem(builder(), Blocks.CYAN_STAINED_GLASS_PANE)); + public static final Item PURPLE_STAINED_GLASS_PANE = register(new BlockItem(builder(), Blocks.PURPLE_STAINED_GLASS_PANE)); + public static final Item BLUE_STAINED_GLASS_PANE = register(new BlockItem(builder(), Blocks.BLUE_STAINED_GLASS_PANE)); + public static final Item BROWN_STAINED_GLASS_PANE = register(new BlockItem(builder(), Blocks.BROWN_STAINED_GLASS_PANE)); + public static final Item GREEN_STAINED_GLASS_PANE = register(new BlockItem(builder(), Blocks.GREEN_STAINED_GLASS_PANE)); + public static final Item RED_STAINED_GLASS_PANE = register(new BlockItem(builder(), Blocks.RED_STAINED_GLASS_PANE)); + public static final Item BLACK_STAINED_GLASS_PANE = register(new BlockItem(builder(), Blocks.BLACK_STAINED_GLASS_PANE)); + public static final Item PRISMARINE = register(new BlockItem(builder(), Blocks.PRISMARINE)); + public static final Item PRISMARINE_BRICKS = register(new BlockItem(builder(), Blocks.PRISMARINE_BRICKS)); + public static final Item DARK_PRISMARINE = register(new BlockItem(builder(), Blocks.DARK_PRISMARINE)); + public static final Item PRISMARINE_STAIRS = register(new BlockItem(builder(), Blocks.PRISMARINE_STAIRS)); + public static final Item PRISMARINE_BRICK_STAIRS = register(new BlockItem(builder(), Blocks.PRISMARINE_BRICK_STAIRS)); + public static final Item DARK_PRISMARINE_STAIRS = register(new BlockItem(builder(), Blocks.DARK_PRISMARINE_STAIRS)); + public static final Item SEA_LANTERN = register(new BlockItem(builder(), Blocks.SEA_LANTERN)); + public static final Item RED_SANDSTONE = register(new BlockItem(builder(), Blocks.RED_SANDSTONE)); + public static final Item CHISELED_RED_SANDSTONE = register(new BlockItem(builder(), Blocks.CHISELED_RED_SANDSTONE)); + public static final Item CUT_RED_SANDSTONE = register(new BlockItem(builder(), Blocks.CUT_RED_SANDSTONE)); + public static final Item RED_SANDSTONE_STAIRS = register(new BlockItem(builder(), Blocks.RED_SANDSTONE_STAIRS)); + public static final Item REPEATING_COMMAND_BLOCK = register(new BlockItem(builder(), Blocks.REPEATING_COMMAND_BLOCK)); + public static final Item CHAIN_COMMAND_BLOCK = register(new BlockItem(builder(), Blocks.CHAIN_COMMAND_BLOCK)); + public static final Item MAGMA_BLOCK = register(new BlockItem(builder(), Blocks.MAGMA_BLOCK)); + public static final Item NETHER_WART_BLOCK = register(new BlockItem(builder(), Blocks.NETHER_WART_BLOCK)); + public static final Item WARPED_WART_BLOCK = register(new BlockItem(builder(), Blocks.WARPED_WART_BLOCK)); + public static final Item RED_NETHER_BRICKS = register(new BlockItem(builder(), Blocks.RED_NETHER_BRICKS)); + public static final Item BONE_BLOCK = register(new BlockItem(builder(), Blocks.BONE_BLOCK)); + public static final Item STRUCTURE_VOID = register(new BlockItem(builder(), Blocks.STRUCTURE_VOID)); + public static final Item SHULKER_BOX = register(new ShulkerBoxItem(builder().stackSize(1), Blocks.SHULKER_BOX)); + public static final Item WHITE_SHULKER_BOX = register(new ShulkerBoxItem(builder().stackSize(1), Blocks.WHITE_SHULKER_BOX)); + public static final Item ORANGE_SHULKER_BOX = register(new ShulkerBoxItem(builder().stackSize(1), Blocks.ORANGE_SHULKER_BOX)); + public static final Item MAGENTA_SHULKER_BOX = register(new ShulkerBoxItem(builder().stackSize(1), Blocks.MAGENTA_SHULKER_BOX)); + public static final Item LIGHT_BLUE_SHULKER_BOX = register(new ShulkerBoxItem(builder().stackSize(1), Blocks.LIGHT_BLUE_SHULKER_BOX)); + public static final Item YELLOW_SHULKER_BOX = register(new ShulkerBoxItem(builder().stackSize(1), Blocks.YELLOW_SHULKER_BOX)); + public static final Item LIME_SHULKER_BOX = register(new ShulkerBoxItem(builder().stackSize(1), Blocks.LIME_SHULKER_BOX)); + public static final Item PINK_SHULKER_BOX = register(new ShulkerBoxItem(builder().stackSize(1), Blocks.PINK_SHULKER_BOX)); + public static final Item GRAY_SHULKER_BOX = register(new ShulkerBoxItem(builder().stackSize(1), Blocks.GRAY_SHULKER_BOX)); + public static final Item LIGHT_GRAY_SHULKER_BOX = register(new ShulkerBoxItem(builder().stackSize(1), Blocks.LIGHT_GRAY_SHULKER_BOX)); + public static final Item CYAN_SHULKER_BOX = register(new ShulkerBoxItem(builder().stackSize(1), Blocks.CYAN_SHULKER_BOX)); + public static final Item PURPLE_SHULKER_BOX = register(new ShulkerBoxItem(builder().stackSize(1), Blocks.PURPLE_SHULKER_BOX)); + public static final Item BLUE_SHULKER_BOX = register(new ShulkerBoxItem(builder().stackSize(1), Blocks.BLUE_SHULKER_BOX)); + public static final Item BROWN_SHULKER_BOX = register(new ShulkerBoxItem(builder().stackSize(1), Blocks.BROWN_SHULKER_BOX)); + public static final Item GREEN_SHULKER_BOX = register(new ShulkerBoxItem(builder().stackSize(1), Blocks.GREEN_SHULKER_BOX)); + public static final Item RED_SHULKER_BOX = register(new ShulkerBoxItem(builder().stackSize(1), Blocks.RED_SHULKER_BOX)); + public static final Item BLACK_SHULKER_BOX = register(new ShulkerBoxItem(builder().stackSize(1), Blocks.BLACK_SHULKER_BOX)); + public static final Item WHITE_GLAZED_TERRACOTTA = register(new BlockItem(builder(), Blocks.WHITE_GLAZED_TERRACOTTA)); + public static final Item ORANGE_GLAZED_TERRACOTTA = register(new BlockItem(builder(), Blocks.ORANGE_GLAZED_TERRACOTTA)); + public static final Item MAGENTA_GLAZED_TERRACOTTA = register(new BlockItem(builder(), Blocks.MAGENTA_GLAZED_TERRACOTTA)); + public static final Item LIGHT_BLUE_GLAZED_TERRACOTTA = register(new BlockItem(builder(), Blocks.LIGHT_BLUE_GLAZED_TERRACOTTA)); + public static final Item YELLOW_GLAZED_TERRACOTTA = register(new BlockItem(builder(), Blocks.YELLOW_GLAZED_TERRACOTTA)); + public static final Item LIME_GLAZED_TERRACOTTA = register(new BlockItem(builder(), Blocks.LIME_GLAZED_TERRACOTTA)); + public static final Item PINK_GLAZED_TERRACOTTA = register(new BlockItem(builder(), Blocks.PINK_GLAZED_TERRACOTTA)); + public static final Item GRAY_GLAZED_TERRACOTTA = register(new BlockItem(builder(), Blocks.GRAY_GLAZED_TERRACOTTA)); + public static final Item LIGHT_GRAY_GLAZED_TERRACOTTA = register(new BlockItem(builder(), Blocks.LIGHT_GRAY_GLAZED_TERRACOTTA)); + public static final Item CYAN_GLAZED_TERRACOTTA = register(new BlockItem(builder(), Blocks.CYAN_GLAZED_TERRACOTTA)); + public static final Item PURPLE_GLAZED_TERRACOTTA = register(new BlockItem(builder(), Blocks.PURPLE_GLAZED_TERRACOTTA)); + public static final Item BLUE_GLAZED_TERRACOTTA = register(new BlockItem(builder(), Blocks.BLUE_GLAZED_TERRACOTTA)); + public static final Item BROWN_GLAZED_TERRACOTTA = register(new BlockItem(builder(), Blocks.BROWN_GLAZED_TERRACOTTA)); + public static final Item GREEN_GLAZED_TERRACOTTA = register(new BlockItem(builder(), Blocks.GREEN_GLAZED_TERRACOTTA)); + public static final Item RED_GLAZED_TERRACOTTA = register(new BlockItem(builder(), Blocks.RED_GLAZED_TERRACOTTA)); + public static final Item BLACK_GLAZED_TERRACOTTA = register(new BlockItem(builder(), Blocks.BLACK_GLAZED_TERRACOTTA)); + public static final Item WHITE_CONCRETE = register(new BlockItem(builder(), Blocks.WHITE_CONCRETE)); + public static final Item ORANGE_CONCRETE = register(new BlockItem(builder(), Blocks.ORANGE_CONCRETE)); + public static final Item MAGENTA_CONCRETE = register(new BlockItem(builder(), Blocks.MAGENTA_CONCRETE)); + public static final Item LIGHT_BLUE_CONCRETE = register(new BlockItem(builder(), Blocks.LIGHT_BLUE_CONCRETE)); + public static final Item YELLOW_CONCRETE = register(new BlockItem(builder(), Blocks.YELLOW_CONCRETE)); + public static final Item LIME_CONCRETE = register(new BlockItem(builder(), Blocks.LIME_CONCRETE)); + public static final Item PINK_CONCRETE = register(new BlockItem(builder(), Blocks.PINK_CONCRETE)); + public static final Item GRAY_CONCRETE = register(new BlockItem(builder(), Blocks.GRAY_CONCRETE)); + public static final Item LIGHT_GRAY_CONCRETE = register(new BlockItem(builder(), Blocks.LIGHT_GRAY_CONCRETE)); + public static final Item CYAN_CONCRETE = register(new BlockItem(builder(), Blocks.CYAN_CONCRETE)); + public static final Item PURPLE_CONCRETE = register(new BlockItem(builder(), Blocks.PURPLE_CONCRETE)); + public static final Item BLUE_CONCRETE = register(new BlockItem(builder(), Blocks.BLUE_CONCRETE)); + public static final Item BROWN_CONCRETE = register(new BlockItem(builder(), Blocks.BROWN_CONCRETE)); + public static final Item GREEN_CONCRETE = register(new BlockItem(builder(), Blocks.GREEN_CONCRETE)); + public static final Item RED_CONCRETE = register(new BlockItem(builder(), Blocks.RED_CONCRETE)); + public static final Item BLACK_CONCRETE = register(new BlockItem(builder(), Blocks.BLACK_CONCRETE)); + public static final Item WHITE_CONCRETE_POWDER = register(new BlockItem(builder(), Blocks.WHITE_CONCRETE_POWDER)); + public static final Item ORANGE_CONCRETE_POWDER = register(new BlockItem(builder(), Blocks.ORANGE_CONCRETE_POWDER)); + public static final Item MAGENTA_CONCRETE_POWDER = register(new BlockItem(builder(), Blocks.MAGENTA_CONCRETE_POWDER)); + public static final Item LIGHT_BLUE_CONCRETE_POWDER = register(new BlockItem(builder(), Blocks.LIGHT_BLUE_CONCRETE_POWDER)); + public static final Item YELLOW_CONCRETE_POWDER = register(new BlockItem(builder(), Blocks.YELLOW_CONCRETE_POWDER)); + public static final Item LIME_CONCRETE_POWDER = register(new BlockItem(builder(), Blocks.LIME_CONCRETE_POWDER)); + public static final Item PINK_CONCRETE_POWDER = register(new BlockItem(builder(), Blocks.PINK_CONCRETE_POWDER)); + public static final Item GRAY_CONCRETE_POWDER = register(new BlockItem(builder(), Blocks.GRAY_CONCRETE_POWDER)); + public static final Item LIGHT_GRAY_CONCRETE_POWDER = register(new BlockItem(builder(), Blocks.LIGHT_GRAY_CONCRETE_POWDER)); + public static final Item CYAN_CONCRETE_POWDER = register(new BlockItem(builder(), Blocks.CYAN_CONCRETE_POWDER)); + public static final Item PURPLE_CONCRETE_POWDER = register(new BlockItem(builder(), Blocks.PURPLE_CONCRETE_POWDER)); + public static final Item BLUE_CONCRETE_POWDER = register(new BlockItem(builder(), Blocks.BLUE_CONCRETE_POWDER)); + public static final Item BROWN_CONCRETE_POWDER = register(new BlockItem(builder(), Blocks.BROWN_CONCRETE_POWDER)); + public static final Item GREEN_CONCRETE_POWDER = register(new BlockItem(builder(), Blocks.GREEN_CONCRETE_POWDER)); + public static final Item RED_CONCRETE_POWDER = register(new BlockItem(builder(), Blocks.RED_CONCRETE_POWDER)); + public static final Item BLACK_CONCRETE_POWDER = register(new BlockItem(builder(), Blocks.BLACK_CONCRETE_POWDER)); + public static final Item TURTLE_EGG = register(new BlockItem(builder(), Blocks.TURTLE_EGG)); + public static final Item SNIFFER_EGG = register(new BlockItem(builder(), Blocks.SNIFFER_EGG)); + public static final Item DEAD_TUBE_CORAL_BLOCK = register(new BlockItem(builder(), Blocks.DEAD_TUBE_CORAL_BLOCK)); + public static final Item DEAD_BRAIN_CORAL_BLOCK = register(new BlockItem(builder(), Blocks.DEAD_BRAIN_CORAL_BLOCK)); + public static final Item DEAD_BUBBLE_CORAL_BLOCK = register(new BlockItem(builder(), Blocks.DEAD_BUBBLE_CORAL_BLOCK)); + public static final Item DEAD_FIRE_CORAL_BLOCK = register(new BlockItem(builder(), Blocks.DEAD_FIRE_CORAL_BLOCK)); + public static final Item DEAD_HORN_CORAL_BLOCK = register(new BlockItem(builder(), Blocks.DEAD_HORN_CORAL_BLOCK)); + public static final Item TUBE_CORAL_BLOCK = register(new BlockItem(builder(), Blocks.TUBE_CORAL_BLOCK)); + public static final Item BRAIN_CORAL_BLOCK = register(new BlockItem(builder(), Blocks.BRAIN_CORAL_BLOCK)); + public static final Item BUBBLE_CORAL_BLOCK = register(new BlockItem(builder(), Blocks.BUBBLE_CORAL_BLOCK)); + public static final Item FIRE_CORAL_BLOCK = register(new BlockItem(builder(), Blocks.FIRE_CORAL_BLOCK)); + public static final Item HORN_CORAL_BLOCK = register(new BlockItem(builder(), Blocks.HORN_CORAL_BLOCK)); + public static final Item TUBE_CORAL = register(new BlockItem(builder(), Blocks.TUBE_CORAL)); + public static final Item BRAIN_CORAL = register(new BlockItem(builder(), Blocks.BRAIN_CORAL)); + public static final Item BUBBLE_CORAL = register(new BlockItem(builder(), Blocks.BUBBLE_CORAL)); + public static final Item FIRE_CORAL = register(new BlockItem(builder(), Blocks.FIRE_CORAL)); + public static final Item HORN_CORAL = register(new BlockItem(builder(), Blocks.HORN_CORAL)); + public static final Item DEAD_BRAIN_CORAL = register(new BlockItem(builder(), Blocks.DEAD_BRAIN_CORAL)); + public static final Item DEAD_BUBBLE_CORAL = register(new BlockItem(builder(), Blocks.DEAD_BUBBLE_CORAL)); + public static final Item DEAD_FIRE_CORAL = register(new BlockItem(builder(), Blocks.DEAD_FIRE_CORAL)); + public static final Item DEAD_HORN_CORAL = register(new BlockItem(builder(), Blocks.DEAD_HORN_CORAL)); + public static final Item DEAD_TUBE_CORAL = register(new BlockItem(builder(), Blocks.DEAD_TUBE_CORAL)); + public static final Item TUBE_CORAL_FAN = register(new BlockItem(builder(), Blocks.TUBE_CORAL_FAN, Blocks.TUBE_CORAL_WALL_FAN)); + public static final Item BRAIN_CORAL_FAN = register(new BlockItem(builder(), Blocks.BRAIN_CORAL_FAN, Blocks.BRAIN_CORAL_WALL_FAN)); + public static final Item BUBBLE_CORAL_FAN = register(new BlockItem(builder(), Blocks.BUBBLE_CORAL_FAN, Blocks.BUBBLE_CORAL_WALL_FAN)); + public static final Item FIRE_CORAL_FAN = register(new BlockItem(builder(), Blocks.FIRE_CORAL_FAN, Blocks.FIRE_CORAL_WALL_FAN)); + public static final Item HORN_CORAL_FAN = register(new BlockItem(builder(), Blocks.HORN_CORAL_FAN, Blocks.HORN_CORAL_WALL_FAN)); + public static final Item DEAD_TUBE_CORAL_FAN = register(new BlockItem(builder(), Blocks.DEAD_TUBE_CORAL_FAN, Blocks.DEAD_TUBE_CORAL_WALL_FAN)); + public static final Item DEAD_BRAIN_CORAL_FAN = register(new BlockItem(builder(), Blocks.DEAD_BRAIN_CORAL_FAN, Blocks.DEAD_BRAIN_CORAL_WALL_FAN)); + public static final Item DEAD_BUBBLE_CORAL_FAN = register(new BlockItem(builder(), Blocks.DEAD_BUBBLE_CORAL_FAN, Blocks.DEAD_BUBBLE_CORAL_WALL_FAN)); + public static final Item DEAD_FIRE_CORAL_FAN = register(new BlockItem(builder(), Blocks.DEAD_FIRE_CORAL_FAN, Blocks.DEAD_FIRE_CORAL_WALL_FAN)); + public static final Item DEAD_HORN_CORAL_FAN = register(new BlockItem(builder(), Blocks.DEAD_HORN_CORAL_FAN, Blocks.DEAD_HORN_CORAL_WALL_FAN)); + public static final Item BLUE_ICE = register(new BlockItem(builder(), Blocks.BLUE_ICE)); + public static final Item CONDUIT = register(new BlockItem(builder(), Blocks.CONDUIT)); + public static final Item POLISHED_GRANITE_STAIRS = register(new BlockItem(builder(), Blocks.POLISHED_GRANITE_STAIRS)); + public static final Item SMOOTH_RED_SANDSTONE_STAIRS = register(new BlockItem(builder(), Blocks.SMOOTH_RED_SANDSTONE_STAIRS)); + public static final Item MOSSY_STONE_BRICK_STAIRS = register(new BlockItem(builder(), Blocks.MOSSY_STONE_BRICK_STAIRS)); + public static final Item POLISHED_DIORITE_STAIRS = register(new BlockItem(builder(), Blocks.POLISHED_DIORITE_STAIRS)); + public static final Item MOSSY_COBBLESTONE_STAIRS = register(new BlockItem(builder(), Blocks.MOSSY_COBBLESTONE_STAIRS)); + public static final Item END_STONE_BRICK_STAIRS = register(new BlockItem(builder(), Blocks.END_STONE_BRICK_STAIRS)); + public static final Item STONE_STAIRS = register(new BlockItem(builder(), Blocks.STONE_STAIRS)); + public static final Item SMOOTH_SANDSTONE_STAIRS = register(new BlockItem(builder(), Blocks.SMOOTH_SANDSTONE_STAIRS)); + public static final Item SMOOTH_QUARTZ_STAIRS = register(new BlockItem(builder(), Blocks.SMOOTH_QUARTZ_STAIRS)); + public static final Item GRANITE_STAIRS = register(new BlockItem(builder(), Blocks.GRANITE_STAIRS)); + public static final Item ANDESITE_STAIRS = register(new BlockItem(builder(), Blocks.ANDESITE_STAIRS)); + public static final Item RED_NETHER_BRICK_STAIRS = register(new BlockItem(builder(), Blocks.RED_NETHER_BRICK_STAIRS)); + public static final Item POLISHED_ANDESITE_STAIRS = register(new BlockItem(builder(), Blocks.POLISHED_ANDESITE_STAIRS)); + public static final Item DIORITE_STAIRS = register(new BlockItem(builder(), Blocks.DIORITE_STAIRS)); + public static final Item COBBLED_DEEPSLATE_STAIRS = register(new BlockItem(builder(), Blocks.COBBLED_DEEPSLATE_STAIRS)); + public static final Item POLISHED_DEEPSLATE_STAIRS = register(new BlockItem(builder(), Blocks.POLISHED_DEEPSLATE_STAIRS)); + public static final Item DEEPSLATE_BRICK_STAIRS = register(new BlockItem(builder(), Blocks.DEEPSLATE_BRICK_STAIRS)); + public static final Item DEEPSLATE_TILE_STAIRS = register(new BlockItem(builder(), Blocks.DEEPSLATE_TILE_STAIRS)); + public static final Item POLISHED_GRANITE_SLAB = register(new BlockItem(builder(), Blocks.POLISHED_GRANITE_SLAB)); + public static final Item SMOOTH_RED_SANDSTONE_SLAB = register(new BlockItem(builder(), Blocks.SMOOTH_RED_SANDSTONE_SLAB)); + public static final Item MOSSY_STONE_BRICK_SLAB = register(new BlockItem(builder(), Blocks.MOSSY_STONE_BRICK_SLAB)); + public static final Item POLISHED_DIORITE_SLAB = register(new BlockItem(builder(), Blocks.POLISHED_DIORITE_SLAB)); + public static final Item MOSSY_COBBLESTONE_SLAB = register(new BlockItem(builder(), Blocks.MOSSY_COBBLESTONE_SLAB)); + public static final Item END_STONE_BRICK_SLAB = register(new BlockItem(builder(), Blocks.END_STONE_BRICK_SLAB)); + public static final Item SMOOTH_SANDSTONE_SLAB = register(new BlockItem(builder(), Blocks.SMOOTH_SANDSTONE_SLAB)); + public static final Item SMOOTH_QUARTZ_SLAB = register(new BlockItem(builder(), Blocks.SMOOTH_QUARTZ_SLAB)); + public static final Item GRANITE_SLAB = register(new BlockItem(builder(), Blocks.GRANITE_SLAB)); + public static final Item ANDESITE_SLAB = register(new BlockItem(builder(), Blocks.ANDESITE_SLAB)); + public static final Item RED_NETHER_BRICK_SLAB = register(new BlockItem(builder(), Blocks.RED_NETHER_BRICK_SLAB)); + public static final Item POLISHED_ANDESITE_SLAB = register(new BlockItem(builder(), Blocks.POLISHED_ANDESITE_SLAB)); + public static final Item DIORITE_SLAB = register(new BlockItem(builder(), Blocks.DIORITE_SLAB)); + public static final Item COBBLED_DEEPSLATE_SLAB = register(new BlockItem(builder(), Blocks.COBBLED_DEEPSLATE_SLAB)); + public static final Item POLISHED_DEEPSLATE_SLAB = register(new BlockItem(builder(), Blocks.POLISHED_DEEPSLATE_SLAB)); + public static final Item DEEPSLATE_BRICK_SLAB = register(new BlockItem(builder(), Blocks.DEEPSLATE_BRICK_SLAB)); + public static final Item DEEPSLATE_TILE_SLAB = register(new BlockItem(builder(), Blocks.DEEPSLATE_TILE_SLAB)); + public static final Item SCAFFOLDING = register(new BlockItem(builder(), Blocks.SCAFFOLDING)); + public static final Item REDSTONE = register(new BlockItem("redstone", builder(), Blocks.REDSTONE_WIRE)); + public static final Item REDSTONE_TORCH = register(new BlockItem(builder(), Blocks.REDSTONE_TORCH, Blocks.REDSTONE_WALL_TORCH)); + public static final Item REDSTONE_BLOCK = register(new BlockItem(builder(), Blocks.REDSTONE_BLOCK)); + public static final Item REPEATER = register(new BlockItem(builder(), Blocks.REPEATER)); + public static final Item COMPARATOR = register(new BlockItem(builder(), Blocks.COMPARATOR)); + public static final Item PISTON = register(new BlockItem(builder(), Blocks.PISTON)); + public static final Item STICKY_PISTON = register(new BlockItem(builder(), Blocks.STICKY_PISTON)); + public static final Item SLIME_BLOCK = register(new BlockItem(builder(), Blocks.SLIME_BLOCK)); + public static final Item HONEY_BLOCK = register(new BlockItem(builder(), Blocks.HONEY_BLOCK)); + public static final Item OBSERVER = register(new BlockItem(builder(), Blocks.OBSERVER)); + public static final Item HOPPER = register(new BlockItem(builder(), Blocks.HOPPER)); + public static final Item DISPENSER = register(new BlockItem(builder(), Blocks.DISPENSER)); + public static final Item DROPPER = register(new BlockItem(builder(), Blocks.DROPPER)); + public static final Item LECTERN = register(new BlockItem(builder(), Blocks.LECTERN)); + public static final Item TARGET = register(new BlockItem(builder(), Blocks.TARGET)); + public static final Item LEVER = register(new BlockItem(builder(), Blocks.LEVER)); + public static final Item LIGHTNING_ROD = register(new BlockItem(builder(), Blocks.LIGHTNING_ROD)); + public static final Item DAYLIGHT_DETECTOR = register(new BlockItem(builder(), Blocks.DAYLIGHT_DETECTOR)); + public static final Item SCULK_SENSOR = register(new BlockItem(builder(), Blocks.SCULK_SENSOR)); + public static final Item CALIBRATED_SCULK_SENSOR = register(new BlockItem(builder(), Blocks.CALIBRATED_SCULK_SENSOR)); + public static final Item TRIPWIRE_HOOK = register(new BlockItem(builder(), Blocks.TRIPWIRE_HOOK)); + public static final Item TRAPPED_CHEST = register(new BlockItem(builder(), Blocks.TRAPPED_CHEST)); + public static final Item TNT = register(new BlockItem(builder(), Blocks.TNT)); + public static final Item REDSTONE_LAMP = register(new BlockItem(builder(), Blocks.REDSTONE_LAMP)); + public static final Item NOTE_BLOCK = register(new BlockItem(builder(), Blocks.NOTE_BLOCK)); + public static final Item STONE_BUTTON = register(new BlockItem(builder(), Blocks.STONE_BUTTON)); + public static final Item POLISHED_BLACKSTONE_BUTTON = register(new BlockItem(builder(), Blocks.POLISHED_BLACKSTONE_BUTTON)); + public static final Item OAK_BUTTON = register(new BlockItem(builder(), Blocks.OAK_BUTTON)); + public static final Item SPRUCE_BUTTON = register(new BlockItem(builder(), Blocks.SPRUCE_BUTTON)); + public static final Item BIRCH_BUTTON = register(new BlockItem(builder(), Blocks.BIRCH_BUTTON)); + public static final Item JUNGLE_BUTTON = register(new BlockItem(builder(), Blocks.JUNGLE_BUTTON)); + public static final Item ACACIA_BUTTON = register(new BlockItem(builder(), Blocks.ACACIA_BUTTON)); + public static final Item CHERRY_BUTTON = register(new BlockItem(builder(), Blocks.CHERRY_BUTTON)); + public static final Item DARK_OAK_BUTTON = register(new BlockItem(builder(), Blocks.DARK_OAK_BUTTON)); + public static final Item MANGROVE_BUTTON = register(new BlockItem(builder(), Blocks.MANGROVE_BUTTON)); + public static final Item BAMBOO_BUTTON = register(new BlockItem(builder(), Blocks.BAMBOO_BUTTON)); + public static final Item CRIMSON_BUTTON = register(new BlockItem(builder(), Blocks.CRIMSON_BUTTON)); + public static final Item WARPED_BUTTON = register(new BlockItem(builder(), Blocks.WARPED_BUTTON)); + public static final Item STONE_PRESSURE_PLATE = register(new BlockItem(builder(), Blocks.STONE_PRESSURE_PLATE)); + public static final Item POLISHED_BLACKSTONE_PRESSURE_PLATE = register(new BlockItem(builder(), Blocks.POLISHED_BLACKSTONE_PRESSURE_PLATE)); + public static final Item LIGHT_WEIGHTED_PRESSURE_PLATE = register(new BlockItem(builder(), Blocks.LIGHT_WEIGHTED_PRESSURE_PLATE)); + public static final Item HEAVY_WEIGHTED_PRESSURE_PLATE = register(new BlockItem(builder(), Blocks.HEAVY_WEIGHTED_PRESSURE_PLATE)); + public static final Item OAK_PRESSURE_PLATE = register(new BlockItem(builder(), Blocks.OAK_PRESSURE_PLATE)); + public static final Item SPRUCE_PRESSURE_PLATE = register(new BlockItem(builder(), Blocks.SPRUCE_PRESSURE_PLATE)); + public static final Item BIRCH_PRESSURE_PLATE = register(new BlockItem(builder(), Blocks.BIRCH_PRESSURE_PLATE)); + public static final Item JUNGLE_PRESSURE_PLATE = register(new BlockItem(builder(), Blocks.JUNGLE_PRESSURE_PLATE)); + public static final Item ACACIA_PRESSURE_PLATE = register(new BlockItem(builder(), Blocks.ACACIA_PRESSURE_PLATE)); + public static final Item CHERRY_PRESSURE_PLATE = register(new BlockItem(builder(), Blocks.CHERRY_PRESSURE_PLATE)); + public static final Item DARK_OAK_PRESSURE_PLATE = register(new BlockItem(builder(), Blocks.DARK_OAK_PRESSURE_PLATE)); + public static final Item MANGROVE_PRESSURE_PLATE = register(new BlockItem(builder(), Blocks.MANGROVE_PRESSURE_PLATE)); + public static final Item BAMBOO_PRESSURE_PLATE = register(new BlockItem(builder(), Blocks.BAMBOO_PRESSURE_PLATE)); + public static final Item CRIMSON_PRESSURE_PLATE = register(new BlockItem(builder(), Blocks.CRIMSON_PRESSURE_PLATE)); + public static final Item WARPED_PRESSURE_PLATE = register(new BlockItem(builder(), Blocks.WARPED_PRESSURE_PLATE)); + public static final Item IRON_DOOR = register(new BlockItem(builder(), Blocks.IRON_DOOR)); + public static final Item OAK_DOOR = register(new BlockItem(builder(), Blocks.OAK_DOOR)); + public static final Item SPRUCE_DOOR = register(new BlockItem(builder(), Blocks.SPRUCE_DOOR)); + public static final Item BIRCH_DOOR = register(new BlockItem(builder(), Blocks.BIRCH_DOOR)); + public static final Item JUNGLE_DOOR = register(new BlockItem(builder(), Blocks.JUNGLE_DOOR)); + public static final Item ACACIA_DOOR = register(new BlockItem(builder(), Blocks.ACACIA_DOOR)); + public static final Item CHERRY_DOOR = register(new BlockItem(builder(), Blocks.CHERRY_DOOR)); + public static final Item DARK_OAK_DOOR = register(new BlockItem(builder(), Blocks.DARK_OAK_DOOR)); + public static final Item MANGROVE_DOOR = register(new BlockItem(builder(), Blocks.MANGROVE_DOOR)); + public static final Item BAMBOO_DOOR = register(new BlockItem(builder(), Blocks.BAMBOO_DOOR)); + public static final Item CRIMSON_DOOR = register(new BlockItem(builder(), Blocks.CRIMSON_DOOR)); + public static final Item WARPED_DOOR = register(new BlockItem(builder(), Blocks.WARPED_DOOR)); + public static final Item COPPER_DOOR = register(new BlockItem(builder(), Blocks.COPPER_DOOR)); + public static final Item EXPOSED_COPPER_DOOR = register(new BlockItem(builder(), Blocks.EXPOSED_COPPER_DOOR)); + public static final Item WEATHERED_COPPER_DOOR = register(new BlockItem(builder(), Blocks.WEATHERED_COPPER_DOOR)); + public static final Item OXIDIZED_COPPER_DOOR = register(new BlockItem(builder(), Blocks.OXIDIZED_COPPER_DOOR)); + public static final Item WAXED_COPPER_DOOR = register(new BlockItem(builder(), Blocks.WAXED_COPPER_DOOR)); + public static final Item WAXED_EXPOSED_COPPER_DOOR = register(new BlockItem(builder(), Blocks.WAXED_EXPOSED_COPPER_DOOR)); + public static final Item WAXED_WEATHERED_COPPER_DOOR = register(new BlockItem(builder(), Blocks.WAXED_WEATHERED_COPPER_DOOR)); + public static final Item WAXED_OXIDIZED_COPPER_DOOR = register(new BlockItem(builder(), Blocks.WAXED_OXIDIZED_COPPER_DOOR)); + public static final Item IRON_TRAPDOOR = register(new BlockItem(builder(), Blocks.IRON_TRAPDOOR)); + public static final Item OAK_TRAPDOOR = register(new BlockItem(builder(), Blocks.OAK_TRAPDOOR)); + public static final Item SPRUCE_TRAPDOOR = register(new BlockItem(builder(), Blocks.SPRUCE_TRAPDOOR)); + public static final Item BIRCH_TRAPDOOR = register(new BlockItem(builder(), Blocks.BIRCH_TRAPDOOR)); + public static final Item JUNGLE_TRAPDOOR = register(new BlockItem(builder(), Blocks.JUNGLE_TRAPDOOR)); + public static final Item ACACIA_TRAPDOOR = register(new BlockItem(builder(), Blocks.ACACIA_TRAPDOOR)); + public static final Item CHERRY_TRAPDOOR = register(new BlockItem(builder(), Blocks.CHERRY_TRAPDOOR)); + public static final Item DARK_OAK_TRAPDOOR = register(new BlockItem(builder(), Blocks.DARK_OAK_TRAPDOOR)); + public static final Item MANGROVE_TRAPDOOR = register(new BlockItem(builder(), Blocks.MANGROVE_TRAPDOOR)); + public static final Item BAMBOO_TRAPDOOR = register(new BlockItem(builder(), Blocks.BAMBOO_TRAPDOOR)); + public static final Item CRIMSON_TRAPDOOR = register(new BlockItem(builder(), Blocks.CRIMSON_TRAPDOOR)); + public static final Item WARPED_TRAPDOOR = register(new BlockItem(builder(), Blocks.WARPED_TRAPDOOR)); + public static final Item COPPER_TRAPDOOR = register(new BlockItem(builder(), Blocks.COPPER_TRAPDOOR)); + public static final Item EXPOSED_COPPER_TRAPDOOR = register(new BlockItem(builder(), Blocks.EXPOSED_COPPER_TRAPDOOR)); + public static final Item WEATHERED_COPPER_TRAPDOOR = register(new BlockItem(builder(), Blocks.WEATHERED_COPPER_TRAPDOOR)); + public static final Item OXIDIZED_COPPER_TRAPDOOR = register(new BlockItem(builder(), Blocks.OXIDIZED_COPPER_TRAPDOOR)); + public static final Item WAXED_COPPER_TRAPDOOR = register(new BlockItem(builder(), Blocks.WAXED_COPPER_TRAPDOOR)); + public static final Item WAXED_EXPOSED_COPPER_TRAPDOOR = register(new BlockItem(builder(), Blocks.WAXED_EXPOSED_COPPER_TRAPDOOR)); + public static final Item WAXED_WEATHERED_COPPER_TRAPDOOR = register(new BlockItem(builder(), Blocks.WAXED_WEATHERED_COPPER_TRAPDOOR)); + public static final Item WAXED_OXIDIZED_COPPER_TRAPDOOR = register(new BlockItem(builder(), Blocks.WAXED_OXIDIZED_COPPER_TRAPDOOR)); + public static final Item OAK_FENCE_GATE = register(new BlockItem(builder(), Blocks.OAK_FENCE_GATE)); + public static final Item SPRUCE_FENCE_GATE = register(new BlockItem(builder(), Blocks.SPRUCE_FENCE_GATE)); + public static final Item BIRCH_FENCE_GATE = register(new BlockItem(builder(), Blocks.BIRCH_FENCE_GATE)); + public static final Item JUNGLE_FENCE_GATE = register(new BlockItem(builder(), Blocks.JUNGLE_FENCE_GATE)); + public static final Item ACACIA_FENCE_GATE = register(new BlockItem(builder(), Blocks.ACACIA_FENCE_GATE)); + public static final Item CHERRY_FENCE_GATE = register(new BlockItem(builder(), Blocks.CHERRY_FENCE_GATE)); + public static final Item DARK_OAK_FENCE_GATE = register(new BlockItem(builder(), Blocks.DARK_OAK_FENCE_GATE)); + public static final Item MANGROVE_FENCE_GATE = register(new BlockItem(builder(), Blocks.MANGROVE_FENCE_GATE)); + public static final Item BAMBOO_FENCE_GATE = register(new BlockItem(builder(), Blocks.BAMBOO_FENCE_GATE)); + public static final Item CRIMSON_FENCE_GATE = register(new BlockItem(builder(), Blocks.CRIMSON_FENCE_GATE)); + public static final Item WARPED_FENCE_GATE = register(new BlockItem(builder(), Blocks.WARPED_FENCE_GATE)); + public static final Item POWERED_RAIL = register(new BlockItem(builder(), Blocks.POWERED_RAIL)); + public static final Item DETECTOR_RAIL = register(new BlockItem(builder(), Blocks.DETECTOR_RAIL)); + public static final Item RAIL = register(new BlockItem(builder(), Blocks.RAIL)); + public static final Item ACTIVATOR_RAIL = register(new BlockItem(builder(), Blocks.ACTIVATOR_RAIL)); public static final Item SADDLE = register(new Item("saddle", builder().stackSize(1))); public static final Item MINECART = register(new Item("minecart", builder().stackSize(1))); public static final Item CHEST_MINECART = register(new Item("chest_minecart", builder().stackSize(1))); @@ -830,8 +831,8 @@ public final class Items { public static final Item MANGROVE_CHEST_BOAT = register(new BoatItem("mangrove_chest_boat", builder().stackSize(1))); public static final Item BAMBOO_RAFT = register(new BoatItem("bamboo_raft", builder().stackSize(1))); public static final Item BAMBOO_CHEST_RAFT = register(new BoatItem("bamboo_chest_raft", builder().stackSize(1))); - public static final Item STRUCTURE_BLOCK = register(new BlockItem("structure_block", builder())); - public static final Item JIGSAW = register(new BlockItem("jigsaw", builder())); + public static final Item STRUCTURE_BLOCK = register(new BlockItem(builder(), Blocks.STRUCTURE_BLOCK)); + public static final Item JIGSAW = register(new BlockItem(builder(), Blocks.JIGSAW)); public static final Item TURTLE_HELMET = register(new ArmorItem("turtle_helmet", ArmorMaterial.TURTLE, builder().stackSize(1).maxDamage(275))); public static final Item TURTLE_SCUTE = register(new Item("turtle_scute", builder())); public static final Item ARMADILLO_SCUTE = register(new Item("armadillo_scute", builder())); @@ -888,10 +889,10 @@ public final class Items { public static final Item STICK = register(new Item("stick", builder())); public static final Item BOWL = register(new Item("bowl", builder())); public static final Item MUSHROOM_STEW = register(new Item("mushroom_stew", builder().stackSize(1))); - public static final Item STRING = register(new BlockItem("string", builder())); + public static final Item STRING = register(new BlockItem("string", builder(), Blocks.TRIPWIRE)); public static final Item FEATHER = register(new Item("feather", builder())); public static final Item GUNPOWDER = register(new Item("gunpowder", builder())); - public static final Item WHEAT_SEEDS = register(new BlockItem("wheat_seeds", builder())); + public static final Item WHEAT_SEEDS = register(new BlockItem("wheat_seeds", builder(), Blocks.WHEAT)); public static final Item WHEAT = register(new Item("wheat", builder())); public static final Item BREAD = register(new Item("bread", builder())); public static final Item LEATHER_HELMET = register(new DyeableArmorItem("leather_helmet", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(55))); @@ -924,32 +925,32 @@ public final class Items { public static final Item PAINTING = register(new Item("painting", builder())); public static final Item GOLDEN_APPLE = register(new Item("golden_apple", builder())); public static final Item ENCHANTED_GOLDEN_APPLE = register(new Item("enchanted_golden_apple", builder())); - public static final Item OAK_SIGN = register(new BlockItem("oak_sign", builder().stackSize(16))); - public static final Item SPRUCE_SIGN = register(new BlockItem("spruce_sign", builder().stackSize(16))); - public static final Item BIRCH_SIGN = register(new BlockItem("birch_sign", builder().stackSize(16))); - public static final Item JUNGLE_SIGN = register(new BlockItem("jungle_sign", builder().stackSize(16))); - public static final Item ACACIA_SIGN = register(new BlockItem("acacia_sign", builder().stackSize(16))); - public static final Item CHERRY_SIGN = register(new BlockItem("cherry_sign", builder().stackSize(16))); - public static final Item DARK_OAK_SIGN = register(new BlockItem("dark_oak_sign", builder().stackSize(16))); - public static final Item MANGROVE_SIGN = register(new BlockItem("mangrove_sign", builder().stackSize(16))); - public static final Item BAMBOO_SIGN = register(new BlockItem("bamboo_sign", builder().stackSize(16))); - public static final Item CRIMSON_SIGN = register(new BlockItem("crimson_sign", builder().stackSize(16))); - public static final Item WARPED_SIGN = register(new BlockItem("warped_sign", builder().stackSize(16))); - public static final Item OAK_HANGING_SIGN = register(new BlockItem("oak_hanging_sign", builder().stackSize(16))); - public static final Item SPRUCE_HANGING_SIGN = register(new BlockItem("spruce_hanging_sign", builder().stackSize(16))); - public static final Item BIRCH_HANGING_SIGN = register(new BlockItem("birch_hanging_sign", builder().stackSize(16))); - public static final Item JUNGLE_HANGING_SIGN = register(new BlockItem("jungle_hanging_sign", builder().stackSize(16))); - public static final Item ACACIA_HANGING_SIGN = register(new BlockItem("acacia_hanging_sign", builder().stackSize(16))); - public static final Item CHERRY_HANGING_SIGN = register(new BlockItem("cherry_hanging_sign", builder().stackSize(16))); - public static final Item DARK_OAK_HANGING_SIGN = register(new BlockItem("dark_oak_hanging_sign", builder().stackSize(16))); - public static final Item MANGROVE_HANGING_SIGN = register(new BlockItem("mangrove_hanging_sign", builder().stackSize(16))); - public static final Item BAMBOO_HANGING_SIGN = register(new BlockItem("bamboo_hanging_sign", builder().stackSize(16))); - public static final Item CRIMSON_HANGING_SIGN = register(new BlockItem("crimson_hanging_sign", builder().stackSize(16))); - public static final Item WARPED_HANGING_SIGN = register(new BlockItem("warped_hanging_sign", builder().stackSize(16))); + public static final Item OAK_SIGN = register(new BlockItem(builder().stackSize(16), Blocks.OAK_SIGN, Blocks.OAK_WALL_SIGN)); + public static final Item SPRUCE_SIGN = register(new BlockItem(builder().stackSize(16), Blocks.SPRUCE_SIGN, Blocks.SPRUCE_WALL_SIGN)); + public static final Item BIRCH_SIGN = register(new BlockItem(builder().stackSize(16), Blocks.BIRCH_SIGN, Blocks.BIRCH_WALL_SIGN)); + public static final Item JUNGLE_SIGN = register(new BlockItem(builder().stackSize(16), Blocks.JUNGLE_SIGN, Blocks.JUNGLE_WALL_SIGN)); + public static final Item ACACIA_SIGN = register(new BlockItem(builder().stackSize(16), Blocks.ACACIA_SIGN, Blocks.ACACIA_WALL_SIGN)); + public static final Item CHERRY_SIGN = register(new BlockItem(builder().stackSize(16), Blocks.CHERRY_SIGN, Blocks.CHERRY_WALL_SIGN)); + public static final Item DARK_OAK_SIGN = register(new BlockItem(builder().stackSize(16), Blocks.DARK_OAK_SIGN, Blocks.DARK_OAK_WALL_SIGN)); + public static final Item MANGROVE_SIGN = register(new BlockItem(builder().stackSize(16), Blocks.MANGROVE_SIGN, Blocks.MANGROVE_WALL_SIGN)); + public static final Item BAMBOO_SIGN = register(new BlockItem(builder().stackSize(16), Blocks.BAMBOO_SIGN, Blocks.BAMBOO_WALL_SIGN)); + public static final Item CRIMSON_SIGN = register(new BlockItem(builder().stackSize(16), Blocks.CRIMSON_SIGN, Blocks.CRIMSON_WALL_SIGN)); + public static final Item WARPED_SIGN = register(new BlockItem(builder().stackSize(16), Blocks.WARPED_SIGN, Blocks.WARPED_WALL_SIGN)); + public static final Item OAK_HANGING_SIGN = register(new BlockItem(builder().stackSize(16), Blocks.OAK_HANGING_SIGN, Blocks.OAK_WALL_HANGING_SIGN)); + public static final Item SPRUCE_HANGING_SIGN = register(new BlockItem(builder().stackSize(16), Blocks.SPRUCE_HANGING_SIGN, Blocks.SPRUCE_WALL_HANGING_SIGN)); + public static final Item BIRCH_HANGING_SIGN = register(new BlockItem(builder().stackSize(16), Blocks.BIRCH_HANGING_SIGN, Blocks.BIRCH_WALL_HANGING_SIGN)); + public static final Item JUNGLE_HANGING_SIGN = register(new BlockItem(builder().stackSize(16), Blocks.JUNGLE_HANGING_SIGN, Blocks.JUNGLE_WALL_HANGING_SIGN)); + public static final Item ACACIA_HANGING_SIGN = register(new BlockItem(builder().stackSize(16), Blocks.ACACIA_HANGING_SIGN, Blocks.ACACIA_WALL_HANGING_SIGN)); + public static final Item CHERRY_HANGING_SIGN = register(new BlockItem(builder().stackSize(16), Blocks.CHERRY_HANGING_SIGN, Blocks.CHERRY_WALL_HANGING_SIGN)); + public static final Item DARK_OAK_HANGING_SIGN = register(new BlockItem(builder().stackSize(16), Blocks.DARK_OAK_HANGING_SIGN, Blocks.DARK_OAK_WALL_HANGING_SIGN)); + public static final Item MANGROVE_HANGING_SIGN = register(new BlockItem(builder().stackSize(16), Blocks.MANGROVE_HANGING_SIGN, Blocks.MANGROVE_WALL_HANGING_SIGN)); + public static final Item BAMBOO_HANGING_SIGN = register(new BlockItem(builder().stackSize(16), Blocks.BAMBOO_HANGING_SIGN, Blocks.BAMBOO_WALL_HANGING_SIGN)); + public static final Item CRIMSON_HANGING_SIGN = register(new BlockItem(builder().stackSize(16), Blocks.CRIMSON_HANGING_SIGN, Blocks.CRIMSON_WALL_HANGING_SIGN)); + public static final Item WARPED_HANGING_SIGN = register(new BlockItem(builder().stackSize(16), Blocks.WARPED_HANGING_SIGN, Blocks.WARPED_WALL_HANGING_SIGN)); public static final Item BUCKET = register(new Item("bucket", builder().stackSize(16))); public static final Item WATER_BUCKET = register(new Item("water_bucket", builder().stackSize(1))); public static final Item LAVA_BUCKET = register(new Item("lava_bucket", builder().stackSize(1))); - public static final Item POWDER_SNOW_BUCKET = register(new BlockItem("powder_snow_bucket", builder().stackSize(1))); + public static final Item POWDER_SNOW_BUCKET = register(new BlockItem("powder_snow_bucket", builder().stackSize(1), Blocks.POWDER_SNOW)); public static final Item SNOWBALL = register(new Item("snowball", builder().stackSize(16))); public static final Item LEATHER = register(new Item("leather", builder())); public static final Item MILK_BUCKET = register(new Item("milk_bucket", builder().stackSize(1))); @@ -961,7 +962,7 @@ public final class Items { public static final Item TADPOLE_BUCKET = register(new Item("tadpole_bucket", builder().stackSize(1))); public static final Item BRICK = register(new Item("brick", builder())); public static final Item CLAY_BALL = register(new Item("clay_ball", builder())); - public static final Item DRIED_KELP_BLOCK = register(new BlockItem("dried_kelp_block", builder())); + public static final Item DRIED_KELP_BLOCK = register(new BlockItem(builder(), Blocks.DRIED_KELP_BLOCK)); public static final Item PAPER = register(new Item("paper", builder())); public static final Item BOOK = register(new Item("book", builder())); public static final Item SLIME_BALL = register(new Item("slime_ball", builder())); @@ -981,7 +982,7 @@ public final class Items { public static final Item COOKED_SALMON = register(new Item("cooked_salmon", builder())); public static final Item INK_SAC = register(new Item("ink_sac", builder())); public static final Item GLOW_INK_SAC = register(new Item("glow_ink_sac", builder())); - public static final Item COCOA_BEANS = register(new BlockItem("cocoa_beans", builder())); + public static final Item COCOA_BEANS = register(new BlockItem("cocoa_beans", builder(), Blocks.COCOA)); public static final Item WHITE_DYE = register(new DyeItem("white_dye", 0, builder())); public static final Item ORANGE_DYE = register(new DyeItem("orange_dye", 1, builder())); public static final Item MAGENTA_DYE = register(new DyeItem("magenta_dye", 2, builder())); @@ -1001,31 +1002,31 @@ public final class Items { public static final Item BONE_MEAL = register(new Item("bone_meal", builder())); public static final Item BONE = register(new Item("bone", builder())); public static final Item SUGAR = register(new Item("sugar", builder())); - public static final Item CAKE = register(new BlockItem("cake", builder().stackSize(1))); - public static final Item WHITE_BED = register(new BlockItem("white_bed", builder().stackSize(1))); - public static final Item ORANGE_BED = register(new BlockItem("orange_bed", builder().stackSize(1))); - public static final Item MAGENTA_BED = register(new BlockItem("magenta_bed", builder().stackSize(1))); - public static final Item LIGHT_BLUE_BED = register(new BlockItem("light_blue_bed", builder().stackSize(1))); - public static final Item YELLOW_BED = register(new BlockItem("yellow_bed", builder().stackSize(1))); - public static final Item LIME_BED = register(new BlockItem("lime_bed", builder().stackSize(1))); - public static final Item PINK_BED = register(new BlockItem("pink_bed", builder().stackSize(1))); - public static final Item GRAY_BED = register(new BlockItem("gray_bed", builder().stackSize(1))); - public static final Item LIGHT_GRAY_BED = register(new BlockItem("light_gray_bed", builder().stackSize(1))); - public static final Item CYAN_BED = register(new BlockItem("cyan_bed", builder().stackSize(1))); - public static final Item PURPLE_BED = register(new BlockItem("purple_bed", builder().stackSize(1))); - public static final Item BLUE_BED = register(new BlockItem("blue_bed", builder().stackSize(1))); - public static final Item BROWN_BED = register(new BlockItem("brown_bed", builder().stackSize(1))); - public static final Item GREEN_BED = register(new BlockItem("green_bed", builder().stackSize(1))); - public static final Item RED_BED = register(new BlockItem("red_bed", builder().stackSize(1))); - public static final Item BLACK_BED = register(new BlockItem("black_bed", builder().stackSize(1))); + public static final Item CAKE = register(new BlockItem(builder().stackSize(1), Blocks.CAKE)); + public static final Item WHITE_BED = register(new BlockItem(builder().stackSize(1), Blocks.WHITE_BED)); + public static final Item ORANGE_BED = register(new BlockItem(builder().stackSize(1), Blocks.ORANGE_BED)); + public static final Item MAGENTA_BED = register(new BlockItem(builder().stackSize(1), Blocks.MAGENTA_BED)); + public static final Item LIGHT_BLUE_BED = register(new BlockItem(builder().stackSize(1), Blocks.LIGHT_BLUE_BED)); + public static final Item YELLOW_BED = register(new BlockItem(builder().stackSize(1), Blocks.YELLOW_BED)); + public static final Item LIME_BED = register(new BlockItem(builder().stackSize(1), Blocks.LIME_BED)); + public static final Item PINK_BED = register(new BlockItem(builder().stackSize(1), Blocks.PINK_BED)); + public static final Item GRAY_BED = register(new BlockItem(builder().stackSize(1), Blocks.GRAY_BED)); + public static final Item LIGHT_GRAY_BED = register(new BlockItem(builder().stackSize(1), Blocks.LIGHT_GRAY_BED)); + public static final Item CYAN_BED = register(new BlockItem(builder().stackSize(1), Blocks.CYAN_BED)); + public static final Item PURPLE_BED = register(new BlockItem(builder().stackSize(1), Blocks.PURPLE_BED)); + public static final Item BLUE_BED = register(new BlockItem(builder().stackSize(1), Blocks.BLUE_BED)); + public static final Item BROWN_BED = register(new BlockItem(builder().stackSize(1), Blocks.BROWN_BED)); + public static final Item GREEN_BED = register(new BlockItem(builder().stackSize(1), Blocks.GREEN_BED)); + public static final Item RED_BED = register(new BlockItem(builder().stackSize(1), Blocks.RED_BED)); + public static final Item BLACK_BED = register(new BlockItem(builder().stackSize(1), Blocks.BLACK_BED)); public static final Item COOKIE = register(new Item("cookie", builder())); - public static final Item CRAFTER = register(new BlockItem("crafter", builder())); + public static final Item CRAFTER = register(new BlockItem(builder(), Blocks.CRAFTER)); public static final Item FILLED_MAP = register(new FilledMapItem("filled_map", builder())); public static final Item SHEARS = register(new Item("shears", builder().stackSize(1).maxDamage(238))); public static final Item MELON_SLICE = register(new Item("melon_slice", builder())); public static final Item DRIED_KELP = register(new Item("dried_kelp", builder())); - public static final Item PUMPKIN_SEEDS = register(new BlockItem("pumpkin_seeds", builder())); - public static final Item MELON_SEEDS = register(new BlockItem("melon_seeds", builder())); + public static final Item PUMPKIN_SEEDS = register(new BlockItem("pumpkin_seeds", builder(), Blocks.PUMPKIN_STEM)); + public static final Item MELON_SEEDS = register(new BlockItem("melon_seeds", builder(), Blocks.MELON_STEM)); public static final Item BEEF = register(new Item("beef", builder())); public static final Item COOKED_BEEF = register(new Item("cooked_beef", builder())); public static final Item CHICKEN = register(new Item("chicken", builder())); @@ -1035,15 +1036,15 @@ public final class Items { public static final Item BLAZE_ROD = register(new Item("blaze_rod", builder())); public static final Item GHAST_TEAR = register(new Item("ghast_tear", builder())); public static final Item GOLD_NUGGET = register(new Item("gold_nugget", builder())); - public static final Item NETHER_WART = register(new BlockItem("nether_wart", builder())); + public static final Item NETHER_WART = register(new BlockItem(builder(), Blocks.NETHER_WART)); public static final Item POTION = register(new PotionItem("potion", builder().stackSize(1))); public static final Item GLASS_BOTTLE = register(new Item("glass_bottle", builder())); public static final Item SPIDER_EYE = register(new Item("spider_eye", builder())); public static final Item FERMENTED_SPIDER_EYE = register(new Item("fermented_spider_eye", builder())); public static final Item BLAZE_POWDER = register(new Item("blaze_powder", builder())); public static final Item MAGMA_CREAM = register(new Item("magma_cream", builder())); - public static final Item BREWING_STAND = register(new BlockItem("brewing_stand", builder())); - public static final Item CAULDRON = register(new BlockItem("cauldron", builder())); + public static final Item BREWING_STAND = register(new BlockItem(builder(), Blocks.BREWING_STAND)); + public static final Item CAULDRON = register(new BlockItem(builder(), Blocks.CAULDRON, Blocks.LAVA_CAULDRON, Blocks.POWDER_SNOW_CAULDRON, Blocks.WATER_CAULDRON)); public static final Item ENDER_EYE = register(new Item("ender_eye", builder())); public static final Item GLISTERING_MELON_SLICE = register(new Item("glistering_melon_slice", builder())); public static final Item ARMADILLO_SPAWN_EGG = register(new SpawnEggItem("armadillo_spawn_egg", builder())); @@ -1134,20 +1135,20 @@ public final class Items { public static final Item MACE = register(new MaceItem("mace", builder().stackSize(1).maxDamage(250))); public static final Item ITEM_FRAME = register(new Item("item_frame", builder())); public static final Item GLOW_ITEM_FRAME = register(new Item("glow_item_frame", builder())); - public static final Item FLOWER_POT = register(new BlockItem("flower_pot", builder())); - public static final Item CARROT = register(new BlockItem("carrot", builder())); - public static final Item POTATO = register(new BlockItem("potato", builder())); + public static final Item FLOWER_POT = register(new BlockItem(builder(), Blocks.FLOWER_POT)); + public static final Item CARROT = register(new BlockItem("carrot", builder(), Blocks.CARROTS)); + public static final Item POTATO = register(new BlockItem("potato", builder(), Blocks.POTATOES)); public static final Item BAKED_POTATO = register(new Item("baked_potato", builder())); public static final Item POISONOUS_POTATO = register(new Item("poisonous_potato", builder())); public static final Item MAP = register(new MapItem("map", builder())); public static final Item GOLDEN_CARROT = register(new Item("golden_carrot", builder())); - public static final Item SKELETON_SKULL = register(new BlockItem("skeleton_skull", builder())); - public static final Item WITHER_SKELETON_SKULL = register(new BlockItem("wither_skeleton_skull", builder())); - public static final Item PLAYER_HEAD = register(new PlayerHeadItem("player_head", builder())); - public static final Item ZOMBIE_HEAD = register(new BlockItem("zombie_head", builder())); - public static final Item CREEPER_HEAD = register(new BlockItem("creeper_head", builder())); - public static final Item DRAGON_HEAD = register(new BlockItem("dragon_head", builder())); - public static final Item PIGLIN_HEAD = register(new BlockItem("piglin_head", builder())); + public static final Item SKELETON_SKULL = register(new BlockItem(builder(), Blocks.SKELETON_SKULL, Blocks.SKELETON_WALL_SKULL)); + public static final Item WITHER_SKELETON_SKULL = register(new BlockItem(builder(), Blocks.WITHER_SKELETON_SKULL, Blocks.WITHER_SKELETON_WALL_SKULL)); + public static final Item PLAYER_HEAD = register(new PlayerHeadItem(builder(), Blocks.PLAYER_HEAD, Blocks.PLAYER_WALL_HEAD)); + public static final Item ZOMBIE_HEAD = register(new BlockItem(builder(), Blocks.ZOMBIE_HEAD, Blocks.ZOMBIE_WALL_HEAD)); + public static final Item CREEPER_HEAD = register(new BlockItem(builder(), Blocks.CREEPER_HEAD, Blocks.CREEPER_WALL_HEAD)); + public static final Item DRAGON_HEAD = register(new BlockItem(builder(), Blocks.DRAGON_HEAD, Blocks.DRAGON_WALL_HEAD)); + public static final Item PIGLIN_HEAD = register(new BlockItem(builder(), Blocks.PIGLIN_HEAD, Blocks.PIGLIN_WALL_HEAD)); public static final Item NETHER_STAR = register(new Item("nether_star", builder())); public static final Item PUMPKIN_PIE = register(new Item("pumpkin_pie", builder())); public static final Item FIREWORK_ROCKET = register(new FireworkRocketItem("firework_rocket", builder())); @@ -1171,29 +1172,29 @@ public final class Items { public static final Item COMMAND_BLOCK_MINECART = register(new Item("command_block_minecart", builder().stackSize(1))); public static final Item MUTTON = register(new Item("mutton", builder())); public static final Item COOKED_MUTTON = register(new Item("cooked_mutton", builder())); - public static final Item WHITE_BANNER = register(new BannerItem("white_banner", builder().stackSize(16))); - public static final Item ORANGE_BANNER = register(new BannerItem("orange_banner", builder().stackSize(16))); - public static final Item MAGENTA_BANNER = register(new BannerItem("magenta_banner", builder().stackSize(16))); - public static final Item LIGHT_BLUE_BANNER = register(new BannerItem("light_blue_banner", builder().stackSize(16))); - public static final Item YELLOW_BANNER = register(new BannerItem("yellow_banner", builder().stackSize(16))); - public static final Item LIME_BANNER = register(new BannerItem("lime_banner", builder().stackSize(16))); - public static final Item PINK_BANNER = register(new BannerItem("pink_banner", builder().stackSize(16))); - public static final Item GRAY_BANNER = register(new BannerItem("gray_banner", builder().stackSize(16))); - public static final Item LIGHT_GRAY_BANNER = register(new BannerItem("light_gray_banner", builder().stackSize(16))); - public static final Item CYAN_BANNER = register(new BannerItem("cyan_banner", builder().stackSize(16))); - public static final Item PURPLE_BANNER = register(new BannerItem("purple_banner", builder().stackSize(16))); - public static final Item BLUE_BANNER = register(new BannerItem("blue_banner", builder().stackSize(16))); - public static final Item BROWN_BANNER = register(new BannerItem("brown_banner", builder().stackSize(16))); - public static final Item GREEN_BANNER = register(new BannerItem("green_banner", builder().stackSize(16))); - public static final Item RED_BANNER = register(new BannerItem("red_banner", builder().stackSize(16))); - public static final Item BLACK_BANNER = register(new BannerItem("black_banner", builder().stackSize(16))); + public static final Item WHITE_BANNER = register(new BannerItem(builder().stackSize(16), Blocks.WHITE_BANNER, Blocks.WHITE_WALL_BANNER)); + public static final Item ORANGE_BANNER = register(new BannerItem(builder().stackSize(16), Blocks.ORANGE_BANNER, Blocks.ORANGE_WALL_BANNER)); + public static final Item MAGENTA_BANNER = register(new BannerItem(builder().stackSize(16), Blocks.MAGENTA_BANNER, Blocks.MAGENTA_WALL_BANNER)); + public static final Item LIGHT_BLUE_BANNER = register(new BannerItem(builder().stackSize(16), Blocks.LIGHT_BLUE_BANNER, Blocks.LIGHT_BLUE_WALL_BANNER)); + public static final Item YELLOW_BANNER = register(new BannerItem(builder().stackSize(16), Blocks.YELLOW_BANNER, Blocks.YELLOW_WALL_BANNER)); + public static final Item LIME_BANNER = register(new BannerItem(builder().stackSize(16), Blocks.LIME_BANNER, Blocks.LIME_WALL_BANNER)); + public static final Item PINK_BANNER = register(new BannerItem(builder().stackSize(16), Blocks.PINK_BANNER, Blocks.PINK_WALL_BANNER)); + public static final Item GRAY_BANNER = register(new BannerItem(builder().stackSize(16), Blocks.GRAY_BANNER, Blocks.GRAY_WALL_BANNER)); + public static final Item LIGHT_GRAY_BANNER = register(new BannerItem(builder().stackSize(16), Blocks.LIGHT_GRAY_BANNER, Blocks.LIGHT_GRAY_WALL_BANNER)); + public static final Item CYAN_BANNER = register(new BannerItem(builder().stackSize(16), Blocks.CYAN_BANNER, Blocks.CYAN_WALL_BANNER)); + public static final Item PURPLE_BANNER = register(new BannerItem(builder().stackSize(16), Blocks.PURPLE_BANNER, Blocks.PURPLE_WALL_BANNER)); + public static final Item BLUE_BANNER = register(new BannerItem(builder().stackSize(16), Blocks.BLUE_BANNER, Blocks.BLUE_WALL_BANNER)); + public static final Item BROWN_BANNER = register(new BannerItem(builder().stackSize(16), Blocks.BROWN_BANNER, Blocks.BROWN_WALL_BANNER)); + public static final Item GREEN_BANNER = register(new BannerItem(builder().stackSize(16), Blocks.GREEN_BANNER, Blocks.GREEN_WALL_BANNER)); + public static final Item RED_BANNER = register(new BannerItem(builder().stackSize(16), Blocks.RED_BANNER, Blocks.RED_WALL_BANNER)); + public static final Item BLACK_BANNER = register(new BannerItem(builder().stackSize(16), Blocks.BLACK_BANNER, Blocks.BLACK_WALL_BANNER)); public static final Item END_CRYSTAL = register(new Item("end_crystal", builder())); public static final Item CHORUS_FRUIT = register(new Item("chorus_fruit", builder())); public static final Item POPPED_CHORUS_FRUIT = register(new Item("popped_chorus_fruit", builder())); - public static final Item TORCHFLOWER_SEEDS = register(new BlockItem("torchflower_seeds", builder())); - public static final Item PITCHER_POD = register(new BlockItem("pitcher_pod", builder())); + public static final Item TORCHFLOWER_SEEDS = register(new BlockItem("torchflower_seeds", builder(), Blocks.TORCHFLOWER_CROP)); + public static final Item PITCHER_POD = register(new BlockItem("pitcher_pod", builder(), Blocks.PITCHER_CROP)); public static final Item BEETROOT = register(new Item("beetroot", builder())); - public static final Item BEETROOT_SEEDS = register(new BlockItem("beetroot_seeds", builder())); + public static final Item BEETROOT_SEEDS = register(new BlockItem("beetroot_seeds", builder(), Blocks.BEETROOTS)); public static final Item BEETROOT_SOUP = register(new Item("beetroot_soup", builder().stackSize(1))); public static final Item DRAGON_BREATH = register(new Item("dragon_breath", builder())); public static final Item SPLASH_POTION = register(new PotionItem("splash_potion", builder().stackSize(1))); @@ -1229,7 +1230,7 @@ public final class Items { public static final Item HEART_OF_THE_SEA = register(new Item("heart_of_the_sea", builder())); public static final Item CROSSBOW = register(new CrossbowItem("crossbow", builder().stackSize(1).maxDamage(465))); public static final Item SUSPICIOUS_STEW = register(new Item("suspicious_stew", builder().stackSize(1))); - public static final Item LOOM = register(new BlockItem("loom", builder())); + public static final Item LOOM = register(new BlockItem(builder(), Blocks.LOOM)); public static final Item FLOWER_BANNER_PATTERN = register(new Item("flower_banner_pattern", builder().stackSize(1))); public static final Item CREEPER_BANNER_PATTERN = register(new Item("creeper_banner_pattern", builder().stackSize(1))); public static final Item SKULL_BANNER_PATTERN = register(new Item("skull_banner_pattern", builder().stackSize(1))); @@ -1239,69 +1240,69 @@ public final class Items { public static final Item FLOW_BANNER_PATTERN = register(new Item("flow_banner_pattern", builder().stackSize(1))); public static final Item GUSTER_BANNER_PATTERN = register(new Item("guster_banner_pattern", builder().stackSize(1))); public static final Item GOAT_HORN = register(new GoatHornItem("goat_horn", builder().stackSize(1))); - public static final Item COMPOSTER = register(new BlockItem("composter", builder())); - public static final Item BARREL = register(new BlockItem("barrel", builder())); - public static final Item SMOKER = register(new BlockItem("smoker", builder())); - public static final Item BLAST_FURNACE = register(new BlockItem("blast_furnace", builder())); - public static final Item CARTOGRAPHY_TABLE = register(new BlockItem("cartography_table", builder())); - public static final Item FLETCHING_TABLE = register(new BlockItem("fletching_table", builder())); - public static final Item GRINDSTONE = register(new BlockItem("grindstone", builder())); - public static final Item SMITHING_TABLE = register(new BlockItem("smithing_table", builder())); - public static final Item STONECUTTER = register(new BlockItem("stonecutter", builder())); - public static final Item BELL = register(new BlockItem("bell", builder())); - public static final Item LANTERN = register(new BlockItem("lantern", builder())); - public static final Item SOUL_LANTERN = register(new BlockItem("soul_lantern", builder())); - public static final Item SWEET_BERRIES = register(new BlockItem("sweet_berries", builder())); - public static final Item GLOW_BERRIES = register(new BlockItem("glow_berries", builder())); - public static final Item CAMPFIRE = register(new BlockItem("campfire", builder())); - public static final Item SOUL_CAMPFIRE = register(new BlockItem("soul_campfire", builder())); - public static final Item SHROOMLIGHT = register(new BlockItem("shroomlight", builder())); + public static final Item COMPOSTER = register(new BlockItem(builder(), Blocks.COMPOSTER)); + public static final Item BARREL = register(new BlockItem(builder(), Blocks.BARREL)); + public static final Item SMOKER = register(new BlockItem(builder(), Blocks.SMOKER)); + public static final Item BLAST_FURNACE = register(new BlockItem(builder(), Blocks.BLAST_FURNACE)); + public static final Item CARTOGRAPHY_TABLE = register(new BlockItem(builder(), Blocks.CARTOGRAPHY_TABLE)); + public static final Item FLETCHING_TABLE = register(new BlockItem(builder(), Blocks.FLETCHING_TABLE)); + public static final Item GRINDSTONE = register(new BlockItem(builder(), Blocks.GRINDSTONE)); + public static final Item SMITHING_TABLE = register(new BlockItem(builder(), Blocks.SMITHING_TABLE)); + public static final Item STONECUTTER = register(new BlockItem(builder(), Blocks.STONECUTTER)); + public static final Item BELL = register(new BlockItem(builder(), Blocks.BELL)); + public static final Item LANTERN = register(new BlockItem(builder(), Blocks.LANTERN)); + public static final Item SOUL_LANTERN = register(new BlockItem(builder(), Blocks.SOUL_LANTERN)); + public static final Item SWEET_BERRIES = register(new BlockItem("sweet_berries", builder(), Blocks.SWEET_BERRY_BUSH)); + public static final Item GLOW_BERRIES = register(new BlockItem("glow_berries", builder(), Blocks.CAVE_VINES)); + public static final Item CAMPFIRE = register(new BlockItem(builder(), Blocks.CAMPFIRE)); + public static final Item SOUL_CAMPFIRE = register(new BlockItem(builder(), Blocks.SOUL_CAMPFIRE)); + public static final Item SHROOMLIGHT = register(new BlockItem(builder(), Blocks.SHROOMLIGHT)); public static final Item HONEYCOMB = register(new Item("honeycomb", builder())); - public static final Item BEE_NEST = register(new BlockItem("bee_nest", builder())); - public static final Item BEEHIVE = register(new BlockItem("beehive", builder())); + public static final Item BEE_NEST = register(new BlockItem(builder(), Blocks.BEE_NEST)); + public static final Item BEEHIVE = register(new BlockItem(builder(), Blocks.BEEHIVE)); public static final Item HONEY_BOTTLE = register(new Item("honey_bottle", builder().stackSize(16))); - public static final Item HONEYCOMB_BLOCK = register(new BlockItem("honeycomb_block", builder())); - public static final Item LODESTONE = register(new BlockItem("lodestone", builder())); - public static final Item CRYING_OBSIDIAN = register(new BlockItem("crying_obsidian", builder())); - public static final Item BLACKSTONE = register(new BlockItem("blackstone", builder())); - public static final Item BLACKSTONE_SLAB = register(new BlockItem("blackstone_slab", builder())); - public static final Item BLACKSTONE_STAIRS = register(new BlockItem("blackstone_stairs", builder())); - public static final Item GILDED_BLACKSTONE = register(new BlockItem("gilded_blackstone", builder())); - public static final Item POLISHED_BLACKSTONE = register(new BlockItem("polished_blackstone", builder())); - public static final Item POLISHED_BLACKSTONE_SLAB = register(new BlockItem("polished_blackstone_slab", builder())); - public static final Item POLISHED_BLACKSTONE_STAIRS = register(new BlockItem("polished_blackstone_stairs", builder())); - public static final Item CHISELED_POLISHED_BLACKSTONE = register(new BlockItem("chiseled_polished_blackstone", builder())); - public static final Item POLISHED_BLACKSTONE_BRICKS = register(new BlockItem("polished_blackstone_bricks", builder())); - public static final Item POLISHED_BLACKSTONE_BRICK_SLAB = register(new BlockItem("polished_blackstone_brick_slab", builder())); - public static final Item POLISHED_BLACKSTONE_BRICK_STAIRS = register(new BlockItem("polished_blackstone_brick_stairs", builder())); - public static final Item CRACKED_POLISHED_BLACKSTONE_BRICKS = register(new BlockItem("cracked_polished_blackstone_bricks", builder())); - public static final Item RESPAWN_ANCHOR = register(new BlockItem("respawn_anchor", builder())); - public static final Item CANDLE = register(new BlockItem("candle", builder())); - public static final Item WHITE_CANDLE = register(new BlockItem("white_candle", builder())); - public static final Item ORANGE_CANDLE = register(new BlockItem("orange_candle", builder())); - public static final Item MAGENTA_CANDLE = register(new BlockItem("magenta_candle", builder())); - public static final Item LIGHT_BLUE_CANDLE = register(new BlockItem("light_blue_candle", builder())); - public static final Item YELLOW_CANDLE = register(new BlockItem("yellow_candle", builder())); - public static final Item LIME_CANDLE = register(new BlockItem("lime_candle", builder())); - public static final Item PINK_CANDLE = register(new BlockItem("pink_candle", builder())); - public static final Item GRAY_CANDLE = register(new BlockItem("gray_candle", builder())); - public static final Item LIGHT_GRAY_CANDLE = register(new BlockItem("light_gray_candle", builder())); - public static final Item CYAN_CANDLE = register(new BlockItem("cyan_candle", builder())); - public static final Item PURPLE_CANDLE = register(new BlockItem("purple_candle", builder())); - public static final Item BLUE_CANDLE = register(new BlockItem("blue_candle", builder())); - public static final Item BROWN_CANDLE = register(new BlockItem("brown_candle", builder())); - public static final Item GREEN_CANDLE = register(new BlockItem("green_candle", builder())); - public static final Item RED_CANDLE = register(new BlockItem("red_candle", builder())); - public static final Item BLACK_CANDLE = register(new BlockItem("black_candle", builder())); - public static final Item SMALL_AMETHYST_BUD = register(new BlockItem("small_amethyst_bud", builder())); - public static final Item MEDIUM_AMETHYST_BUD = register(new BlockItem("medium_amethyst_bud", builder())); - public static final Item LARGE_AMETHYST_BUD = register(new BlockItem("large_amethyst_bud", builder())); - public static final Item AMETHYST_CLUSTER = register(new BlockItem("amethyst_cluster", builder())); - public static final Item POINTED_DRIPSTONE = register(new BlockItem("pointed_dripstone", builder())); - public static final Item OCHRE_FROGLIGHT = register(new BlockItem("ochre_froglight", builder())); - public static final Item VERDANT_FROGLIGHT = register(new BlockItem("verdant_froglight", builder())); - public static final Item PEARLESCENT_FROGLIGHT = register(new BlockItem("pearlescent_froglight", builder())); - public static final Item FROGSPAWN = register(new BlockItem("frogspawn", builder())); + public static final Item HONEYCOMB_BLOCK = register(new BlockItem(builder(), Blocks.HONEYCOMB_BLOCK)); + public static final Item LODESTONE = register(new BlockItem(builder(), Blocks.LODESTONE)); + public static final Item CRYING_OBSIDIAN = register(new BlockItem(builder(), Blocks.CRYING_OBSIDIAN)); + public static final Item BLACKSTONE = register(new BlockItem(builder(), Blocks.BLACKSTONE)); + public static final Item BLACKSTONE_SLAB = register(new BlockItem(builder(), Blocks.BLACKSTONE_SLAB)); + public static final Item BLACKSTONE_STAIRS = register(new BlockItem(builder(), Blocks.BLACKSTONE_STAIRS)); + public static final Item GILDED_BLACKSTONE = register(new BlockItem(builder(), Blocks.GILDED_BLACKSTONE)); + public static final Item POLISHED_BLACKSTONE = register(new BlockItem(builder(), Blocks.POLISHED_BLACKSTONE)); + public static final Item POLISHED_BLACKSTONE_SLAB = register(new BlockItem(builder(), Blocks.POLISHED_BLACKSTONE_SLAB)); + public static final Item POLISHED_BLACKSTONE_STAIRS = register(new BlockItem(builder(), Blocks.POLISHED_BLACKSTONE_STAIRS)); + public static final Item CHISELED_POLISHED_BLACKSTONE = register(new BlockItem(builder(), Blocks.CHISELED_POLISHED_BLACKSTONE)); + public static final Item POLISHED_BLACKSTONE_BRICKS = register(new BlockItem(builder(), Blocks.POLISHED_BLACKSTONE_BRICKS)); + public static final Item POLISHED_BLACKSTONE_BRICK_SLAB = register(new BlockItem(builder(), Blocks.POLISHED_BLACKSTONE_BRICK_SLAB)); + public static final Item POLISHED_BLACKSTONE_BRICK_STAIRS = register(new BlockItem(builder(), Blocks.POLISHED_BLACKSTONE_BRICK_STAIRS)); + public static final Item CRACKED_POLISHED_BLACKSTONE_BRICKS = register(new BlockItem(builder(), Blocks.CRACKED_POLISHED_BLACKSTONE_BRICKS)); + public static final Item RESPAWN_ANCHOR = register(new BlockItem(builder(), Blocks.RESPAWN_ANCHOR)); + public static final Item CANDLE = register(new BlockItem(builder(), Blocks.CANDLE)); + public static final Item WHITE_CANDLE = register(new BlockItem(builder(), Blocks.WHITE_CANDLE)); + public static final Item ORANGE_CANDLE = register(new BlockItem(builder(), Blocks.ORANGE_CANDLE)); + public static final Item MAGENTA_CANDLE = register(new BlockItem(builder(), Blocks.MAGENTA_CANDLE)); + public static final Item LIGHT_BLUE_CANDLE = register(new BlockItem(builder(), Blocks.LIGHT_BLUE_CANDLE)); + public static final Item YELLOW_CANDLE = register(new BlockItem(builder(), Blocks.YELLOW_CANDLE)); + public static final Item LIME_CANDLE = register(new BlockItem(builder(), Blocks.LIME_CANDLE)); + public static final Item PINK_CANDLE = register(new BlockItem(builder(), Blocks.PINK_CANDLE)); + public static final Item GRAY_CANDLE = register(new BlockItem(builder(), Blocks.GRAY_CANDLE)); + public static final Item LIGHT_GRAY_CANDLE = register(new BlockItem(builder(), Blocks.LIGHT_GRAY_CANDLE)); + public static final Item CYAN_CANDLE = register(new BlockItem(builder(), Blocks.CYAN_CANDLE)); + public static final Item PURPLE_CANDLE = register(new BlockItem(builder(), Blocks.PURPLE_CANDLE)); + public static final Item BLUE_CANDLE = register(new BlockItem(builder(), Blocks.BLUE_CANDLE)); + public static final Item BROWN_CANDLE = register(new BlockItem(builder(), Blocks.BROWN_CANDLE)); + public static final Item GREEN_CANDLE = register(new BlockItem(builder(), Blocks.GREEN_CANDLE)); + public static final Item RED_CANDLE = register(new BlockItem(builder(), Blocks.RED_CANDLE)); + public static final Item BLACK_CANDLE = register(new BlockItem(builder(), Blocks.BLACK_CANDLE)); + public static final Item SMALL_AMETHYST_BUD = register(new BlockItem(builder(), Blocks.SMALL_AMETHYST_BUD)); + public static final Item MEDIUM_AMETHYST_BUD = register(new BlockItem(builder(), Blocks.MEDIUM_AMETHYST_BUD)); + public static final Item LARGE_AMETHYST_BUD = register(new BlockItem(builder(), Blocks.LARGE_AMETHYST_BUD)); + public static final Item AMETHYST_CLUSTER = register(new BlockItem(builder(), Blocks.AMETHYST_CLUSTER)); + public static final Item POINTED_DRIPSTONE = register(new BlockItem(builder(), Blocks.POINTED_DRIPSTONE)); + public static final Item OCHRE_FROGLIGHT = register(new BlockItem(builder(), Blocks.OCHRE_FROGLIGHT)); + public static final Item VERDANT_FROGLIGHT = register(new BlockItem(builder(), Blocks.VERDANT_FROGLIGHT)); + public static final Item PEARLESCENT_FROGLIGHT = register(new BlockItem(builder(), Blocks.PEARLESCENT_FROGLIGHT)); + public static final Item FROGSPAWN = register(new BlockItem(builder(), Blocks.FROGSPAWN)); public static final Item ECHO_SHARD = register(new Item("echo_shard", builder())); public static final Item BRUSH = register(new Item("brush", builder().stackSize(1).maxDamage(64))); public static final Item NETHERITE_UPGRADE_SMITHING_TEMPLATE = register(new Item("netherite_upgrade_smithing_template", builder())); @@ -1346,26 +1347,26 @@ public final class Items { public static final Item SHELTER_POTTERY_SHERD = register(new Item("shelter_pottery_sherd", builder())); public static final Item SKULL_POTTERY_SHERD = register(new Item("skull_pottery_sherd", builder())); public static final Item SNORT_POTTERY_SHERD = register(new Item("snort_pottery_sherd", builder())); - public static final Item COPPER_GRATE = register(new BlockItem("copper_grate", builder())); - public static final Item EXPOSED_COPPER_GRATE = register(new BlockItem("exposed_copper_grate", builder())); - public static final Item WEATHERED_COPPER_GRATE = register(new BlockItem("weathered_copper_grate", builder())); - public static final Item OXIDIZED_COPPER_GRATE = register(new BlockItem("oxidized_copper_grate", builder())); - public static final Item WAXED_COPPER_GRATE = register(new BlockItem("waxed_copper_grate", builder())); - public static final Item WAXED_EXPOSED_COPPER_GRATE = register(new BlockItem("waxed_exposed_copper_grate", builder())); - public static final Item WAXED_WEATHERED_COPPER_GRATE = register(new BlockItem("waxed_weathered_copper_grate", builder())); - public static final Item WAXED_OXIDIZED_COPPER_GRATE = register(new BlockItem("waxed_oxidized_copper_grate", builder())); - public static final Item COPPER_BULB = register(new BlockItem("copper_bulb", builder())); - public static final Item EXPOSED_COPPER_BULB = register(new BlockItem("exposed_copper_bulb", builder())); - public static final Item WEATHERED_COPPER_BULB = register(new BlockItem("weathered_copper_bulb", builder())); - public static final Item OXIDIZED_COPPER_BULB = register(new BlockItem("oxidized_copper_bulb", builder())); - public static final Item WAXED_COPPER_BULB = register(new BlockItem("waxed_copper_bulb", builder())); - public static final Item WAXED_EXPOSED_COPPER_BULB = register(new BlockItem("waxed_exposed_copper_bulb", builder())); - public static final Item WAXED_WEATHERED_COPPER_BULB = register(new BlockItem("waxed_weathered_copper_bulb", builder())); - public static final Item WAXED_OXIDIZED_COPPER_BULB = register(new BlockItem("waxed_oxidized_copper_bulb", builder())); - public static final Item TRIAL_SPAWNER = register(new BlockItem("trial_spawner", builder())); + public static final Item COPPER_GRATE = register(new BlockItem(builder(), Blocks.COPPER_GRATE)); + public static final Item EXPOSED_COPPER_GRATE = register(new BlockItem(builder(), Blocks.EXPOSED_COPPER_GRATE)); + public static final Item WEATHERED_COPPER_GRATE = register(new BlockItem(builder(), Blocks.WEATHERED_COPPER_GRATE)); + public static final Item OXIDIZED_COPPER_GRATE = register(new BlockItem(builder(), Blocks.OXIDIZED_COPPER_GRATE)); + public static final Item WAXED_COPPER_GRATE = register(new BlockItem(builder(), Blocks.WAXED_COPPER_GRATE)); + public static final Item WAXED_EXPOSED_COPPER_GRATE = register(new BlockItem(builder(), Blocks.WAXED_EXPOSED_COPPER_GRATE)); + public static final Item WAXED_WEATHERED_COPPER_GRATE = register(new BlockItem(builder(), Blocks.WAXED_WEATHERED_COPPER_GRATE)); + public static final Item WAXED_OXIDIZED_COPPER_GRATE = register(new BlockItem(builder(), Blocks.WAXED_OXIDIZED_COPPER_GRATE)); + public static final Item COPPER_BULB = register(new BlockItem(builder(), Blocks.COPPER_BULB)); + public static final Item EXPOSED_COPPER_BULB = register(new BlockItem(builder(), Blocks.EXPOSED_COPPER_BULB)); + public static final Item WEATHERED_COPPER_BULB = register(new BlockItem(builder(), Blocks.WEATHERED_COPPER_BULB)); + public static final Item OXIDIZED_COPPER_BULB = register(new BlockItem(builder(), Blocks.OXIDIZED_COPPER_BULB)); + public static final Item WAXED_COPPER_BULB = register(new BlockItem(builder(), Blocks.WAXED_COPPER_BULB)); + public static final Item WAXED_EXPOSED_COPPER_BULB = register(new BlockItem(builder(), Blocks.WAXED_EXPOSED_COPPER_BULB)); + public static final Item WAXED_WEATHERED_COPPER_BULB = register(new BlockItem(builder(), Blocks.WAXED_WEATHERED_COPPER_BULB)); + public static final Item WAXED_OXIDIZED_COPPER_BULB = register(new BlockItem(builder(), Blocks.WAXED_OXIDIZED_COPPER_BULB)); + public static final Item TRIAL_SPAWNER = register(new BlockItem(builder(), Blocks.TRIAL_SPAWNER)); public static final Item TRIAL_KEY = register(new Item("trial_key", builder())); public static final Item OMINOUS_TRIAL_KEY = register(new Item("ominous_trial_key", builder())); - public static final Item VAULT = register(new BlockItem("vault", builder())); + public static final Item VAULT = register(new BlockItem(builder(), Blocks.VAULT)); public static final Item OMINOUS_BOTTLE = register(new Item("ominous_bottle", builder())); public static final Item BREEZE_ROD = register(new Item("breeze_rod", builder())); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index 6c2678db9..b53843882 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -35,6 +35,7 @@ import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.inventory.item.BannerPattern; import org.geysermc.geyser.inventory.item.DyeColor; +import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.registry.JavaRegistry; @@ -199,8 +200,8 @@ public class BannerItem extends BlockItem { return null; } - public BannerItem(String javaIdentifier, Builder builder) { - super(javaIdentifier, builder); + public BannerItem(Builder builder, Block block, Block... otherBlocks) { + super(builder, block, otherBlocks); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BlockItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BlockItem.java index 0dbf0971a..30a31a100 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BlockItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BlockItem.java @@ -25,11 +25,26 @@ package org.geysermc.geyser.item.type; -/** - * TODO needed? - */ +import org.geysermc.geyser.level.block.type.Block; + public class BlockItem extends Item { - public BlockItem(String javaIdentifier, Builder builder) { + public BlockItem(Builder builder, Block block, Block... otherBlocks) { + super(block.javaIdentifier().value(), builder); + + // Ensure this item can be looked up by its block(s) + registerBlock(block, this); + for (Block otherBlock : otherBlocks) { + registerBlock(otherBlock, this); + } + } + + // Use this constructor if the item name is not the same as its primary block + public BlockItem(String javaIdentifier, Builder builder, Block block, Block... otherBlocks) { super(javaIdentifier, builder); + + registerBlock(block, this); + for (Block otherBlock : otherBlocks) { + registerBlock(otherBlock, this); + } } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java index 2631bf9be..578ba4063 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DecoratedPotItem.java @@ -27,6 +27,7 @@ package org.geysermc.geyser.item.type; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtType; +import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; @@ -38,8 +39,8 @@ import java.util.List; public class DecoratedPotItem extends BlockItem { - public DecoratedPotItem(String javaIdentifier, Builder builder) { - super(javaIdentifier, builder); + public DecoratedPotItem(Builder builder, Block block, Block... otherBlocks) { + super(builder, block, otherBlocks); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/item/type/Item.java b/core/src/main/java/org/geysermc/geyser/item/type/Item.java index fc4fda07c..1ec410eaf 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/Item.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/Item.java @@ -35,6 +35,7 @@ import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.inventory.item.Enchantment; import org.geysermc.geyser.item.Items; +import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.session.GeyserSession; @@ -49,20 +50,12 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponen import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; public class Item { - /** - * This is a map from Java-only enchantments to their translation keys so that we can - * map these enchantments to Bedrock clients, since they don't actually exist there. - */ - private static final Map ENCHANTMENT_TRANSLATION_KEYS = Map.of( - Enchantment.JavaEnchantment.SWEEPING_EDGE, "enchantment.minecraft.sweeping", - Enchantment.JavaEnchantment.DENSITY, "enchantment.minecraft.density", - Enchantment.JavaEnchantment.BREACH, "enchantment.minecraft.breach", - Enchantment.JavaEnchantment.WIND_BURST, "enchantment.minecraft.wind_burst"); - + private static final Map BLOCK_TO_ITEM = new HashMap<>(); private final String javaIdentifier; private int javaId = -1; private final int stackSize; @@ -233,6 +226,16 @@ public class Item { // } } + /** + * This is a map from Java-only enchantments to their translation keys so that we can + * map these enchantments to Bedrock clients, since they don't actually exist there. + */ + private static final Map ENCHANTMENT_TRANSLATION_KEYS = Map.of( + Enchantment.JavaEnchantment.SWEEPING_EDGE, "enchantment.minecraft.sweeping", + Enchantment.JavaEnchantment.DENSITY, "enchantment.minecraft.density", + Enchantment.JavaEnchantment.BREACH, "enchantment.minecraft.breach", + Enchantment.JavaEnchantment.WIND_BURST, "enchantment.minecraft.wind_burst"); + protected final @Nullable NbtMap remapEnchantment(GeyserSession session, int enchantId, int level, BedrockItemBuilder builder) { // TODO verify // TODO streamline Enchantment process @@ -281,6 +284,18 @@ public class Item { '}'; } + /** + * @return the block associated with this item, or air if nothing + */ + @NonNull + public static Item byBlock(Block block) { + return BLOCK_TO_ITEM.getOrDefault(block, Items.AIR); + } + + protected static void registerBlock(Block block, Item item) { + BLOCK_TO_ITEM.put(block, item); + } + public static Builder builder() { return new Builder(); } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java index 0cdbe70f1..86572d60c 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java @@ -27,6 +27,7 @@ package org.geysermc.geyser.item.type; import com.github.steveice10.mc.auth.data.GameProfile; import org.checkerframework.checker.nullness.qual.NonNull; +import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.text.MinecraftLocale; @@ -34,9 +35,9 @@ import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; -public class PlayerHeadItem extends Item { - public PlayerHeadItem(String javaIdentifier, Builder builder) { - super(javaIdentifier, builder); +public class PlayerHeadItem extends BlockItem { + public PlayerHeadItem(Builder builder, Block block, Block... otherBlocks) { + super(builder, block, otherBlocks); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java index 6b2d589d6..a539fa739 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShulkerBoxItem.java @@ -30,6 +30,7 @@ import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.item.Items; +import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; @@ -42,8 +43,8 @@ import java.util.ArrayList; import java.util.List; public class ShulkerBoxItem extends BlockItem { - public ShulkerBoxItem(String javaIdentifier, Builder builder) { - super(javaIdentifier, builder); + public ShulkerBoxItem(Builder builder, Block block, Block... otherBlocks) { + super(builder, block, otherBlocks); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java b/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java index a64e5c1c8..9b390f6ee 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java @@ -249,25 +249,6 @@ public final class BlockStateValues { return ALL_CAULDRONS.contains(state); } - /** - * All double chest values are part of the block state in Java and part of the block entity tag in Bedrock. - * This gives the DoubleChestValue that can be calculated into the final tag. - * - * @return The map of all DoubleChestValues. - */ - public static Int2ObjectMap getDoubleChestValues() { - return DOUBLE_CHEST_VALUES; - } - - /** - * Get the Int2ObjectMap of flower pot block states to containing plant - * - * @return Int2ObjectMap of flower pot values - */ - public static Int2ObjectMap getFlowerPotValues() { - return FLOWER_POT_VALUES; - } - /** * @return a set of all forward-facing jigsaws, to use as a fallback if NBT is missing. */ @@ -282,26 +263,6 @@ public final class BlockStateValues { return LECTERN_BOOK_STATES; } - /** - * The note that noteblocks output when hit is part of the block state in Java but sent as a BlockEventPacket in Bedrock. - * This gives an integer pitch that Bedrock can use. - * - * @param state BlockState of the block - * @return note block note integer or -1 if not present - */ - public static int getNoteblockPitch(int state) { - return NOTEBLOCK_PITCHES.getOrDefault(state, -1); - } - - /** - * Get the Int2BooleanMap showing if a piston block state is extended or not. - * - * @return the Int2BooleanMap of piston extensions. - */ - public static Int2BooleanMap getPistonValues() { - return PISTON_VALUES; - } - public static boolean isStickyPiston(int blockState) { return STICKY_PISTONS.contains(blockState); } @@ -435,16 +396,6 @@ public final class BlockStateValues { return WATER_LEVEL.getOrDefault(state, -1); } - /** - * Check if a block is the upper half of a door. - * - * @param state BlockState of the block - * @return True if the block is the upper half of a door - */ - public static boolean isUpperDoor(int state) { - return UPPER_DOORS.contains(state); - } - /** * Get the height of water from the block state * This is used in FishingHookEntity to create splash sounds when the hook hits the water. In addition, diff --git a/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java b/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java index 142708dd9..485d52161 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java @@ -82,7 +82,7 @@ public final class Blocks { .intState(STAGE, 0, 1) .booleanState(WATERLOGGED))); public static final Block BEDROCK = register(new Block("bedrock", builder().destroyTime(-1.0f))); - public static final Block WATER = register(new Block("water", builder().destroyTime(100.0f).pushReaction(PistonBehavior.DESTROY) + public static final Block WATER = register(new WaterBlock("water", builder().destroyTime(100.0f).pushReaction(PistonBehavior.DESTROY) .intState(LEVEL, 0, 15))); public static final Block LAVA = register(new Block("lava", builder().destroyTime(100.0f).pushReaction(PistonBehavior.DESTROY) .intState(LEVEL, 0, 15))); @@ -379,7 +379,7 @@ public final class Blocks { .booleanState(UP) .booleanState(WEST))); public static final Block SOUL_FIRE = register(new Block("soul_fire", builder().pushReaction(PistonBehavior.DESTROY))); - public static final Block SPAWNER = register(new Block("spawner", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(5.0f))); + public static final Block SPAWNER = register(new SpawnerBlock("spawner", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(5.0f))); public static final Block OAK_STAIRS = register(new Block("oak_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") @@ -403,7 +403,7 @@ public final class Blocks { .intState(AGE_7, 0, 7))); public static final Block FARMLAND = register(new Block("farmland", builder().destroyTime(0.6f) .intState(MOISTURE, 0, 7))); - public static final Block FURNACE = register(new Block("furnace", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(3.5f) + public static final Block FURNACE = register(new FurnaceBlock("furnace", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(LIT))); public static final Block OAK_SIGN = register(new Block("oak_sign", builder().setBlockEntity().destroyTime(1.0f) @@ -823,10 +823,10 @@ public final class Blocks { .booleanState(HAS_BOTTLE_1) .booleanState(HAS_BOTTLE_2))); public static final Block CAULDRON = register(new CauldronBlock("cauldron", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); - public static final Block WATER_CAULDRON = register(new Block("water_cauldron", builder().requiresCorrectToolForDrops().destroyTime(2.0f) + public static final Block WATER_CAULDRON = register(new CauldronBlock("water_cauldron", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .intState(LEVEL_CAULDRON, 1, 3))); - public static final Block LAVA_CAULDRON = register(new Block("lava_cauldron", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); - public static final Block POWDER_SNOW_CAULDRON = register(new Block("powder_snow_cauldron", builder().requiresCorrectToolForDrops().destroyTime(2.0f) + public static final Block LAVA_CAULDRON = register(new CauldronBlock("lava_cauldron", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); + public static final Block POWDER_SNOW_CAULDRON = register(new CauldronBlock("powder_snow_cauldron", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .intState(LEVEL_CAULDRON, 1, 3))); public static final Block END_PORTAL = register(new Block("end_portal", builder().setBlockEntity().destroyTime(-1.0f).pushReaction(PistonBehavior.BLOCK))); public static final Block END_PORTAL_FRAME = register(new Block("end_portal_frame", builder().destroyTime(-1.0f) @@ -2179,7 +2179,7 @@ public final class Blocks { public static final Block BEEHIVE = register(new Block("beehive", builder().setBlockEntity().destroyTime(0.6f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .intState(LEVEL_HONEY, 0, 5))); - public static final Block HONEY_BLOCK = register(new Block("honey_block", builder())); + public static final Block HONEY_BLOCK = register(new HoneyBlock("honey_block", builder())); public static final Block HONEYCOMB_BLOCK = register(new Block("honeycomb_block", builder().destroyTime(0.6f))); public static final Block NETHERITE_BLOCK = register(new Block("netherite_block", builder().requiresCorrectToolForDrops().destroyTime(50.0f))); public static final Block ANCIENT_DEBRIS = register(new Block("ancient_debris", builder().requiresCorrectToolForDrops().destroyTime(30.0f))); diff --git a/core/src/main/java/org/geysermc/geyser/level/block/property/Property.java b/core/src/main/java/org/geysermc/geyser/level/block/property/Property.java index da68c54e4..ca5f62daa 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/property/Property.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/property/Property.java @@ -32,6 +32,10 @@ public class Property> { this.name = name; } + public String name() { + return name; + } + @Override public String toString() { return getClass().getSimpleName() + "[" + name + "]"; diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java b/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java index 3114f31f9..491894a35 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java @@ -25,21 +25,24 @@ package org.geysermc.geyser.level.block.type; -import it.unimi.dsi.fastutil.Pair; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.objects.Reference2ObjectArrayMap; import it.unimi.dsi.fastutil.objects.Reference2ObjectMap; +import it.unimi.dsi.fastutil.objects.Reference2ObjectMaps; +import net.kyori.adventure.key.Key; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; +import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.level.block.Blocks; +import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.property.Property; import org.geysermc.geyser.level.physics.PistonBehavior; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.mcprotocollib.protocol.data.game.Identifier; +import org.intellij.lang.annotations.Subst; import java.util.*; import java.util.stream.Stream; @@ -47,20 +50,21 @@ import java.util.stream.Stream; public class Block { public static final int JAVA_AIR_ID = 0; - private final String javaIdentifier; + private final Key javaIdentifier; private final boolean requiresCorrectToolForDrops; private final boolean hasBlockEntity; private final float destroyTime; private final @NonNull PistonBehavior pushReaction; + protected Item item = null; private int javaId = -1; - public Block(String javaIdentifier, Builder builder) { - this.javaIdentifier = Identifier.formalize(javaIdentifier).intern(); + public Block(@Subst("empty") String javaIdentifier, Builder builder) { + this.javaIdentifier = Key.key(javaIdentifier); this.requiresCorrectToolForDrops = builder.requiresCorrectToolForDrops; this.hasBlockEntity = builder.hasBlockEntity; this.destroyTime = builder.destroyTime; this.pushReaction = builder.pushReaction; - builder.build(this); + processStates(builder.build(this)); } public void updateBlock(GeyserSession session, BlockState state, Vector3i position) { @@ -114,7 +118,8 @@ public class Block { UpdateBlockPacket waterPacket = new UpdateBlockPacket(); waterPacket.setDataLayer(1); waterPacket.setBlockPosition(position); - if (BlockRegistries.WATERLOGGED.get().get(state.javaId())) { + Boolean waterlogged = state.getValue(Properties.WATERLOGGED); + if (waterlogged == Boolean.TRUE) { waterPacket.setDefinition(session.getBlockMappings().getBedrockWater()); } else { waterPacket.setDefinition(session.getBlockMappings().getBedrockAir()); @@ -129,7 +134,21 @@ public class Block { } } - public String javaIdentifier() { + public Item asItem() { + if (this.item == null) { + return this.item = Item.byBlock(this); + } + return this.item; + } + + /** + * A list of BlockStates is created pertaining to this block. Do we need any of them? If so, override this method. + */ + protected void processStates(List states) { + } + + @NonNull + public Key javaIdentifier() { return javaIdentifier; } @@ -163,7 +182,7 @@ public class Block { @Override public String toString() { - return "Item{" + + return "Block{" + "javaIdentifier='" + javaIdentifier + '\'' + ", javaId=" + javaId + '}'; @@ -229,14 +248,27 @@ public class Block { return this; } - private void build(Block block) { + private List build(Block block) { if (states.isEmpty()) { - BlockRegistries.BLOCK_STATES.get().add(new BlockState(block, BlockRegistries.BLOCK_STATES.get().size())); + BlockState state = new BlockState(block, BlockRegistries.BLOCK_STATES.get().size()); + BlockRegistries.BLOCK_STATES.get().add(state); + return List.of(state); + } else if (states.size() == 1) { + // We can optimize because we don't need to worry about combinations + Map.Entry, List>> property = this.states.entrySet().stream().findFirst().orElseThrow(); + List states = new ArrayList<>(property.getValue().size()); + property.getValue().forEach(value -> { + Reference2ObjectMap, Comparable> propertyMap = Reference2ObjectMaps.singleton(property.getKey(), value); + BlockState state = new BlockState(block, BlockRegistries.BLOCK_STATES.get().size(), propertyMap); + BlockRegistries.BLOCK_STATES.get().add(state); + states.add(state); + }); + return states; } else { // Think of this stream as another list containing, at the start, one empty list. // It's two collections. Not a stream from the empty list. - Stream, Comparable>>> stream = Stream.of(Collections.emptyList()); - for (var state : this.states.entrySet()) { + Stream>> stream = Stream.of(Collections.emptyList()); + for (var values : this.states.values()) { // OK, so here's how I understand this works. Because this was staring at vanilla Java code trying // to figure out exactly how it works so we don't have any discrepencies. // For each existing pair in the list, a new list is created, adding one of the new values. @@ -247,24 +279,29 @@ public class Block { // or it may be populated if this is not the first property. // We're about to create a new stream, each with a new list, // for every previous property - state.getValue().stream().map(value -> { + values.stream().map(value -> { var newProperties = new ArrayList<>(aPreviousPropertiesList); - newProperties.add(Pair.of(state.getKey(), value)); + newProperties.add(value); return newProperties; })); } + List states = new ArrayList<>(); // Now we have a list of Pairs. Each list is a block state! // If we have two boolean properties: up [true/false] and down [true/false], // We'll see [up=true,down=true], [up=false,down=true], [up=true,down=false], [up=false,down=false] - stream.forEach(properties -> { - Reference2ObjectMap, Comparable> propertyMap = new Reference2ObjectArrayMap<>(properties.size()); - for (int i = 0; i < properties.size(); i++) { - Pair, Comparable> property = properties.get(i); - propertyMap.put(property.key(), property.value()); - } - BlockRegistries.BLOCK_STATES.get().add(new BlockState(block, BlockRegistries.BLOCK_STATES.get().size(), propertyMap)); + List>> result = stream.toList(); + // Ensure each block state shares the same key array. Creating a keySet here shouldn't be an issue since + // this states map should be removed after build. + Property[] keys = this.states.keySet().toArray(new Property[0]); + result.forEach(properties -> { + Comparable[] values = properties.toArray(new Comparable[0]); + Reference2ObjectMap, Comparable> propertyMap = new Reference2ObjectArrayMap<>(keys, values); + BlockState state = new BlockState(block, BlockRegistries.BLOCK_STATES.get().size(), propertyMap); + BlockRegistries.BLOCK_STATES.get().add(state); + states.add(state); }); + return states; } } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java b/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java index de4806efa..cb375eaf9 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java @@ -30,6 +30,8 @@ import it.unimi.dsi.fastutil.objects.Reference2ObjectMaps; import org.geysermc.geyser.level.block.property.Property; import org.geysermc.geyser.registry.BlockRegistries; +import java.util.Locale; + public final class BlockState { private final Block block; private final int javaId; @@ -62,12 +64,25 @@ public final class BlockState { return this.block == block; } + @Override + public String toString() { + if (this.states.isEmpty()) { + return this.block.javaIdentifier().toString(); + } + return this.block.javaIdentifier().toString() + "[" + paramsToString() + "]"; + } + private String paramsToString() { StringBuilder builder = new StringBuilder(); var it = this.states.entrySet().iterator(); while (it.hasNext()) { var entry = it.next(); - builder.append(entry.getKey()).append("=").append(entry.getValue()); + builder.append(entry.getKey().name()) + .append("=") + .append(entry.getValue().toString().toLowerCase(Locale.ROOT)); // lowercase covers enums + if (it.hasNext()) { + builder.append(","); + } } return builder.toString(); } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/FlowerPotBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/FlowerPotBlock.java index 8c911ad97..53d0b1ec1 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/FlowerPotBlock.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/FlowerPotBlock.java @@ -68,7 +68,7 @@ public class FlowerPotBlock extends Block implements BedrockChunkWantsBlockEntit if (this.flower != Blocks.AIR) { // Get the Bedrock CompoundTag of the block. // This is where we need to store the *Java* name because Bedrock has six minecraft:sapling blocks with different block states. - NbtMap plant = session.getBlockMappings().getFlowerPotBlocks().get(this.flower.javaIdentifier()); + NbtMap plant = session.getBlockMappings().getFlowerPotBlocks().get(this.flower.javaIdentifier().asString()); if (plant != null) { tagBuilder.putCompound("PlantBlock", plant.toBuilder().build()); } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/FurnaceBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/FurnaceBlock.java new file mode 100644 index 000000000..2b898e089 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/FurnaceBlock.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.type; + +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.level.physics.Direction; + +import java.util.List; + +public class FurnaceBlock extends Block { + private static BlockState LIT; + private static BlockState UNLIT; + + public FurnaceBlock(String javaIdentifier, Builder builder) { + super(javaIdentifier, builder); + } + + @Override + protected void processStates(List states) { + LIT = states.stream() + .filter(state -> state.getValue(Properties.HORIZONTAL_FACING) == Direction.NORTH + && state.getValue(Properties.LIT)) + .findFirst().orElseThrow(); + UNLIT = states.stream() + .filter(state -> state.getValue(Properties.HORIZONTAL_FACING) == Direction.NORTH + && !state.getValue(Properties.LIT)) + .findFirst().orElseThrow(); + } + + public static BlockState state(boolean lit) { + return lit ? LIT : UNLIT; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/HoneyBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/HoneyBlock.java new file mode 100644 index 000000000..73c4d02aa --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/HoneyBlock.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.type; + +import java.util.List; + +public class HoneyBlock extends Block { + private static BlockState STATE; + + public HoneyBlock(String javaIdentifier, Builder builder) { + super(javaIdentifier, builder); + } + + @Override + protected void processStates(List states) { + STATE = states.get(0); + } + + public static BlockState state() { + return STATE; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/SpawnerBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/SpawnerBlock.java new file mode 100644 index 000000000..2103fe6e5 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/SpawnerBlock.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.type; + +import java.util.List; + +public class SpawnerBlock extends Block { + private static BlockState STATE; + + public SpawnerBlock(String javaIdentifier, Builder builder) { + super(javaIdentifier, builder); + } + + @Override + protected void processStates(List states) { + STATE = states.get(0); + } + + public static BlockState state() { + return STATE; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/WaterBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/WaterBlock.java new file mode 100644 index 000000000..801a7f9e7 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/WaterBlock.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.type; + +import java.util.List; + +public class WaterBlock extends Block { + private static BlockState LEVEL_0; + + public WaterBlock(String javaIdentifier, Builder builder) { + super(javaIdentifier, builder); + } + + @Override + protected void processStates(List states) { + super.processStates(states); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java b/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java index 416ab7793..a18ffff7d 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java +++ b/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java @@ -147,6 +147,7 @@ public class BlockRegistries { CustomBlockRegistryPopulator.populate(CustomBlockRegistryPopulator.Stage.CUSTOM_REGISTRATION); BlockRegistryPopulator.populate(BlockRegistryPopulator.Stage.INIT_BEDROCK); BlockRegistryPopulator.populate(BlockRegistryPopulator.Stage.POST_INIT); + System.out.println("Block registries loaded"); } public static void init() { diff --git a/core/src/main/java/org/geysermc/geyser/registry/Registries.java b/core/src/main/java/org/geysermc/geyser/registry/Registries.java index 54d013140..7f0d9013a 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/Registries.java +++ b/core/src/main/java/org/geysermc/geyser/registry/Registries.java @@ -204,5 +204,6 @@ public final class Registries { biomesNbt.put(key, value.build()); } BIOMES_NBT.set(biomesNbt.build()); + System.out.println("Registries loaded"); } } diff --git a/core/src/main/java/org/geysermc/geyser/registry/loader/CollisionRegistryLoader.java b/core/src/main/java/org/geysermc/geyser/registry/loader/CollisionRegistryLoader.java index 7cf39b6d7..2cd7f82d6 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/loader/CollisionRegistryLoader.java +++ b/core/src/main/java/org/geysermc/geyser/registry/loader/CollisionRegistryLoader.java @@ -106,7 +106,7 @@ public class CollisionRegistryLoader extends MultiResourceRegistryLoader, CollisionInfo> annotationMap, int collisionIndex, List collisionList) { - String blockName = state.block().javaIdentifier().substring("minecraft:".length()); + String blockName = state.block().javaIdentifier().value(); for (Map.Entry, CollisionInfo> collisionRemappers : annotationMap.entrySet()) { Class type = collisionRemappers.getKey(); diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java index 66301cef2..0180fc8b7 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java @@ -50,10 +50,12 @@ import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.block.custom.CustomBlockData; import org.geysermc.geyser.api.block.custom.CustomBlockState; import org.geysermc.geyser.api.block.custom.nonvanilla.JavaBlockState; +import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.level.physics.PistonBehavior; import org.geysermc.geyser.registry.BlockRegistries; +import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.BlockMapping; import org.geysermc.geyser.registry.type.BlockMappings; import org.geysermc.geyser.registry.type.GeyserBedrockBlock; @@ -391,7 +393,7 @@ public final class BlockRegistryPopulator { throw new AssertionError("Unable to load Java block mappings", e); } - JAVA_BLOCKS_SIZE = blocksJson.size(); + JAVA_BLOCKS_SIZE = BlockRegistries.BLOCK_STATES.get().size(); if (!BlockRegistries.NON_VANILLA_BLOCK_STATE_OVERRIDES.get().isEmpty()) { MIN_CUSTOM_RUNTIME_ID = BlockRegistries.NON_VANILLA_BLOCK_STATE_OVERRIDES.get().keySet().stream().min(Comparator.comparing(JavaBlockState::javaId)).orElseThrow().javaId(); @@ -409,12 +411,6 @@ public final class BlockRegistryPopulator { Deque cleanIdentifiers = new ArrayDeque<>(); int javaRuntimeId = -1; - int furnaceRuntimeId = -1; - int furnaceLitRuntimeId = -1; - int honeyBlockRuntimeId = -1; - int slimeBlockRuntimeId = -1; - int spawnerRuntimeId = -1; - int uniqueJavaId = -1; int waterRuntimeId = -1; Iterator> blocksIterator = blocksJson.fields(); while (blocksIterator.hasNext()) { @@ -422,7 +418,6 @@ public final class BlockRegistryPopulator { Map.Entry entry = blocksIterator.next(); String javaId = entry.getKey(); - // TODO fix this, (no block should have a null hardness) BlockMapping.BlockMappingBuilder builder = BlockMapping.builder(); JsonNode pickItemNode = entry.getValue().get("pick_item"); @@ -443,7 +438,6 @@ public final class BlockRegistryPopulator { String bedrockIdentifier = entry.getValue().get("bedrock_identifier").asText(); if (!cleanJavaIdentifier.equals(cleanIdentifiers.peekLast())) { - uniqueJavaId++; cleanIdentifiers.add(cleanJavaIdentifier.intern()); } @@ -456,50 +450,11 @@ public final class BlockRegistryPopulator { // It's possible to only have this store differences in names, but the key set of all Java names is used in sending command suggestions BlockRegistries.JAVA_TO_BEDROCK_IDENTIFIERS.register(cleanJavaIdentifier.intern(), bedrockIdentifier.intern()); - if (javaId.startsWith("minecraft:furnace[facing=north")) { - if (javaId.contains("lit=true")) { - furnaceLitRuntimeId = javaRuntimeId; - } else { - furnaceRuntimeId = javaRuntimeId; - } - - } else if (javaId.startsWith("minecraft:spawner")) { - spawnerRuntimeId = javaRuntimeId; - - } else if ("minecraft:water[level=0]".equals(javaId)) { + if ("minecraft:water[level=0]".equals(javaId)) { waterRuntimeId = javaRuntimeId; - } else if (javaId.equals("minecraft:honey_block")) { - honeyBlockRuntimeId = javaRuntimeId; - } else if (javaId.equals("minecraft:slime_block")) { - slimeBlockRuntimeId = javaRuntimeId; } } - if (furnaceRuntimeId == -1) { - throw new AssertionError("Unable to find furnace in palette"); - } - BlockStateValues.JAVA_FURNACE_ID = furnaceRuntimeId; - - if (furnaceLitRuntimeId == -1) { - throw new AssertionError("Unable to find lit furnace in palette"); - } - BlockStateValues.JAVA_FURNACE_LIT_ID = furnaceLitRuntimeId; - - if (honeyBlockRuntimeId == -1) { - throw new AssertionError("Unable to find honey block in palette"); - } - BlockStateValues.JAVA_HONEY_BLOCK_ID = honeyBlockRuntimeId; - - if (slimeBlockRuntimeId == -1) { - throw new AssertionError("Unable to find slime block in palette"); - } - BlockStateValues.JAVA_SLIME_BLOCK_ID = slimeBlockRuntimeId; - - if (spawnerRuntimeId == -1) { - throw new AssertionError("Unable to find spawner in palette"); - } - BlockStateValues.JAVA_SPAWNER_ID = spawnerRuntimeId; - if (waterRuntimeId == -1) { throw new AssertionError("Unable to find Java water in palette"); } @@ -534,12 +489,20 @@ public final class BlockRegistryPopulator { builder.setBlockEntity(); } String cleanJavaIdentifier = BlockUtils.getCleanIdentifier(javaBlockState.identifier()); - Block block = new Block(cleanJavaIdentifier, builder); + String pickItem = javaBlockState.pickItem(); + Block block = new Block(cleanJavaIdentifier, builder) { + @Override + public Item asItem() { + if (this.item == null) { + return Registries.JAVA_ITEM_IDENTIFIERS.get(pickItem); + } + return this.item; + } + }; String bedrockIdentifier = customBlockState.block().identifier(); if (!cleanJavaIdentifier.equals(cleanIdentifiers.peekLast())) { - uniqueJavaId++; cleanIdentifiers.add(cleanJavaIdentifier.intern()); } diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/BlockMapping.java b/core/src/main/java/org/geysermc/geyser/registry/type/BlockMapping.java index d6ee55965..0520924f8 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/type/BlockMapping.java +++ b/core/src/main/java/org/geysermc/geyser/registry/type/BlockMapping.java @@ -28,7 +28,6 @@ package org.geysermc.geyser.registry.type; import lombok.Builder; import lombok.Value; import org.checkerframework.checker.nullness.qual.Nullable; -import org.geysermc.geyser.util.BlockUtils; @Builder @Value @@ -37,42 +36,8 @@ public class BlockMapping { String javaIdentifier; - boolean canBreakWithHand; @Nullable String pickItem; boolean isBlockEntity; boolean isNonVanilla; - - /** - * @return the identifier without the additional block states - */ - public String getCleanJavaIdentifier() { - return BlockUtils.getCleanIdentifier(javaIdentifier); - } - - /** - * @return the corresponding Java identifier for this item - */ - public String getItemIdentifier() { - if (pickItem != null && !pickItem.equals("minecraft:air")) { - // Spawners can have air as their pick item which we are not interested in. - return pickItem; - } - - return getCleanJavaIdentifier(); - } - - /** - * Get the item a Java client would receive when pressing - * the Pick Block key on a specific Java block state. - * - * @return The Java identifier of the item - */ - public String getPickItem() { - if (pickItem != null) { - return pickItem; - } - - return getCleanJavaIdentifier(); - } } diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 144cd9f27..c85c0fd28 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -97,6 +97,7 @@ import org.geysermc.geyser.inventory.PlayerInventory; import org.geysermc.geyser.inventory.recipe.GeyserRecipe; import org.geysermc.geyser.inventory.recipe.GeyserStonecutterData; import org.geysermc.geyser.item.Items; +import org.geysermc.geyser.item.type.BlockItem; import org.geysermc.geyser.level.JavaDimension; import org.geysermc.geyser.level.WorldManager; import org.geysermc.geyser.level.physics.CollisionManager; @@ -349,7 +350,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { private Vector3i lastBlockPlacePosition; @Setter - private String lastBlockPlacedId; + private BlockItem lastBlockPlaced; @Setter private boolean interacting; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/AbstractBlockInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/AbstractBlockInventoryTranslator.java index ac6e9870e..2dfa2a85a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/AbstractBlockInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/AbstractBlockInventoryTranslator.java @@ -30,6 +30,7 @@ import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.holder.BlockInventoryHolder; import org.geysermc.geyser.inventory.holder.InventoryHolder; import org.geysermc.geyser.inventory.updater.InventoryUpdater; +import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.session.GeyserSession; /** @@ -44,10 +45,10 @@ public abstract class AbstractBlockInventoryTranslator extends BaseInventoryTran * @param javaBlockIdentifier a Java block identifier that is used as a temporary block * @param containerType the container type of this inventory * @param updater updater - * @param additionalValidBlocks any other block identifiers that can safely use this inventory without a fake block + * @param additionalValidBlocks any other blocks that can safely use this inventory without a fake block */ public AbstractBlockInventoryTranslator(int size, String javaBlockIdentifier, ContainerType containerType, InventoryUpdater updater, - String... additionalValidBlocks) { + Block... additionalValidBlocks) { super(size); this.holder = new BlockInventoryHolder(javaBlockIdentifier, containerType, additionalValidBlocks); this.updater = updater; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/AnvilInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/AnvilInventoryTranslator.java index 2da51a0eb..705fac362 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/AnvilInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/AnvilInventoryTranslator.java @@ -37,6 +37,7 @@ import org.geysermc.geyser.inventory.BedrockContainerSlot; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.PlayerInventory; import org.geysermc.geyser.inventory.updater.AnvilInventoryUpdater; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; @@ -45,7 +46,7 @@ import java.util.Objects; public class AnvilInventoryTranslator extends AbstractBlockInventoryTranslator { public AnvilInventoryTranslator() { super(3, "minecraft:anvil[facing=north]", org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.ANVIL, AnvilInventoryUpdater.INSTANCE, - "minecraft:chipped_anvil", "minecraft:damaged_anvil"); + Blocks.CHIPPED_ANVIL, Blocks.DAMAGED_ANVIL); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/Generic3X3InventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/Generic3X3InventoryTranslator.java index 2a80161c0..f47a367d8 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/Generic3X3InventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/Generic3X3InventoryTranslator.java @@ -32,6 +32,7 @@ import org.geysermc.geyser.inventory.Generic3X3Container; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.PlayerInventory; import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; @@ -41,7 +42,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; public class Generic3X3InventoryTranslator extends AbstractBlockInventoryTranslator { public Generic3X3InventoryTranslator() { super(9, "minecraft:dispenser[facing=north,triggered=false]", org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.DISPENSER, ContainerInventoryUpdater.INSTANCE, - "minecraft:dropper"); + Blocks.DROPPER); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java index 795eba101..72f5260a0 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java @@ -52,14 +52,14 @@ public class ShulkerInventoryTranslator extends AbstractBlockInventoryTranslator } @Override - protected void setCustomName(GeyserSession session, Vector3i position, Inventory inventory, int javaBlockState) { + protected void setCustomName(GeyserSession session, Vector3i position, Inventory inventory, BlockState javaBlockState) { NbtMapBuilder tag = NbtMap.builder() .putInt("x", position.getX()) .putInt("y", position.getY()) .putInt("z", position.getZ()) .putString("CustomName", inventory.getTitle()); // Don't reset facing property - shulkerBoxTranslator.translateTag(session, tag, null, BlockState.of(javaBlockState)); + shulkerBoxTranslator.translateTag(session, tag, null, javaBlockState); BlockEntityDataPacket dataPacket = new BlockEntityDataPacket(); dataPacket.setData(tag.build()); diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/SingleChestInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/SingleChestInventoryTranslator.java index d09e7e990..e18096862 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/SingleChestInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/SingleChestInventoryTranslator.java @@ -29,15 +29,17 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.holder.BlockInventoryHolder; import org.geysermc.geyser.inventory.holder.InventoryHolder; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.session.GeyserSession; public class SingleChestInventoryTranslator extends ChestInventoryTranslator { private final InventoryHolder holder; + // TODO add barrel??? public SingleChestInventoryTranslator(int size) { super(size, 27); this.holder = new BlockInventoryHolder("minecraft:chest[facing=north,type=single,waterlogged=false]", ContainerType.CONTAINER, - "minecraft:ender_chest", "minecraft:trapped_chest") { + Blocks.ENDER_CHEST, Blocks.TRAPPED_CHEST) { @Override protected boolean isValidBlock(String[] javaBlockString) { if (javaBlockString[0].equals("minecraft:ender_chest")) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java index 14282228b..ca8679319 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java @@ -30,6 +30,7 @@ import it.unimi.dsi.fastutil.objects.*; import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.level.block.type.BlockState; +import org.geysermc.geyser.level.block.type.HoneyBlock; import org.geysermc.geyser.level.block.type.PistonBlock; import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.PistonValueType; import org.cloudburstmc.math.vector.Vector3d; @@ -98,7 +99,7 @@ public class PistonBlockEntity { static { // Create a ~1 x ~0.5 x ~1 bounding box above the honey block - BlockCollision blockCollision = BlockRegistries.COLLISIONS.get(BlockStateValues.JAVA_HONEY_BLOCK_ID); + BlockCollision blockCollision = BlockRegistries.COLLISIONS.get(HoneyBlock.state().javaId()); if (blockCollision == null) { throw new RuntimeException("Failed to find honey block collision"); } @@ -622,11 +623,11 @@ public class PistonBlockEntity { } placedFinalBlocks = true; Vector3i movement = getMovement(); - attachedBlocks.forEach((blockPos, javaId) -> { + attachedBlocks.forEach((blockPos, state) -> { blockPos = blockPos.add(movement); // Don't place blocks that collide with the player if (!SOLID_BOUNDING_BOX.checkIntersection(blockPos.toDouble(), session.getCollisionManager().getPlayerBoundingBox())) { - ChunkUtils.updateBlock(session, javaId, blockPos); + ChunkUtils.updateBlock(session, state, blockPos); } }); if (action == PistonValueType.PUSHING) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java index 507d67ba5..be3af2061 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java @@ -29,11 +29,10 @@ import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.packet.BlockPickRequestPacket; import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.type.ItemFrameEntity; -import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.item.Items; +import org.geysermc.geyser.level.block.Blocks; +import org.geysermc.geyser.level.block.type.BannerBlock; import org.geysermc.geyser.level.block.type.Block; -import org.geysermc.geyser.registry.BlockRegistries; -import org.geysermc.geyser.registry.type.BlockMapping; -import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; @@ -46,10 +45,10 @@ public class BedrockBlockPickRequestTranslator extends PacketTranslator session.ensureInEventLoop(() -> { if (components == null) { - pickItem(session, blockMapping); + pickItem(session, blockToPick); return; } - // I don't really like this... I'd rather get an ID from the block mapping I think - ItemMapping mapping = session.getItemMappings().getMapping(blockMapping.getPickItem()); - - ItemStack itemStack = new ItemStack(mapping.getJavaItem().javaId(), 1, components); + ItemStack itemStack = new ItemStack(blockToPick.asItem().javaId(), 1, components); InventoryUtils.findOrCreateItem(session, itemStack); })); return; } - pickItem(session, blockMapping); + pickItem(session, blockToPick); } - private void pickItem(GeyserSession session, BlockMapping blockToPick) { - InventoryUtils.findOrCreateItem(session, blockToPick.getPickItem()); + private void pickItem(GeyserSession session, Block block) { + InventoryUtils.findOrCreateItem(session, block.asItem()); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java index 9c6a1cb56..78745aeb8 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java @@ -355,9 +355,9 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator * This attempts to mimic Java Edition behavior as best as it can. * @param session the Bedrock client's session - * @param itemName the Java identifier of the item to search/select + * @param item the Java item to search/select for */ - public static void findOrCreateItem(GeyserSession session, String itemName) { + public static void findOrCreateItem(GeyserSession session, Item item) { // Get the inventory to choose a slot to pick PlayerInventory inventory = session.getPlayerInventory(); - if (itemName.equals("minecraft:air")) { + if (item == Items.AIR) { return; } @@ -326,7 +332,7 @@ public class InventoryUtils { continue; } // If this isn't the item we're looking for - if (!geyserItem.asItem().javaIdentifier().equals(itemName)) { + if (!geyserItem.asItem().equals(item)) { continue; } @@ -342,7 +348,7 @@ public class InventoryUtils { continue; } // If this isn't the item we're looking for - if (!geyserItem.asItem().javaIdentifier().equals(itemName)) { + if (!geyserItem.asItem().equals(item)) { continue; } @@ -355,17 +361,13 @@ public class InventoryUtils { if (session.getGameMode() == GameMode.CREATIVE) { int slot = findEmptyHotbarSlot(inventory); - ItemMapping mapping = session.getItemMappings().getMapping(itemName); // TODO - if (mapping != null) { - ServerboundSetCreativeModeSlotPacket actionPacket = new ServerboundSetCreativeModeSlotPacket((short)slot, - new ItemStack(mapping.getJavaItem().javaId())); - if ((slot - 36) != inventory.getHeldItemSlot()) { - setHotbarItem(session, slot); - } - session.sendDownstreamGamePacket(actionPacket); - } else { - session.getGeyser().getLogger().debug("Cannot find item for block " + itemName); + ItemMapping mapping = session.getItemMappings().getMapping(item); + ServerboundSetCreativeModeSlotPacket actionPacket = new ServerboundSetCreativeModeSlotPacket((short)slot, + new ItemStack(mapping.getJavaItem().javaId())); + if ((slot - 36) != inventory.getHeldItemSlot()) { + setHotbarItem(session, slot); } + session.sendDownstreamGamePacket(actionPacket); } } diff --git a/core/src/main/java/org/geysermc/geyser/util/StatisticsUtils.java b/core/src/main/java/org/geysermc/geyser/util/StatisticsUtils.java index 8f9be0b98..7e1227f6c 100644 --- a/core/src/main/java/org/geysermc/geyser/util/StatisticsUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/StatisticsUtils.java @@ -96,7 +96,7 @@ public class StatisticsUtils { if (entry.getKey() instanceof BreakBlockStatistic statistic) { Block block = BlockRegistries.JAVA_BLOCKS_TO_RENAME.get(statistic.getId()); if (block != null) { - String identifier = block.javaIdentifier().replace("minecraft:", "block.minecraft."); + String identifier = "block.minecraft." + block.javaIdentifier().value(); content.add(identifier + ": " + entry.getIntValue()); } } From 1e9dbaf38be7895f0d44f408c56c64ef87ff3947 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 18 May 2024 16:54:42 -0400 Subject: [PATCH 176/272] Here is the Spigot change --- .../platform/spigot/world/GeyserSpigotBlockPlaceListener.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserSpigotBlockPlaceListener.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserSpigotBlockPlaceListener.java index b5f4bd4f9..1cdd77c64 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserSpigotBlockPlaceListener.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserSpigotBlockPlaceListener.java @@ -33,7 +33,6 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.block.BlockPlaceEvent; import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.platform.spigot.world.manager.GeyserSpigotWorldManager; import org.geysermc.geyser.registry.BlockRegistries; @@ -65,6 +64,6 @@ public class GeyserSpigotBlockPlaceListener implements Listener { placeBlockSoundPacket.setIdentifier(":"); session.sendUpstreamPacket(placeBlockSoundPacket); session.setLastBlockPlacePosition(null); - session.setLastBlockPlacedId(null); + session.setLastBlockPlaced(null); } } From d85549c38dd404ade6aa364990c53548f8f4fea3 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sun, 19 May 2024 20:24:19 -0400 Subject: [PATCH 177/272] BlockMapping is removed --- .../java/org/geysermc/geyser/GeyserImpl.java | 11 - .../geyser/entity/type/ItemEntity.java | 3 +- .../type/living/merchant/VillagerEntity.java | 39 ++-- .../entity/type/player/SkullPlayerEntity.java | 26 ++- .../geysermc/geyser/inventory/Container.java | 5 +- .../geyser/inventory/Generic3X3Container.java | 8 +- .../holder/BlockInventoryHolder.java | 2 +- .../geysermc/geyser/level/WorldManager.java | 6 +- .../geyser/level/block/BlockStateValues.java | 220 ++---------------- .../geysermc/geyser/level/block/Blocks.java | 82 +++---- .../geyser/level/block/DoubleChestValue.java | 40 ---- .../geyser/level/block/type/Block.java | 37 ++- .../geyser/level/block/type/BlockState.java | 10 +- .../level/block/type/FlowerPotBlock.java | 16 +- .../geyser/level/block/type/SkullBlock.java | 46 +++- .../block/type/WallSkullBlock.java} | 34 +-- .../geyser/registry/BlockRegistries.java | 15 +- .../populator/BlockRegistryPopulator.java | 176 ++++++-------- .../geyser/registry/type/BlockMappings.java | 3 +- .../geyser/session/cache/SkullCache.java | 27 ++- .../chest/DoubleChestInventoryTranslator.java | 28 +-- .../entity/SkullBlockEntityTranslator.java | 15 +- .../BedrockBlockPickRequestTranslator.java | 16 +- ...BedrockInventoryTransactionTranslator.java | 23 +- .../player/BedrockActionTranslator.java | 28 +-- .../BedrockLevelSoundEventTranslator.java | 15 +- .../level/JavaBlockEntityDataTranslator.java | 2 +- .../java/level/JavaBlockUpdateTranslator.java | 10 +- .../JavaLevelChunkWithLightTranslator.java | 5 +- .../geysermc/geyser/util/StatisticsUtils.java | 2 +- .../util/collection/FixedInt2BooleanMap.java | 120 ---------- .../util/collection/FixedInt2ByteMap.java | 121 ---------- .../util/collection/FixedInt2IntMap.java | 120 ---------- .../util/collection/LecternHasBookMap.java | 75 ------ .../geyser/util/collection/package-info.java | 34 --- core/src/main/resources/mappings | 2 +- .../collection/GeyserCollectionsTest.java | 181 -------------- 37 files changed, 378 insertions(+), 1225 deletions(-) delete mode 100644 core/src/main/java/org/geysermc/geyser/level/block/DoubleChestValue.java rename core/src/main/java/org/geysermc/geyser/{registry/type/BlockMapping.java => level/block/type/WallSkullBlock.java} (58%) delete mode 100644 core/src/main/java/org/geysermc/geyser/util/collection/FixedInt2BooleanMap.java delete mode 100644 core/src/main/java/org/geysermc/geyser/util/collection/FixedInt2ByteMap.java delete mode 100644 core/src/main/java/org/geysermc/geyser/util/collection/FixedInt2IntMap.java delete mode 100644 core/src/main/java/org/geysermc/geyser/util/collection/LecternHasBookMap.java delete mode 100644 core/src/main/java/org/geysermc/geyser/util/collection/package-info.java delete mode 100644 core/src/test/java/org/geysermc/geyser/util/collection/GeyserCollectionsTest.java diff --git a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java index 7be1fe15b..a60a14ea0 100644 --- a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java +++ b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java @@ -256,17 +256,6 @@ public class GeyserImpl implements GeyserApi { } VersionCheckUtils.checkForOutdatedJava(logger); - - for (int i = 0; i < BlockRegistries.JAVA_BLOCKS.get().length; i++) { - String oldIdentifier = BlockRegistries.JAVA_BLOCKS.get(i).getJavaIdentifier(); - String newIdentifier = BlockRegistries.BLOCK_STATES.get(i).toString(); - if (!oldIdentifier.equals(newIdentifier)) { - System.out.println("Check block " + oldIdentifier + " " + newIdentifier); - break; - } - } - System.out.println(BlockRegistries.JAVA_BLOCKS.get().length); - System.out.println(BlockRegistries.BLOCK_STATES.get().size()); } private void startInstance() { diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java index ead717b34..49eb9ddc4 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java @@ -34,6 +34,7 @@ import org.cloudburstmc.protocol.bedrock.packet.AddItemEntityPacket; import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; @@ -137,7 +138,7 @@ public class ItemEntity extends ThrowableEntity { protected float getDrag() { if (isOnGround()) { Vector3i groundBlockPos = position.toInt().down(1); - int blockState = session.getGeyser().getWorldManager().getBlockAt(session, groundBlockPos); + BlockState blockState = session.getGeyser().getWorldManager().blockAt(session, groundBlockPos); return BlockStateValues.getSlipperiness(blockState) * 0.98f; } return 0.98f; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/VillagerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/VillagerEntity.java index 3c2160a2b..fb07572e6 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/VillagerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/VillagerEntity.java @@ -33,8 +33,8 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.MoveEntityAbsolutePacket; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.registry.BlockRegistries; -import org.geysermc.geyser.registry.type.BlockMapping; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.VillagerData; @@ -119,28 +119,29 @@ public class VillagerEntity extends AbstractMerchantEntity { } // The bed block - int blockId = session.getGeyser().getWorldManager().getBlockAt(session, bedPosition); - String fullIdentifier = BlockRegistries.JAVA_BLOCKS.getOrDefault(blockId, BlockMapping.DEFAULT).getJavaIdentifier(); + BlockState state = session.getGeyser().getWorldManager().blockAt(session, bedPosition); // Set the correct position offset and rotation when sleeping int bedRotation = 0; float xOffset = 0; float zOffset = 0; - if (fullIdentifier.contains("facing=south")) { - // bed is facing south - bedRotation = 180; - zOffset = -.5f; - } else if (fullIdentifier.contains("facing=east")) { - // bed is facing east - bedRotation = 90; - xOffset = -.5f; - } else if (fullIdentifier.contains("facing=west")) { - // bed is facing west - bedRotation = 270; - xOffset = .5f; - } else if (fullIdentifier.contains("facing=north")) { - // rotation does not change because north is 0 - zOffset = .5f; + switch (state.getValue(Properties.HORIZONTAL_FACING)) { + case SOUTH -> { + bedRotation = 180; + zOffset = -.5f; + } + case EAST -> { + bedRotation = 90; + xOffset = -.5f; + } + case WEST -> { + bedRotation = 270; + xOffset = .5f; + } + case NORTH -> { + // rotation does not change because north is 0 + zOffset = .5f; + } } setYaw(yaw); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/SkullPlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/SkullPlayerEntity.java index 89f9c37d6..f2f93b266 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/SkullPlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/SkullPlayerEntity.java @@ -34,7 +34,10 @@ import org.cloudburstmc.protocol.bedrock.data.command.CommandPermission; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.AddPlayerPacket; -import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.level.block.type.BlockState; +import org.geysermc.geyser.level.block.type.WallSkullBlock; +import org.geysermc.geyser.level.physics.Direction; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.SkullCache; import org.geysermc.geyser.skin.SkullSkinManager; @@ -137,20 +140,19 @@ public class SkullPlayerEntity extends PlayerEntity { float z = skull.getPosition().getZ() + .5f; float rotation; - int blockState = skull.getBlockState(); - byte floorRotation = BlockStateValues.getSkullRotation(blockState); - if (floorRotation == -1) { - // Wall skull + BlockState blockState = skull.getBlockState(); + if (blockState.block() instanceof WallSkullBlock) { y += 0.25f; - rotation = BlockStateValues.getSkullWallDirections().get(blockState); - switch ((int) rotation) { - case 180 -> z += 0.24f; // North - case 0 -> z -= 0.24f; // South - case 90 -> x += 0.24f; // West - case 270 -> x -= 0.24f; // East + Direction direction = blockState.getValue(Properties.HORIZONTAL_FACING); + rotation = WallSkullBlock.getDegrees(direction); + switch (direction) { + case NORTH -> z += 0.24f; + case SOUTH -> z -= 0.24f; + case WEST -> x += 0.24f; + case EAST -> x -= 0.24f; } } else { - rotation = (180f + (floorRotation * 22.5f)) % 360; + rotation = (180f + (blockState.getValue(Properties.ROTATION_16) * 22.5f)) % 360; } moveAbsolute(Vector3f.from(x, y, z), rotation, 0, rotation, true, true); diff --git a/core/src/main/java/org/geysermc/geyser/inventory/Container.java b/core/src/main/java/org/geysermc/geyser/inventory/Container.java index 209aeb24f..81818613f 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/Container.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/Container.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.inventory; +import org.geysermc.geyser.level.block.type.Block; import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import lombok.Getter; import org.checkerframework.checker.nullness.qual.NonNull; @@ -83,9 +84,9 @@ public class Container extends Inventory { * Will be overwritten for droppers. * * @param usingRealBlock whether this container is using a real container or not - * @param javaBlockId the Java block string of the block, if real + * @param block the Java block, if real */ - public void setUsingRealBlock(boolean usingRealBlock, String javaBlockId) { + public void setUsingRealBlock(boolean usingRealBlock, Block block) { isUsingRealBlock = usingRealBlock; } } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/Generic3X3Container.java b/core/src/main/java/org/geysermc/geyser/inventory/Generic3X3Container.java index 65e47d877..0b14d1105 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/Generic3X3Container.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/Generic3X3Container.java @@ -26,6 +26,8 @@ package org.geysermc.geyser.inventory; import lombok.Getter; +import org.geysermc.geyser.level.block.Blocks; +import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.inventory.Generic3X3InventoryTranslator; import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; @@ -44,10 +46,10 @@ public class Generic3X3Container extends Container { } @Override - public void setUsingRealBlock(boolean usingRealBlock, String javaBlockId) { - super.setUsingRealBlock(usingRealBlock, javaBlockId); + public void setUsingRealBlock(boolean usingRealBlock, Block block) { + super.setUsingRealBlock(usingRealBlock, block); if (usingRealBlock) { - isDropper = javaBlockId.startsWith("minecraft:dropper"); + isDropper = block == Blocks.DROPPER; } } } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java b/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java index 686fe39ad..0a51d43ef 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java @@ -90,7 +90,7 @@ public class BlockInventoryHolder extends InventoryHolder { if (isValidBlock(javaBlockString)) { // We can safely use this block inventory.setHolderPosition(session.getLastInteractionBlockPosition()); - ((Container) inventory).setUsingRealBlock(true, javaBlockString[0]); + ((Container) inventory).setUsingRealBlock(true, state.block()); setCustomName(session, session.getLastInteractionBlockPosition(), inventory, state); return true; diff --git a/core/src/main/java/org/geysermc/geyser/level/WorldManager.java b/core/src/main/java/org/geysermc/geyser/level/WorldManager.java index 5edce21dc..6cd9c3e26 100644 --- a/core/src/main/java/org/geysermc/geyser/level/WorldManager.java +++ b/core/src/main/java/org/geysermc/geyser/level/WorldManager.java @@ -59,10 +59,12 @@ import java.util.function.Function; */ public abstract class WorldManager { - public final BlockState blockAt(GeyserSession session, Vector3i vector3i) { - return BlockState.of(this.getBlockAt(session, vector3i)); + @NonNull + public final BlockState blockAt(GeyserSession session, Vector3i vector) { + return this.blockAt(session, vector.getX(), vector.getY(), vector.getZ()); } + @NonNull public BlockState blockAt(GeyserSession session, int x, int y, int z) { return BlockState.of(this.getBlockAt(session, x, y, z)); } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java b/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java index 9b390f6ee..8bc9cf1e2 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.level.block; -import com.fasterxml.jackson.databind.JsonNode; import it.unimi.dsi.fastutil.ints.*; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; @@ -36,10 +35,6 @@ import org.geysermc.geyser.level.block.type.PistonBlock; import org.geysermc.geyser.level.physics.Direction; import org.geysermc.geyser.level.physics.PistonBehavior; import org.geysermc.geyser.registry.BlockRegistries; -import org.geysermc.geyser.registry.type.BlockMapping; -import org.geysermc.geyser.util.collection.FixedInt2ByteMap; -import org.geysermc.geyser.util.collection.FixedInt2IntMap; -import org.geysermc.geyser.util.collection.LecternHasBookMap; import java.util.Locale; @@ -47,35 +42,13 @@ import java.util.Locale; * Used for block entities if the Java block state contains Bedrock block information. */ public final class BlockStateValues { - private static final IntSet ALL_CAULDRONS = new IntOpenHashSet(); - private static final Int2IntMap BANNER_COLORS = new FixedInt2IntMap(); - private static final Int2ByteMap BED_COLORS = new FixedInt2ByteMap(); - private static final Int2IntMap BRUSH_PROGRESS = new Int2IntOpenHashMap(); - private static final Int2ObjectMap DOUBLE_CHEST_VALUES = new Int2ObjectOpenHashMap<>(); - private static final Int2ObjectMap FLOWER_POT_VALUES = new Int2ObjectOpenHashMap<>(); private static final IntSet HORIZONTAL_FACING_JIGSAWS = new IntOpenHashSet(); - private static final LecternHasBookMap LECTERN_BOOK_STATES = new LecternHasBookMap(); - private static final IntSet NON_WATER_CAULDRONS = new IntOpenHashSet(); - private static final Int2IntMap NOTEBLOCK_PITCHES = new FixedInt2IntMap(); - private static final Int2BooleanMap PISTON_VALUES = new Int2BooleanOpenHashMap(); private static final IntSet STICKY_PISTONS = new IntOpenHashSet(); private static final Object2IntMap PISTON_HEADS = new Object2IntOpenHashMap<>(); private static final Int2ObjectMap PISTON_ORIENTATION = new Int2ObjectOpenHashMap<>(); private static final IntSet ALL_PISTON_HEADS = new IntOpenHashSet(); - private static final IntSet MOVING_PISTONS = new IntOpenHashSet(); - private static final Int2ByteMap SKULL_VARIANTS = new FixedInt2ByteMap(); - private static final IntSet SKULL_POWERED = new IntOpenHashSet(); - private static final Int2ByteMap SKULL_ROTATIONS = new Int2ByteOpenHashMap(); - private static final Int2IntMap SKULL_WALL_DIRECTIONS = new Int2IntOpenHashMap(); - private static final Int2ByteMap SHULKERBOX_DIRECTIONS = new FixedInt2ByteMap(); private static final Int2IntMap WATER_LEVEL = new Int2IntOpenHashMap(); - private static final IntSet UPPER_DOORS = new IntOpenHashSet(); - public static int JAVA_FURNACE_ID; - public static int JAVA_FURNACE_LIT_ID; - public static int JAVA_HONEY_BLOCK_ID; - public static int JAVA_SLIME_BLOCK_ID; - public static int JAVA_SPAWNER_ID; public static int JAVA_WATER_ID; public static final int NUM_WATER_LEVELS = 9; @@ -85,66 +58,9 @@ public final class BlockStateValues { * * @param javaId The Java Identifier of the block * @param javaBlockState the Java Block State of the block - * @param blockData JsonNode of info about the block from blocks.json */ - public static void storeBlockStateValues(String javaId, int javaBlockState, JsonNode blockData) { - JsonNode bannerColor = blockData.get("banner_color"); - if (bannerColor != null) { - BANNER_COLORS.put(javaBlockState, (byte) bannerColor.intValue()); - return; // There will never be a banner color and a skull variant - } - - JsonNode bedColor = blockData.get("bed_color"); - if (bedColor != null) { - BED_COLORS.put(javaBlockState, (byte) bedColor.intValue()); - return; - } - - JsonNode bedrockStates = blockData.get("bedrock_states"); - if (bedrockStates != null) { - JsonNode brushedProgress = bedrockStates.get("brushed_progress"); - if (brushedProgress != null) { - BRUSH_PROGRESS.put(javaBlockState, brushedProgress.intValue()); - return; - } - } - - if (blockData.get("double_chest_position") != null) { - boolean isX = (blockData.get("x") != null); - boolean isDirectionPositive = ((blockData.get("x") != null && blockData.get("x").asBoolean()) || - (blockData.get("z") != null && blockData.get("z").asBoolean())); - boolean isLeft = (blockData.get("double_chest_position").asText().contains("left")); - DOUBLE_CHEST_VALUES.put(javaBlockState, new DoubleChestValue(isX, isDirectionPositive, isLeft)); - return; - } - - if (javaId.startsWith("minecraft:potted_") || javaId.equals("minecraft:flower_pot")) { - String name = javaId.replace("potted_", ""); - if (name.contains("azalea")) { - // Exception to the rule - name = name.replace("_bush", ""); - } - FLOWER_POT_VALUES.put(javaBlockState, name); - return; - } - - if (javaId.startsWith("minecraft:lectern")) { - LECTERN_BOOK_STATES.put(javaBlockState, javaId.contains("has_book=true")); - return; - } - - JsonNode notePitch = blockData.get("note_pitch"); - if (notePitch != null) { - NOTEBLOCK_PITCHES.put(javaBlockState, blockData.get("note_pitch").intValue()); - return; - } - + public static void storeBlockStateValues(String javaId, int javaBlockState) { if (javaId.contains("piston[")) { // minecraft:moving_piston, minecraft:sticky_piston, minecraft:piston - if (javaId.startsWith("minecraft:moving_piston")) { - MOVING_PISTONS.add(javaBlockState); - } else { - PISTON_VALUES.put(javaBlockState, javaId.contains("extended=true")); - } if (javaId.contains("sticky")) { STICKY_PISTONS.add(javaBlockState); } @@ -158,40 +74,6 @@ public final class BlockStateValues { return; } - JsonNode skullVariation = blockData.get("variation"); - if (skullVariation != null) { - SKULL_VARIANTS.put(javaBlockState, (byte) skullVariation.intValue()); - } - - JsonNode skullRotation = blockData.get("skull_rotation"); - if (skullRotation != null) { - SKULL_ROTATIONS.put(javaBlockState, (byte) skullRotation.intValue()); - } - - if (javaId.startsWith("minecraft:dragon_head[") || javaId.startsWith("minecraft:piglin_head[") - || javaId.startsWith("minecraft:dragon_wall_head[") || javaId.startsWith("minecraft:piglin_wall_head[")) { - if (javaId.contains("powered=true")) { - SKULL_POWERED.add(javaBlockState); - } - } - - if (javaId.contains("wall_skull") || javaId.contains("wall_head")) { - String direction = javaId.substring(javaId.lastIndexOf("facing=") + 7, javaId.lastIndexOf("powered=") - 1); - int rotation = switch (direction) { - case "north" -> 180; - case "west" -> 90; - case "east" -> 270; - default -> 0; // Also south - }; - SKULL_WALL_DIRECTIONS.put(javaBlockState, rotation); - } - - JsonNode shulkerDirection = blockData.get("shulker_direction"); - if (shulkerDirection != null) { - BlockStateValues.SHULKERBOX_DIRECTIONS.put(javaBlockState, (byte) shulkerDirection.intValue()); - return; - } - if (javaId.startsWith("minecraft:water") && !javaId.contains("cauldron")) { String strLevel = javaId.substring(javaId.lastIndexOf("level=") + 6, javaId.length() - 1); int level = Integer.parseInt(strLevel); @@ -205,48 +87,7 @@ public final class BlockStateValues { if (direction.isHorizontal()) { HORIZONTAL_FACING_JIGSAWS.add(javaBlockState); } - return; } - - if (javaId.contains("cauldron")) { - ALL_CAULDRONS.add(javaBlockState); - } - if (javaId.contains("_cauldron") && !javaId.contains("water_")) { - NON_WATER_CAULDRONS.add(javaBlockState); - } - - if (javaId.contains("_door[") && javaId.contains("half=upper")) { - UPPER_DOORS.add(javaBlockState); - } - } - - /** - * Banner colors are part of the namespaced ID in Java Edition, but part of the block entity tag in Bedrock. - * This gives an integer color that Bedrock can use. - * - * @param state BlockState of the block - * @return Banner color integer or -1 if no color - */ - public static int getBannerColor(int state) { - return BANNER_COLORS.getOrDefault(state, -1); - } - - /** - * @return if this Java block state is a non-empty non-water cauldron - */ - public static boolean isNonWaterCauldron(int state) { - return NON_WATER_CAULDRONS.contains(state); - } - - /** - * Cauldrons (since Bedrock 1.18.30) must have a block entity packet sent on chunk load to fix rendering issues. - *

- * When using a bucket on a cauldron sending a ServerboundUseItemPacket can result in the liquid being placed. - * - * @return if this Java block state is a cauldron - */ - public static boolean isCauldron(int state) { - return ALL_CAULDRONS.contains(state); } /** @@ -256,13 +97,6 @@ public final class BlockStateValues { return HORIZONTAL_FACING_JIGSAWS; } - /** - * @return the lectern book state map pointing to book present state - */ - public static LecternHasBookMap getLecternBookStates() { - return LECTERN_BOOK_STATES; - } - public static boolean isStickyPiston(int blockState) { return STICKY_PISTONS.contains(blockState); } @@ -354,38 +188,6 @@ public final class BlockStateValues { }; } - /** - * Skull variations are part of the namespaced ID in Java Edition, but part of the block entity tag in Bedrock. - * This gives a byte variant ID that Bedrock can use. - * - * @param state BlockState of the block - * @return Skull variant byte or -1 if no variant - */ - public static byte getSkullVariant(int state) { - return SKULL_VARIANTS.getOrDefault(state, (byte) -1); - } - - /** - * Skull rotations are part of the namespaced ID in Java Edition, but part of the block entity tag in Bedrock. - * This gives a byte rotation that Bedrock can use. - * - * @param state BlockState of the block - * @return Skull rotation value or -1 if no value - */ - public static byte getSkullRotation(int state) { - return SKULL_ROTATIONS.getOrDefault(state, (byte) -1); - } - - /** - * Skull rotations are part of the namespaced ID in Java Edition, but part of the block entity tag in Bedrock. - * This gives a integer rotation that Bedrock can use. - * - * @return Skull wall rotation value with the blockstate - */ - public static Int2IntMap getSkullWallDirections() { - return SKULL_WALL_DIRECTIONS; - } - /** * Get the level of water from the block state. * @@ -427,14 +229,18 @@ public final class BlockStateValues { * @param state BlockState of the block * @return The block's slipperiness */ - public static float getSlipperiness(int state) { - String blockIdentifier = BlockRegistries.JAVA_BLOCKS.getOrDefault(state, BlockMapping.DEFAULT).getJavaIdentifier(); - return switch (blockIdentifier) { - case "minecraft:slime_block" -> 0.8f; - case "minecraft:ice", "minecraft:packed_ice" -> 0.98f; - case "minecraft:blue_ice" -> 0.989f; - default -> 0.6f; - }; + public static float getSlipperiness(BlockState state) { + Block block = state.block(); + if (block == Blocks.SLIME_BLOCK) { + return 0.8f; + } + if (block == Blocks.ICE || block == Blocks.PACKED_ICE) { + return 0.98f; + } + if (block == Blocks.BLUE_ICE) { + return 0.989f; + } + return 0.6f; } private static Direction getBlockDirection(String javaId) { diff --git a/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java b/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java index 485d52161..178887754 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.level.block; +import org.geysermc.geyser.item.Items; import org.geysermc.geyser.level.block.property.ChestType; import org.geysermc.geyser.level.block.type.*; import org.geysermc.geyser.level.physics.Axis; @@ -308,7 +309,7 @@ public final class Blocks { public static final Block FERN = register(new Block("fern", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block DEAD_BUSH = register(new Block("dead_bush", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block SEAGRASS = register(new Block("seagrass", builder().pushReaction(PistonBehavior.DESTROY))); - public static final Block TALL_SEAGRASS = register(new Block("tall_seagrass", builder().pushReaction(PistonBehavior.DESTROY) + public static final Block TALL_SEAGRASS = register(new Block("tall_seagrass", builder().pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.SEAGRASS) .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); public static final Block PISTON = register(new PistonBlock("piston", builder().destroyTime(1.5f).pushReaction(PistonBehavior.BLOCK) .booleanState(EXTENDED) @@ -758,9 +759,9 @@ public final class Blocks { .booleanState(WEST))); public static final Block PUMPKIN = register(new Block("pumpkin", builder().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY))); public static final Block MELON = register(new Block("melon", builder().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY))); - public static final Block ATTACHED_PUMPKIN_STEM = register(new Block("attached_pumpkin_stem", builder().pushReaction(PistonBehavior.DESTROY) + public static final Block ATTACHED_PUMPKIN_STEM = register(new Block("attached_pumpkin_stem", builder().pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.PUMPKIN_SEEDS) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); - public static final Block ATTACHED_MELON_STEM = register(new Block("attached_melon_stem", builder().pushReaction(PistonBehavior.DESTROY) + public static final Block ATTACHED_MELON_STEM = register(new Block("attached_melon_stem", builder().pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.MELON_SEEDS) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); public static final Block PUMPKIN_STEM = register(new Block("pumpkin_stem", builder().pushReaction(PistonBehavior.DESTROY) .intState(AGE_7, 0, 7))); @@ -963,46 +964,46 @@ public final class Blocks { .enumState(ATTACH_FACE, "floor", "wall", "ceiling") .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block SKELETON_SKULL = register(new SkullBlock("skeleton_skull", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) + public static final Block SKELETON_SKULL = register(new SkullBlock("skeleton_skull", SkullBlock.Type.SKELETON, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) .intState(ROTATION_16, 0, 15))); - public static final Block SKELETON_WALL_SKULL = register(new SkullBlock("skeleton_wall_skull", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) + public static final Block SKELETON_WALL_SKULL = register(new WallSkullBlock("skeleton_wall_skull", SkullBlock.Type.SKELETON, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block WITHER_SKELETON_SKULL = register(new SkullBlock("wither_skeleton_skull", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) + public static final Block WITHER_SKELETON_SKULL = register(new SkullBlock("wither_skeleton_skull", SkullBlock.Type.WITHER_SKELETON, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) .intState(ROTATION_16, 0, 15))); - public static final Block WITHER_SKELETON_WALL_SKULL = register(new SkullBlock("wither_skeleton_wall_skull", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) + public static final Block WITHER_SKELETON_WALL_SKULL = register(new WallSkullBlock("wither_skeleton_wall_skull", SkullBlock.Type.WITHER_SKELETON, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block ZOMBIE_HEAD = register(new SkullBlock("zombie_head", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) + public static final Block ZOMBIE_HEAD = register(new SkullBlock("zombie_head", SkullBlock.Type.ZOMBIE, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) .intState(ROTATION_16, 0, 15))); - public static final Block ZOMBIE_WALL_HEAD = register(new SkullBlock("zombie_wall_head", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) + public static final Block ZOMBIE_WALL_HEAD = register(new WallSkullBlock("zombie_wall_head", SkullBlock.Type.ZOMBIE, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block PLAYER_HEAD = register(new SkullBlock("player_head", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) + public static final Block PLAYER_HEAD = register(new SkullBlock("player_head", SkullBlock.Type.PLAYER, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) .intState(ROTATION_16, 0, 15))); - public static final Block PLAYER_WALL_HEAD = register(new SkullBlock("player_wall_head", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) + public static final Block PLAYER_WALL_HEAD = register(new WallSkullBlock("player_wall_head", SkullBlock.Type.PLAYER, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block CREEPER_HEAD = register(new SkullBlock("creeper_head", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) + public static final Block CREEPER_HEAD = register(new SkullBlock("creeper_head", SkullBlock.Type.CREEPER, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) .intState(ROTATION_16, 0, 15))); - public static final Block CREEPER_WALL_HEAD = register(new SkullBlock("creeper_wall_head", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) + public static final Block CREEPER_WALL_HEAD = register(new WallSkullBlock("creeper_wall_head", SkullBlock.Type.CREEPER, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block DRAGON_HEAD = register(new SkullBlock("dragon_head", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) + public static final Block DRAGON_HEAD = register(new SkullBlock("dragon_head", SkullBlock.Type.DRAGON, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) .intState(ROTATION_16, 0, 15))); - public static final Block DRAGON_WALL_HEAD = register(new SkullBlock("dragon_wall_head", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) + public static final Block DRAGON_WALL_HEAD = register(new WallSkullBlock("dragon_wall_head", SkullBlock.Type.DRAGON, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); - public static final Block PIGLIN_HEAD = register(new SkullBlock("piglin_head", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) + public static final Block PIGLIN_HEAD = register(new SkullBlock("piglin_head", SkullBlock.Type.PIGLIN, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) .intState(ROTATION_16, 0, 15))); - public static final Block PIGLIN_WALL_HEAD = register(new SkullBlock("piglin_wall_head", builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) + public static final Block PIGLIN_WALL_HEAD = register(new WallSkullBlock("piglin_wall_head", SkullBlock.Type.PIGLIN, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block ANVIL = register(new Block("anvil", builder().requiresCorrectToolForDrops().destroyTime(5.0f).pushReaction(PistonBehavior.BLOCK) @@ -1694,7 +1695,7 @@ public final class Blocks { public static final Block BLACK_CONCRETE_POWDER = register(new Block("black_concrete_powder", builder().destroyTime(0.5f))); public static final Block KELP = register(new Block("kelp", builder().pushReaction(PistonBehavior.DESTROY) .intState(AGE_25, 0, 25))); - public static final Block KELP_PLANT = register(new Block("kelp_plant", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block KELP_PLANT = register(new Block("kelp_plant", builder().pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.KELP))); public static final Block DRIED_KELP_BLOCK = register(new Block("dried_kelp_block", builder().destroyTime(0.5f))); public static final Block TURTLE_EGG = register(new Block("turtle_egg", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .intState(EGGS, 1, 4) @@ -1787,7 +1788,7 @@ public final class Blocks { public static final Block BLUE_ICE = register(new Block("blue_ice", builder().destroyTime(2.8f))); public static final Block CONDUIT = register(new Block("conduit", builder().setBlockEntity().destroyTime(3.0f) .booleanState(WATERLOGGED))); - public static final Block BAMBOO_SAPLING = register(new Block("bamboo_sapling", builder().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY))); + public static final Block BAMBOO_SAPLING = register(new Block("bamboo_sapling", builder().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.BAMBOO))); public static final Block BAMBOO = register(new Block("bamboo", builder().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .intState(AGE_1, 0, 1) .enumState(BAMBOO_LEAVES, "none", "small", "large") @@ -2072,10 +2073,10 @@ public final class Blocks { public static final Block SHROOMLIGHT = register(new Block("shroomlight", builder().destroyTime(1.0f))); public static final Block WEEPING_VINES = register(new Block("weeping_vines", builder().pushReaction(PistonBehavior.DESTROY) .intState(AGE_25, 0, 25))); - public static final Block WEEPING_VINES_PLANT = register(new Block("weeping_vines_plant", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block WEEPING_VINES_PLANT = register(new Block("weeping_vines_plant", builder().pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.WEEPING_VINES))); public static final Block TWISTING_VINES = register(new Block("twisting_vines", builder().pushReaction(PistonBehavior.DESTROY) .intState(AGE_25, 0, 25))); - public static final Block TWISTING_VINES_PLANT = register(new Block("twisting_vines_plant", builder().pushReaction(PistonBehavior.DESTROY))); + public static final Block TWISTING_VINES_PLANT = register(new Block("twisting_vines_plant", builder().pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.TWISTING_VINES))); public static final Block CRIMSON_ROOTS = register(new Block("crimson_roots", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block CRIMSON_PLANKS = register(new Block("crimson_planks", builder().destroyTime(2.0f))); public static final Block WARPED_PLANKS = register(new Block("warped_planks", builder().destroyTime(2.0f))); @@ -2319,39 +2320,39 @@ public final class Blocks { .intState(CANDLES, 1, 4) .booleanState(LIT) .booleanState(WATERLOGGED))); - public static final Block CANDLE_CAKE = register(new Block("candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) + public static final Block CANDLE_CAKE = register(new Block("candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.CAKE) .booleanState(LIT))); - public static final Block WHITE_CANDLE_CAKE = register(new Block("white_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) + public static final Block WHITE_CANDLE_CAKE = register(new Block("white_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.CAKE) .booleanState(LIT))); - public static final Block ORANGE_CANDLE_CAKE = register(new Block("orange_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) + public static final Block ORANGE_CANDLE_CAKE = register(new Block("orange_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.CAKE) .booleanState(LIT))); - public static final Block MAGENTA_CANDLE_CAKE = register(new Block("magenta_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) + public static final Block MAGENTA_CANDLE_CAKE = register(new Block("magenta_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.CAKE) .booleanState(LIT))); - public static final Block LIGHT_BLUE_CANDLE_CAKE = register(new Block("light_blue_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) + public static final Block LIGHT_BLUE_CANDLE_CAKE = register(new Block("light_blue_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.CAKE) .booleanState(LIT))); - public static final Block YELLOW_CANDLE_CAKE = register(new Block("yellow_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) + public static final Block YELLOW_CANDLE_CAKE = register(new Block("yellow_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.CAKE) .booleanState(LIT))); - public static final Block LIME_CANDLE_CAKE = register(new Block("lime_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) + public static final Block LIME_CANDLE_CAKE = register(new Block("lime_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.CAKE) .booleanState(LIT))); - public static final Block PINK_CANDLE_CAKE = register(new Block("pink_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) + public static final Block PINK_CANDLE_CAKE = register(new Block("pink_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.CAKE) .booleanState(LIT))); - public static final Block GRAY_CANDLE_CAKE = register(new Block("gray_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) + public static final Block GRAY_CANDLE_CAKE = register(new Block("gray_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.CAKE) .booleanState(LIT))); - public static final Block LIGHT_GRAY_CANDLE_CAKE = register(new Block("light_gray_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) + public static final Block LIGHT_GRAY_CANDLE_CAKE = register(new Block("light_gray_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.CAKE) .booleanState(LIT))); - public static final Block CYAN_CANDLE_CAKE = register(new Block("cyan_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) + public static final Block CYAN_CANDLE_CAKE = register(new Block("cyan_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.CAKE) .booleanState(LIT))); - public static final Block PURPLE_CANDLE_CAKE = register(new Block("purple_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) + public static final Block PURPLE_CANDLE_CAKE = register(new Block("purple_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.CAKE) .booleanState(LIT))); - public static final Block BLUE_CANDLE_CAKE = register(new Block("blue_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) + public static final Block BLUE_CANDLE_CAKE = register(new Block("blue_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.CAKE) .booleanState(LIT))); - public static final Block BROWN_CANDLE_CAKE = register(new Block("brown_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) + public static final Block BROWN_CANDLE_CAKE = register(new Block("brown_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.CAKE) .booleanState(LIT))); - public static final Block GREEN_CANDLE_CAKE = register(new Block("green_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) + public static final Block GREEN_CANDLE_CAKE = register(new Block("green_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.CAKE) .booleanState(LIT))); - public static final Block RED_CANDLE_CAKE = register(new Block("red_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) + public static final Block RED_CANDLE_CAKE = register(new Block("red_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.CAKE) .booleanState(LIT))); - public static final Block BLACK_CANDLE_CAKE = register(new Block("black_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) + public static final Block BLACK_CANDLE_CAKE = register(new Block("black_candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.CAKE) .booleanState(LIT))); public static final Block AMETHYST_BLOCK = register(new Block("amethyst_block", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block BUDDING_AMETHYST = register(new Block("budding_amethyst", builder().requiresCorrectToolForDrops().destroyTime(1.5f).pushReaction(PistonBehavior.DESTROY))); @@ -2682,7 +2683,7 @@ public final class Blocks { public static final Block CAVE_VINES = register(new Block("cave_vines", builder().pushReaction(PistonBehavior.DESTROY) .intState(AGE_25, 0, 25) .booleanState(BERRIES))); - public static final Block CAVE_VINES_PLANT = register(new Block("cave_vines_plant", builder().pushReaction(PistonBehavior.DESTROY) + public static final Block CAVE_VINES_PLANT = register(new Block("cave_vines_plant", builder().pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.GLOW_BERRIES) .booleanState(BERRIES))); public static final Block SPORE_BLOSSOM = register(new Block("spore_blossom", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block AZALEA = register(new Block("azalea", builder().pushReaction(PistonBehavior.DESTROY))); @@ -2811,7 +2812,8 @@ public final class Blocks { .booleanState(WATERLOGGED))); private static T register(T block) { - BlockRegistries.JAVA_BLOCKS_TO_RENAME.get().add(block); + block.setJavaId(BlockRegistries.JAVA_BLOCKS.get().size()); + BlockRegistries.JAVA_BLOCKS.get().add(block); return block; } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/DoubleChestValue.java b/core/src/main/java/org/geysermc/geyser/level/block/DoubleChestValue.java deleted file mode 100644 index 97c861df7..000000000 --- a/core/src/main/java/org/geysermc/geyser/level/block/DoubleChestValue.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.geyser.level.block; - -/** - * This stores all values of double chests that are part of the Java block state. - * - * @param isFacingEast If true, then chest is facing east/west; if false, south/north - * @param isDirectionPositive If true, direction is positive (east/south); if false, direction is negative (west/north) - * @param isLeft If true, chest is the left of a pair; if false, chest is the right of a pair. - */ -public record DoubleChestValue( - boolean isFacingEast, - boolean isDirectionPositive, - boolean isLeft) { - -} diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java b/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java index 491894a35..b31c9aeb5 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java @@ -37,24 +37,33 @@ import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.level.block.Blocks; -import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.property.Property; import org.geysermc.geyser.level.physics.PistonBehavior; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import org.intellij.lang.annotations.Subst; import java.util.*; +import java.util.function.Supplier; import java.util.stream.Stream; public class Block { public static final int JAVA_AIR_ID = 0; private final Key javaIdentifier; + /** + * Can you harvest this with your hand. + */ private final boolean requiresCorrectToolForDrops; private final boolean hasBlockEntity; private final float destroyTime; private final @NonNull PistonBehavior pushReaction; + /** + * Used for classes we don't have implemented yet that override Mojmap getCloneItemStack with their own item. + * A supplier prevents any issues arising where the Items class finishes before the Blocks class. + */ + private final Supplier pickItem; protected Item item = null; private int javaId = -1; @@ -64,10 +73,13 @@ public class Block { this.hasBlockEntity = builder.hasBlockEntity; this.destroyTime = builder.destroyTime; this.pushReaction = builder.pushReaction; + this.pickItem = builder.pickItem; processStates(builder.build(this)); } public void updateBlock(GeyserSession session, BlockState state, Vector3i position) { + checkForEmptySkull(session, state, position); + BlockDefinition definition = session.getBlockMappings().getBedrockBlock(state); sendBlockUpdatePacket(session, state, definition, position); @@ -118,8 +130,7 @@ public class Block { UpdateBlockPacket waterPacket = new UpdateBlockPacket(); waterPacket.setDataLayer(1); waterPacket.setBlockPosition(position); - Boolean waterlogged = state.getValue(Properties.WATERLOGGED); - if (waterlogged == Boolean.TRUE) { + if (BlockRegistries.WATERLOGGED.get().get(state.javaId())) { waterPacket.setDefinition(session.getBlockMappings().getBedrockWater()); } else { waterPacket.setDefinition(session.getBlockMappings().getBedrockAir()); @@ -127,6 +138,13 @@ public class Block { session.sendUpstreamPacket(waterPacket); } + protected void checkForEmptySkull(GeyserSession session, BlockState state, Vector3i position) { + if (!(state.block() instanceof SkullBlock)) { + // Skull is gone + session.getSkullCache().removeSkull(position); + } + } + protected void handleLecternBlockUpdate(GeyserSession session, BlockState state, Vector3i position) { // Block state is out of bounds of this map - lectern has been destroyed, if it existed if (!session.getGeyser().getWorldManager().shouldExpectLecternHandled(session)) { @@ -141,6 +159,13 @@ public class Block { return this.item; } + public ItemStack pickItem(BlockState state) { + if (this.pickItem != null) { + return new ItemStack(this.pickItem.get().javaId()); + } + return new ItemStack(this.asItem().javaId()); + } + /** * A list of BlockStates is created pertaining to this block. Do we need any of them? If so, override this method. */ @@ -198,6 +223,7 @@ public class Block { private boolean hasBlockEntity = false; private PistonBehavior pushReaction = PistonBehavior.NORMAL; private float destroyTime; + private Supplier pickItem; /** * For states that we're just tracking for mirroring Java states. @@ -248,6 +274,11 @@ public class Block { return this; } + public Builder pickItem(Supplier pickItem) { + this.pickItem = pickItem; + return this; + } + private List build(Block block) { if (states.isEmpty()) { BlockState state = new BlockState(block, BlockRegistries.BLOCK_STATES.get().size()); diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java b/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java index cb375eaf9..4fed30e7a 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java @@ -37,7 +37,7 @@ public final class BlockState { private final int javaId; private final Reference2ObjectMap, Comparable> states; - BlockState(Block block, int javaId) { + public BlockState(Block block, int javaId) { this(block, javaId, Reference2ObjectMaps.emptyMap()); } @@ -52,6 +52,14 @@ public final class BlockState { return (T) states.get(property); } + public boolean getValue(Property property, boolean def) { + var value = states.get(property); + if (value == null) { + return def; + } + return (Boolean) value; + } + public Block block() { return block; } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/FlowerPotBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/FlowerPotBlock.java index 53d0b1ec1..5107616af 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/FlowerPotBlock.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/FlowerPotBlock.java @@ -34,6 +34,7 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.level.block.entity.BedrockChunkWantsBlockEntityTag; import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator; import org.geysermc.geyser.util.BlockEntityUtils; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; public class FlowerPotBlock extends Block implements BedrockChunkWantsBlockEntityTag { private final Block flower; @@ -68,11 +69,24 @@ public class FlowerPotBlock extends Block implements BedrockChunkWantsBlockEntit if (this.flower != Blocks.AIR) { // Get the Bedrock CompoundTag of the block. // This is where we need to store the *Java* name because Bedrock has six minecraft:sapling blocks with different block states. - NbtMap plant = session.getBlockMappings().getFlowerPotBlocks().get(this.flower.javaIdentifier().asString()); + // TODO flattening might make this nicer in the future! + NbtMap plant = session.getBlockMappings().getFlowerPotBlocks().get(this.flower); if (plant != null) { tagBuilder.putCompound("PlantBlock", plant.toBuilder().build()); } } return tagBuilder.build(); } + + @Override + public ItemStack pickItem(BlockState state) { + if (this.flower != Blocks.AIR) { + return new ItemStack(this.flower.asItem().javaId()); + } + return super.pickItem(state); + } + + public Block flower() { + return flower; + } } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/SkullBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/SkullBlock.java index 01a757eae..76b532919 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/SkullBlock.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/SkullBlock.java @@ -27,28 +27,58 @@ package org.geysermc.geyser.level.block.type; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; -import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.SkullCache; public class SkullBlock extends Block { - public SkullBlock(String javaIdentifier, Builder builder) { + private final Type type; + + public SkullBlock(String javaIdentifier, Type type, Builder builder) { super(javaIdentifier, builder); + this.type = type; } @Override protected void sendBlockUpdatePacket(GeyserSession session, BlockState state, BlockDefinition definition, Vector3i position) { - int skullVariant = BlockStateValues.getSkullVariant(state.javaId()); // TODO - if (skullVariant == -1) { - // Skull is gone - session.getSkullCache().removeSkull(position); - } else if (skullVariant == 3) { + if (this.type == Type.PLAYER) { // The changed block was a player skull so check if a custom block was defined for this skull - SkullCache.Skull skull = session.getSkullCache().updateSkull(position, state.javaId()); + SkullCache.Skull skull = session.getSkullCache().updateSkull(position, state); if (skull != null && skull.getBlockDefinition() != null) { definition = skull.getBlockDefinition(); } } super.sendBlockUpdatePacket(session, state, definition, position); } + + @Override + protected void checkForEmptySkull(GeyserSession session, BlockState state, Vector3i position) { + // It's not an empty skull. + } + + public Type skullType() { + return type; + } + + /** + * Enum order matches Java. + */ + public enum Type { + SKELETON(0), + WITHER_SKELETON(1), + PLAYER(3), + ZOMBIE(2), + CREEPER(4), + PIGLIN(6), + DRAGON(5); + + private final int bedrockId; + + Type(int bedrockId) { + this.bedrockId = bedrockId; + } + + public int bedrockId() { + return bedrockId; + } + } } diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/BlockMapping.java b/core/src/main/java/org/geysermc/geyser/level/block/type/WallSkullBlock.java similarity index 58% rename from core/src/main/java/org/geysermc/geyser/registry/type/BlockMapping.java rename to core/src/main/java/org/geysermc/geyser/level/block/type/WallSkullBlock.java index 0520924f8..e8fedcc76 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/type/BlockMapping.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/WallSkullBlock.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * Copyright (c) 2024 GeyserMC. http://geysermc.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,21 +23,27 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.geyser.registry.type; +package org.geysermc.geyser.level.block.type; -import lombok.Builder; -import lombok.Value; -import org.checkerframework.checker.nullness.qual.Nullable; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.level.physics.Direction; -@Builder -@Value -public class BlockMapping { - public static BlockMapping DEFAULT = BlockMapping.builder().javaIdentifier("minecraft:air").build(); +public class WallSkullBlock extends SkullBlock { + public WallSkullBlock(String javaIdentifier, Type type, Builder builder) { + super(javaIdentifier, type, builder); + } - String javaIdentifier; + public static int getDegrees(BlockState state) { + return getDegrees(state.getValue(Properties.HORIZONTAL_FACING)); + } - @Nullable String pickItem; - - boolean isBlockEntity; - boolean isNonVanilla; + public static int getDegrees(Direction direction) { + return switch (direction) { + case NORTH -> 180; + case WEST -> 90; + case EAST -> 270; + case SOUTH -> 0; + default -> throw new IllegalStateException(); + }; + } } diff --git a/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java b/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java index a18ffff7d..93ac5e457 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java +++ b/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java @@ -42,7 +42,6 @@ import org.geysermc.geyser.registry.loader.RegistryLoaders; import org.geysermc.geyser.registry.populator.BlockRegistryPopulator; import org.geysermc.geyser.registry.populator.CustomBlockRegistryPopulator; import org.geysermc.geyser.registry.populator.CustomSkullRegistryPopulator; -import org.geysermc.geyser.registry.type.BlockMapping; import org.geysermc.geyser.registry.type.BlockMappings; import org.geysermc.geyser.registry.type.CustomSkull; import org.geysermc.geyser.translator.collision.BlockCollision; @@ -67,24 +66,22 @@ public class BlockRegistries { */ public static final ListRegistry BLOCK_STATES = ListRegistry.create(RegistryLoaders.empty(ArrayList::new)); - public static final ListRegistry JAVA_BLOCKS_TO_RENAME = ListRegistry.create(RegistryLoaders.empty(ArrayList::new)); - /** * A mapped registry which stores Java to Bedrock block identifiers. */ public static final SimpleMappedRegistry JAVA_TO_BEDROCK_IDENTIFIERS = SimpleMappedRegistry.create(RegistryLoaders.empty(Object2ObjectOpenHashMap::new)); - /** - * A registry which stores Java IDs to {@link BlockMapping}, containing miscellaneous information about - * blocks and their behavior in many cases. - */ - public static final ArrayRegistry JAVA_BLOCKS = ArrayRegistry.create(RegistryLoaders.uninitialized()); - /** * A mapped registry containing which holds block IDs to its {@link BlockCollision}. */ public static final ListRegistry COLLISIONS; + /** + * A registry which stores Java IDs to {@link Block}, containing miscellaneous information about + * blocks and their behavior in many cases. + */ + public static final ListRegistry JAVA_BLOCKS = ListRegistry.create(RegistryLoaders.empty(ArrayList::new)); + /** * A mapped registry containing the Java identifiers to IDs. */ diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java index 0180fc8b7..a0af4cfa0 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java @@ -32,13 +32,12 @@ import com.google.common.collect.Interner; import com.google.common.collect.Interners; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.ints.IntOpenHashSet; +import it.unimi.dsi.fastutil.ints.IntSet; import it.unimi.dsi.fastutil.objects.*; import org.cloudburstmc.blockstateupdater.BlockStateUpdater; import org.cloudburstmc.blockstateupdater.util.tagupdater.CompoundTagUpdaterContext; -import org.cloudburstmc.nbt.NBTInputStream; -import org.cloudburstmc.nbt.NbtMap; -import org.cloudburstmc.nbt.NbtMapBuilder; -import org.cloudburstmc.nbt.NbtType; +import org.cloudburstmc.nbt.*; import org.cloudburstmc.protocol.bedrock.codec.v622.Bedrock_v622; import org.cloudburstmc.protocol.bedrock.codec.v630.Bedrock_v630; import org.cloudburstmc.protocol.bedrock.codec.v649.Bedrock_v649; @@ -50,21 +49,26 @@ import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.block.custom.CustomBlockData; import org.geysermc.geyser.api.block.custom.CustomBlockState; import org.geysermc.geyser.api.block.custom.nonvanilla.JavaBlockState; -import org.geysermc.geyser.item.type.Item; +import org.geysermc.geyser.item.Items; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.Blocks; +import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.type.Block; +import org.geysermc.geyser.level.block.type.BlockState; +import org.geysermc.geyser.level.block.type.FlowerPotBlock; import org.geysermc.geyser.level.physics.PistonBehavior; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.Registries; -import org.geysermc.geyser.registry.type.BlockMapping; import org.geysermc.geyser.registry.type.BlockMappings; import org.geysermc.geyser.registry.type.GeyserBedrockBlock; import org.geysermc.geyser.util.BlockUtils; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import java.io.DataInputStream; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.*; +import java.util.stream.Stream; import java.util.zip.GZIPInputStream; /** @@ -102,7 +106,7 @@ public final class BlockRegistryPopulator { public static void populate(Stage stage) { switch (stage) { - case PRE_INIT, POST_INIT -> nullifyBlocksNode(); + case PRE_INIT, POST_INIT -> nullifyBlocksNbt(); case INIT_JAVA -> registerJavaBlocks(); case INIT_BEDROCK -> registerBedrockBlocks(); default -> throw new IllegalArgumentException("Unknown stage: " + stage); @@ -110,14 +114,14 @@ public final class BlockRegistryPopulator { } /** - * Stores the raw blocks JSON until it is no longer needed. + * Stores the raw blocks NBT until it is no longer needed. */ - private static JsonNode BLOCKS_JSON; + private static List BLOCKS_NBT; private static int MIN_CUSTOM_RUNTIME_ID = -1; private static int JAVA_BLOCKS_SIZE = -1; - private static void nullifyBlocksNode() { - BLOCKS_JSON = null; + private static void nullifyBlocksNbt() { + BLOCKS_NBT = null; } private static void registerBedrockBlocks() { @@ -218,19 +222,31 @@ public final class BlockRegistryPopulator { int javaRuntimeId = -1; + List javaBlockStates = BlockRegistries.BLOCK_STATES.get(); + GeyserBedrockBlock airDefinition = null; BlockDefinition commandBlockDefinition = null; BlockDefinition mobSpawnerBlockDefinition = null; BlockDefinition waterDefinition = null; BlockDefinition movingBlockDefinition = null; - Iterator> blocksIterator = BLOCKS_JSON.fields(); + Iterator blocksIterator = BLOCKS_NBT.iterator(); Remapper stateMapper = blockMappers.get(palette); GeyserBedrockBlock[] javaToBedrockBlocks = new GeyserBedrockBlock[JAVA_BLOCKS_SIZE]; GeyserBedrockBlock[] javaToVanillaBedrockBlocks = new GeyserBedrockBlock[JAVA_BLOCKS_SIZE]; - Map flowerPotBlocks = new Object2ObjectOpenHashMap<>(); + // Stream isn't ideal. + List javaPottable = BlockRegistries.JAVA_BLOCKS.get() + .parallelStream() + .flatMap(block -> { + if (block instanceof FlowerPotBlock flowerPot && flowerPot.flower() != Blocks.AIR) { + return Stream.of(flowerPot.flower()); + } + return null; + }) + .toList(); + Map flowerPotBlocks = new Object2ObjectOpenHashMap<>(); Map itemFrames = new Object2ObjectOpenHashMap<>(); Set jigsawDefinitions = new ObjectOpenHashSet<>(); @@ -239,10 +255,11 @@ public final class BlockRegistryPopulator { BlockMappings.BlockMappingsBuilder builder = BlockMappings.builder(); while (blocksIterator.hasNext()) { javaRuntimeId++; - Map.Entry entry = blocksIterator.next(); - String javaId = entry.getKey(); + NbtMap entry = blocksIterator.next(); + BlockState blockState = javaBlockStates.get(javaRuntimeId); + String javaId = blockState.toString(); - NbtMap originalBedrockTag = buildBedrockState(entry.getValue()); + NbtMap originalBedrockTag = buildBedrockState(blockState, entry); NbtMap bedrockTag = stateMapper.remap(originalBedrockTag); GeyserBedrockBlock vanillaBedrockDefinition = blockStateOrderedMap.get(bedrockTag); @@ -274,35 +291,27 @@ public final class BlockRegistryPopulator { case "minecraft:moving_piston[facing=north,type=normal]" -> movingBlockDefinition = bedrockDefinition; } - if (javaId.contains("jigsaw")) { + if (blockState.block() == Blocks.JIGSAW) { jigsawDefinitions.add(bedrockDefinition); } - if (javaId.contains("structure_block")) { - int modeIndex = javaId.indexOf("mode="); - if (modeIndex != -1) { - int startIndex = modeIndex + 5; // Length of "mode=" is 5 - int endIndex = javaId.indexOf("]", startIndex); - if (endIndex != -1) { - String modeValue = javaId.substring(startIndex, endIndex); - structureBlockDefinitions.put(modeValue.toUpperCase(), bedrockDefinition); - } - } + if (blockState.block() == Blocks.STRUCTURE_BLOCK) { + String mode = blockState.getValue(Properties.STRUCTUREBLOCK_MODE); + structureBlockDefinitions.put(mode.toUpperCase(Locale.ROOT), bedrockDefinition); } - boolean waterlogged = entry.getKey().contains("waterlogged=true") - || javaId.contains("minecraft:bubble_column") || javaId.contains("minecraft:kelp") || javaId.contains("seagrass"); + boolean waterlogged = blockState.getValue(Properties.WATERLOGGED, false) + || blockState.block() == Blocks.BUBBLE_COLUMN || blockState.block() == Blocks.KELP || blockState.block() == Blocks.SEAGRASS; if (waterlogged) { int finalJavaRuntimeId = javaRuntimeId; BlockRegistries.WATERLOGGED.register(set -> set.set(finalJavaRuntimeId)); } - String cleanJavaIdentifier = BlockUtils.getCleanIdentifier(entry.getKey()); - // Get the tag needed for non-empty flower pots - if (entry.getValue().get("pottable") != null) { - flowerPotBlocks.put(cleanJavaIdentifier.intern(), blockStates.get(bedrockDefinition.getRuntimeId())); + if (javaPottable.contains(blockState.block())) { + // Specifically NOT putIfAbsent - mangrove propagule breaks otherwise + flowerPotBlocks.put(blockState.block(), blockStates.get(bedrockDefinition.getRuntimeId())); } javaToVanillaBedrockBlocks[javaRuntimeId] = vanillaBedrockDefinition; @@ -386,9 +395,10 @@ public final class BlockRegistryPopulator { } private static void registerJavaBlocks() { - JsonNode blocksJson; - try (InputStream stream = GeyserImpl.getInstance().getBootstrap().getResourceOrThrow("mappings/blocks.json")) { - blocksJson = GeyserImpl.JSON_MAPPER.readTree(stream); + List blocksNbt; + try (InputStream stream = GeyserImpl.getInstance().getBootstrap().getResourceOrThrow("mappings/blocks.nbt")) { + blocksNbt = ((NbtMap) NbtUtils.createGZIPReader(stream).readTag()) + .getList("bedrock_mappings", NbtType.COMPOUND); } catch (Exception e) { throw new AssertionError("Unable to load Java block mappings", e); } @@ -399,56 +409,29 @@ public final class BlockRegistryPopulator { MIN_CUSTOM_RUNTIME_ID = BlockRegistries.NON_VANILLA_BLOCK_STATE_OVERRIDES.get().keySet().stream().min(Comparator.comparing(JavaBlockState::javaId)).orElseThrow().javaId(); int maxCustomRuntimeID = BlockRegistries.NON_VANILLA_BLOCK_STATE_OVERRIDES.get().keySet().stream().max(Comparator.comparing(JavaBlockState::javaId)).orElseThrow().javaId(); - if (MIN_CUSTOM_RUNTIME_ID < blocksJson.size()) { + if (MIN_CUSTOM_RUNTIME_ID < blocksNbt.size()) { throw new RuntimeException("Non vanilla custom block state overrides runtime ID must start after the last vanilla block state (" + JAVA_BLOCKS_SIZE + ")"); } JAVA_BLOCKS_SIZE = maxCustomRuntimeID + 1; // Runtime ids start at 0, so we need to add 1 } - BlockRegistries.JAVA_BLOCKS.set(new BlockMapping[JAVA_BLOCKS_SIZE]); // Set array size to number of blockstates - - Deque cleanIdentifiers = new ArrayDeque<>(); - int javaRuntimeId = -1; int waterRuntimeId = -1; - Iterator> blocksIterator = blocksJson.fields(); - while (blocksIterator.hasNext()) { + for (BlockState javaBlockState : BlockRegistries.BLOCK_STATES.get()) { javaRuntimeId++; - Map.Entry entry = blocksIterator.next(); - String javaId = entry.getKey(); + String javaId = javaBlockState.toString().intern(); - BlockMapping.BlockMappingBuilder builder = BlockMapping.builder(); + BlockStateValues.storeBlockStateValues(javaId, javaRuntimeId); - JsonNode pickItemNode = entry.getValue().get("pick_item"); - if (pickItemNode != null) { - builder.pickItem(pickItemNode.textValue().intern()); - } - - JsonNode hasBlockEntityNode = entry.getValue().get("has_block_entity"); - if (hasBlockEntityNode != null) { - builder.isBlockEntity(hasBlockEntityNode.booleanValue()); - } else { - builder.isBlockEntity(false); - } - - BlockStateValues.storeBlockStateValues(entry.getKey(), javaRuntimeId, entry.getValue()); - - String cleanJavaIdentifier = BlockUtils.getCleanIdentifier(entry.getKey()); - String bedrockIdentifier = entry.getValue().get("bedrock_identifier").asText(); - - if (!cleanJavaIdentifier.equals(cleanIdentifiers.peekLast())) { - cleanIdentifiers.add(cleanJavaIdentifier.intern()); - } - - builder.javaIdentifier(javaId); + //String cleanJavaIdentifier = javaBlockState.block().javaIdentifier().toString(); + //String bedrockIdentifier = entry.getValue().get("bedrock_identifier").asText(); BlockRegistries.JAVA_IDENTIFIER_TO_ID.register(javaId, javaRuntimeId); - BlockRegistries.JAVA_BLOCKS.register(javaRuntimeId, builder.build()); // Keeping this here since this is currently unchanged between versions // It's possible to only have this store differences in names, but the key set of all Java names is used in sending command suggestions - BlockRegistries.JAVA_TO_BEDROCK_IDENTIFIERS.register(cleanJavaIdentifier.intern(), bedrockIdentifier.intern()); + //BlockRegistries.JAVA_TO_BEDROCK_IDENTIFIERS.register(cleanJavaIdentifier.intern(), bedrockIdentifier.intern()); if ("minecraft:water[level=0]".equals(javaId)) { waterRuntimeId = javaRuntimeId; @@ -461,7 +444,7 @@ public final class BlockRegistryPopulator { BlockStateValues.JAVA_WATER_ID = waterRuntimeId; if (!BlockRegistries.NON_VANILLA_BLOCK_STATE_OVERRIDES.get().isEmpty()) { - Set usedNonVanillaRuntimeIDs = new HashSet<>(); + IntSet usedNonVanillaRuntimeIDs = new IntOpenHashSet(); for (JavaBlockState javaBlockState : BlockRegistries.NON_VANILLA_BLOCK_STATE_OVERRIDES.get().keySet()) { if (!usedNonVanillaRuntimeIDs.add(javaBlockState.javaId())) { @@ -473,11 +456,6 @@ public final class BlockRegistryPopulator { String javaId = javaBlockState.identifier(); int stateRuntimeId = javaBlockState.javaId(); String pistonBehavior = javaBlockState.pistonBehavior(); - BlockMapping blockMapping = BlockMapping.builder() - .pickItem(javaBlockState.pickItem()) - .isNonVanilla(true) - .javaIdentifier(javaId) - .build(); Block.Builder builder = Block.builder() .destroyTime(javaBlockState.blockHardness()) @@ -492,23 +470,25 @@ public final class BlockRegistryPopulator { String pickItem = javaBlockState.pickItem(); Block block = new Block(cleanJavaIdentifier, builder) { @Override - public Item asItem() { + public ItemStack pickItem(BlockState state) { if (this.item == null) { - return Registries.JAVA_ITEM_IDENTIFIERS.get(pickItem); + this.item = Registries.JAVA_ITEM_IDENTIFIERS.get(pickItem); + if (this.item == null) { + GeyserImpl.getInstance().getLogger().warning("We could not find item " + pickItem + + " for getting the item for block " + javaBlockState.identifier()); + this.item = Items.AIR; + } } - return this.item; + return new ItemStack(this.item.javaId()); } }; + block.setJavaId(javaBlockState.stateGroupId()); String bedrockIdentifier = customBlockState.block().identifier(); - if (!cleanJavaIdentifier.equals(cleanIdentifiers.peekLast())) { - cleanIdentifiers.add(cleanJavaIdentifier.intern()); - } - - BlockRegistries.JAVA_BLOCKS_TO_RENAME.get().add(javaBlockState.stateGroupId(), block); //TODO don't allow duplicates, allow blanks + BlockRegistries.JAVA_BLOCKS.get().add(javaBlockState.stateGroupId(), block); //TODO don't allow duplicates, allow blanks BlockRegistries.JAVA_IDENTIFIER_TO_ID.register(javaId, stateRuntimeId); - BlockRegistries.JAVA_BLOCKS.register(stateRuntimeId, blockMapping); + BlockRegistries.BLOCK_STATES.register(stateRuntimeId, new BlockState(block, stateRuntimeId)); // Keeping this here since this is currently unchanged between versions // It's possible to only have this store differences in names, but the key set of all Java names is used in sending command suggestions @@ -516,7 +496,7 @@ public final class BlockRegistryPopulator { } } - BLOCKS_JSON = blocksJson; + BLOCKS_NBT = blocksNbt; JsonNode blockInteractionsJson; try (InputStream stream = GeyserImpl.getInstance().getBootstrap().getResourceOrThrow("mappings/interactions.json")) { @@ -537,29 +517,11 @@ public final class BlockRegistryPopulator { return blockStateSet; } - private static NbtMap buildBedrockState(JsonNode node) { + private static NbtMap buildBedrockState(BlockState state, NbtMap nbt) { NbtMapBuilder tagBuilder = NbtMap.builder(); - String bedrockIdentifier = node.get("bedrock_identifier").textValue(); + String bedrockIdentifier = "minecraft:" + nbt.getString("bedrock_identifier", state.block().javaIdentifier().value()); tagBuilder.putString("name", bedrockIdentifier); - - NbtMapBuilder statesBuilder = NbtMap.builder(); - - // check for states - JsonNode states = node.get("bedrock_states"); - if (states != null) { - Iterator> statesIterator = states.fields(); - - while (statesIterator.hasNext()) { - Map.Entry stateEntry = statesIterator.next(); - JsonNode stateValue = stateEntry.getValue(); - switch (stateValue.getNodeType()) { - case BOOLEAN -> statesBuilder.putBoolean(stateEntry.getKey(), stateValue.booleanValue()); - case STRING -> statesBuilder.putString(stateEntry.getKey(), stateValue.textValue()); - case NUMBER -> statesBuilder.putInt(stateEntry.getKey(), stateValue.intValue()); - } - } - } - tagBuilder.put("states", statesBuilder.build()); + tagBuilder.put("states", nbt.getCompound("state")); return tagBuilder.build(); } diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java b/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java index 2fe808070..e4b7111b3 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java +++ b/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java @@ -35,6 +35,7 @@ import org.cloudburstmc.protocol.bedrock.data.BlockPropertyData; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.common.DefinitionRegistry; import org.geysermc.geyser.api.block.custom.CustomBlockState; +import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.level.block.type.BlockState; import java.util.List; @@ -59,7 +60,7 @@ public class BlockMappings implements DefinitionRegistry { BlockDefinition mobSpawnerBlock; Map itemFrames; - Map flowerPotBlocks; + Map flowerPotBlocks; Set jigsawStates; Map structureBlockStates; diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/SkullCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/SkullCache.java index 5b208a41f..a40a1156d 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/SkullCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/SkullCache.java @@ -25,18 +25,20 @@ package org.geysermc.geyser.session.cache; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.cloudburstmc.math.vector.Vector3f; -import org.cloudburstmc.math.vector.Vector3i; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import lombok.Data; import lombok.Getter; import lombok.RequiredArgsConstructor; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.cloudburstmc.math.vector.Vector3f; +import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.block.custom.CustomBlockState; import org.geysermc.geyser.entity.type.player.SkullPlayerEntity; -import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.level.block.type.BlockState; +import org.geysermc.geyser.level.block.type.WallSkullBlock; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.type.CustomSkull; import org.geysermc.geyser.session.GeyserSession; @@ -80,7 +82,7 @@ public class SkullCache { this.skullRenderDistanceSquared = distance * distance; } - public Skull putSkull(Vector3i position, UUID uuid, String texturesProperty, int blockState) { + public Skull putSkull(Vector3i position, UUID uuid, String texturesProperty, BlockState blockState) { Skull skull = skulls.computeIfAbsent(position, Skull::new); skull.uuid = uuid; if (!texturesProperty.equals(skull.texturesProperty)) { @@ -147,7 +149,7 @@ public class SkullCache { } } - public Skull updateSkull(Vector3i position, int blockState) { + public Skull updateSkull(Vector3i position, BlockState blockState) { Skull skull = skulls.get(position); if (skull != null) { putSkull(position, skull.uuid, skull.texturesProperty, blockState); @@ -248,17 +250,14 @@ public class SkullCache { lastPlayerPosition = null; } - private @Nullable BlockDefinition translateCustomSkull(String skinHash, int blockState) { + private @Nullable BlockDefinition translateCustomSkull(String skinHash, BlockState blockState) { CustomSkull customSkull = BlockRegistries.CUSTOM_SKULLS.get(skinHash); if (customSkull != null) { - byte floorRotation = BlockStateValues.getSkullRotation(blockState); CustomBlockState customBlockState; - if (floorRotation == -1) { - // Wall skull - int wallDirection = BlockStateValues.getSkullWallDirections().get(blockState); - customBlockState = customSkull.getWallBlockState(wallDirection); + if (blockState.block() instanceof WallSkullBlock) { + customBlockState = customSkull.getWallBlockState(WallSkullBlock.getDegrees(blockState)); } else { - customBlockState = customSkull.getFloorBlockState(floorRotation); + customBlockState = customSkull.getFloorBlockState(blockState.getValue(Properties.ROTATION_16)); } return session.getBlockMappings().getCustomBlockStateDefinitions().get(customBlockState); @@ -273,7 +272,7 @@ public class SkullCache { private String texturesProperty; private String skinHash; - private int blockState; + private BlockState blockState; private BlockDefinition blockDefinition; private SkullPlayerEntity entity; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java index cb973fa18..4c49c8e5a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java @@ -36,10 +36,13 @@ import org.cloudburstmc.protocol.bedrock.packet.ContainerOpenPacket; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; import org.geysermc.geyser.inventory.Container; import org.geysermc.geyser.inventory.Inventory; +import org.geysermc.geyser.level.block.Blocks; +import org.geysermc.geyser.level.block.property.ChestType; +import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.registry.BlockRegistries; -import org.geysermc.geyser.registry.type.BlockMapping; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator; import org.geysermc.geyser.translator.level.block.entity.DoubleChestBlockEntityTranslator; import org.geysermc.geyser.util.InventoryUtils; @@ -55,24 +58,17 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator { public boolean prepareInventory(GeyserSession session, Inventory inventory) { // See BlockInventoryHolder - same concept there except we're also dealing with a specific block state if (session.getLastInteractionPlayerPosition().equals(session.getPlayerEntity().getPosition())) { - int javaBlockId = session.getGeyser().getWorldManager().getBlockAt(session, session.getLastInteractionBlockPosition()); - if (!BlockRegistries.CUSTOM_BLOCK_STATE_OVERRIDES.get().containsKey(javaBlockId)) { - String[] javaBlockString = BlockRegistries.JAVA_BLOCKS.getOrDefault(javaBlockId, BlockMapping.DEFAULT).getJavaIdentifier().split("\\["); - if (javaBlockString.length > 1 && (javaBlockString[0].equals("minecraft:chest") || javaBlockString[0].equals("minecraft:trapped_chest")) - && !javaBlockString[1].contains("type=single")) { + BlockState state = session.getGeyser().getWorldManager().blockAt(session, session.getLastInteractionBlockPosition()); + if (!BlockRegistries.CUSTOM_BLOCK_STATE_OVERRIDES.get().containsKey(state.javaId())) { + if (state.block() == Blocks.CHEST || state.block() == Blocks.TRAPPED_CHEST + && state.getValue(Properties.CHEST_TYPE) != ChestType.SINGLE) { inventory.setHolderPosition(session.getLastInteractionBlockPosition()); - ((Container) inventory).setUsingRealBlock(true, javaBlockString[0]); + ((Container) inventory).setUsingRealBlock(true, state.block()); - NbtMapBuilder tag = NbtMap.builder() - .putString("id", "Chest") - .putInt("x", session.getLastInteractionBlockPosition().getX()) - .putInt("y", session.getLastInteractionBlockPosition().getY()) - .putInt("z", session.getLastInteractionBlockPosition().getZ()) - .putString("CustomName", inventory.getTitle()) - .putString("id", "Chest"); + NbtMapBuilder tag = BlockEntityTranslator.getConstantBedrockTag("Chest", session.getLastInteractionBlockPosition()) + .putString("CustomName", inventory.getTitle()); - BlockState blockState = BlockState.of(javaBlockId); - DoubleChestBlockEntityTranslator.translateChestValue(tag, blockState, + DoubleChestBlockEntityTranslator.translateChestValue(tag, state, session.getLastInteractionBlockPosition().getX(), session.getLastInteractionBlockPosition().getZ()); BlockEntityDataPacket dataPacket = new BlockEntityDataPacket(); diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java index c03ae8ef0..cdbb20c44 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SkullBlockEntityTranslator.java @@ -33,9 +33,9 @@ import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.type.BlockState; +import org.geysermc.geyser.level.block.type.SkullBlock; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.SkullCache; import org.geysermc.geyser.skin.SkinProvider; @@ -53,17 +53,12 @@ public class SkullBlockEntityTranslator extends BlockEntityTranslator implements @Override public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) { - byte skullVariant = BlockStateValues.getSkullVariant(blockState.javaId()); // TODO - // Just in case... - if (skullVariant == -1) { - skullVariant = 0; - } Integer rotation = blockState.getValue(Properties.ROTATION_16); if (rotation != null) { - // Could be a wall skull block + // Could be a wall skull block otherwise, which has rotation in its Bedrock state bedrockNbt.putFloat("Rotation", rotation * 22.5f); } - bedrockNbt.putByte("SkullType", skullVariant); + bedrockNbt.putByte("SkullType", (byte) (blockState.block() instanceof SkullBlock skull ? skull.skullType().bedrockId() : 0)); if (blockState.getValue(Properties.POWERED)) { bedrockNbt.putBoolean("MouthMoving", true); } @@ -106,7 +101,7 @@ public class SkullBlockEntityTranslator extends BlockEntityTranslator implements return CompletableFuture.completedFuture(texture); } - public static @Nullable BlockDefinition translateSkull(GeyserSession session, NbtMap javaNbt, Vector3i blockPosition, int blockState) { + public static @Nullable BlockDefinition translateSkull(GeyserSession session, NbtMap javaNbt, Vector3i blockPosition, BlockState blockState) { NbtMap profile = javaNbt.getCompound("profile"); if (profile.isEmpty()) { session.getSkullCache().removeSkull(blockPosition); @@ -150,7 +145,7 @@ public class SkullBlockEntityTranslator extends BlockEntityTranslator implements return null; } - private static void putSkull(GeyserSession session, Vector3i blockPosition, UUID uuid, String texturesProperty, int blockState) { + private static void putSkull(GeyserSession session, Vector3i blockPosition, UUID uuid, String texturesProperty, BlockState blockState) { SkullCache.Skull skull = session.getSkullCache().putSkull(blockPosition, uuid, texturesProperty, blockState); if (skull.getBlockDefinition() != null) { UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java index be3af2061..0a721e4b0 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java @@ -32,7 +32,7 @@ import org.geysermc.geyser.entity.type.ItemFrameEntity; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.level.block.type.BannerBlock; -import org.geysermc.geyser.level.block.type.Block; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; @@ -45,10 +45,10 @@ public class BedrockBlockPickRequestTranslator extends PacketTranslator session.ensureInEventLoop(() -> { if (components == null) { @@ -73,7 +73,7 @@ public class BedrockBlockPickRequestTranslator extends PacketTranslator { @@ -77,9 +78,9 @@ public class BedrockLevelSoundEventTranslator extends PacketTranslator { @@ -102,7 +100,7 @@ public class JavaBlockUpdateTranslator extends PacketTranslator> 4) - (bedrockDimension.minY() >> 4); int subChunkIndex = (y >> 4) + (bedrockDimension.minY() >> 4); diff --git a/core/src/main/java/org/geysermc/geyser/util/StatisticsUtils.java b/core/src/main/java/org/geysermc/geyser/util/StatisticsUtils.java index 7e1227f6c..72fcb4fa6 100644 --- a/core/src/main/java/org/geysermc/geyser/util/StatisticsUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/StatisticsUtils.java @@ -94,7 +94,7 @@ public class StatisticsUtils { for (Object2IntMap.Entry entry : session.getStatistics().object2IntEntrySet()) { if (entry.getKey() instanceof BreakBlockStatistic statistic) { - Block block = BlockRegistries.JAVA_BLOCKS_TO_RENAME.get(statistic.getId()); + Block block = BlockRegistries.JAVA_BLOCKS.get(statistic.getId()); if (block != null) { String identifier = "block.minecraft." + block.javaIdentifier().value(); content.add(identifier + ": " + entry.getIntValue()); diff --git a/core/src/main/java/org/geysermc/geyser/util/collection/FixedInt2BooleanMap.java b/core/src/main/java/org/geysermc/geyser/util/collection/FixedInt2BooleanMap.java deleted file mode 100644 index dc4545529..000000000 --- a/core/src/main/java/org/geysermc/geyser/util/collection/FixedInt2BooleanMap.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.geyser.util.collection; - -import it.unimi.dsi.fastutil.ints.AbstractInt2BooleanMap; -import it.unimi.dsi.fastutil.objects.ObjectSet; - -import java.io.Serial; - -public class FixedInt2BooleanMap extends AbstractInt2BooleanMap { - - @Serial - private static final long serialVersionUID = 1L; - - protected boolean[] value; - protected int start = -1; - - @Override - public int size() { - return value.length; - } - - @Override - public ObjectSet int2BooleanEntrySet() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean get(int i) { - return getOrDefault(i, defRetValue); - } - - @Override - public boolean getOrDefault(int key, boolean defaultValue) { - int offset = key - start; - if (offset < 0 || offset >= value.length) { - return defaultValue; - } - - return value[offset]; - } - - @Override - public boolean put(int key, boolean value) { - if (start == -1) { - start = key; - this.value = new boolean[] {value}; - } else { - int offset = key - start; - if (offset >= 0 && offset < this.value.length) { - boolean curr = this.value[offset]; - this.value[offset] = value; - return curr; - } else if (offset != this.value.length) { - throw new IndexOutOfBoundsException("Expected: " + (this.value.length + start) + ", got " + key); - } - - boolean[] newValue = new boolean[offset + 1]; - System.arraycopy(this.value, 0, newValue, 0, this.value.length); - this.value = newValue; - this.value[offset] = value; - } - - return this.defRetValue; - } - - @Override - public boolean containsKey(int k) { - int offset = k - start; - return offset >= 0 && offset < value.length; - } - - @Override - public boolean containsValue(boolean v) { - for (boolean b : value) { - if (b == v) { - return true; - } - } - - return false; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder("{"); - int index = start; - for (boolean b : value) { - builder.append(index++).append("=>").append(b); - if (index < value.length + start) { - // Add commas while there are still more entries in the list - builder.append(", "); - } - } - return builder.append('}').toString(); - } -} diff --git a/core/src/main/java/org/geysermc/geyser/util/collection/FixedInt2ByteMap.java b/core/src/main/java/org/geysermc/geyser/util/collection/FixedInt2ByteMap.java deleted file mode 100644 index 46cb2a2ca..000000000 --- a/core/src/main/java/org/geysermc/geyser/util/collection/FixedInt2ByteMap.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.geyser.util.collection; - -import it.unimi.dsi.fastutil.ints.AbstractInt2ByteMap; -import it.unimi.dsi.fastutil.ints.Int2ByteMap; -import it.unimi.dsi.fastutil.objects.ObjectSet; - -import java.io.Serial; - -public class FixedInt2ByteMap extends AbstractInt2ByteMap { - - @Serial - private static final long serialVersionUID = 1L; - - protected byte[] value; - protected int start = -1; - - @Override - public int size() { - return value.length; - } - - @Override - public ObjectSet int2ByteEntrySet() { - throw new UnsupportedOperationException(); - } - - @Override - public byte get(int i) { - return getOrDefault(i, defRetValue); - } - - @Override - public byte getOrDefault(int key, byte defaultValue) { - int offset = key - start; - if (offset < 0 || offset >= value.length) { - return defaultValue; - } - - return value[offset]; - } - - @Override - public byte put(int key, byte value) { - if (start == -1) { - start = key; - this.value = new byte[] {value}; - } else { - int offset = key - start; - if (offset >= 0 && offset < this.value.length) { - byte curr = this.value[offset]; - this.value[offset] = value; - return curr; - } else if (offset != this.value.length) { - throw new IndexOutOfBoundsException("Expected: " + (this.value.length + start) + ", got " + key); - } - - byte[] newValue = new byte[offset + 1]; - System.arraycopy(this.value, 0, newValue, 0, this.value.length); - this.value = newValue; - this.value[offset] = value; - } - - return this.defRetValue; - } - - @Override - public boolean containsKey(int k) { - int offset = k - start; - return offset >= 0 && offset < value.length; - } - - @Override - public boolean containsValue(byte v) { - for (byte i : value) { - if (i == v) { - return true; - } - } - - return false; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder("{"); - int index = start; - for (byte b : value) { - builder.append(index++).append("=>").append(b); - if (index < value.length + start) { - // Add commas while there are still more entries in the list - builder.append(", "); - } - } - return builder.append('}').toString(); - } -} diff --git a/core/src/main/java/org/geysermc/geyser/util/collection/FixedInt2IntMap.java b/core/src/main/java/org/geysermc/geyser/util/collection/FixedInt2IntMap.java deleted file mode 100644 index 4a27d51a9..000000000 --- a/core/src/main/java/org/geysermc/geyser/util/collection/FixedInt2IntMap.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.geyser.util.collection; - -import it.unimi.dsi.fastutil.ints.AbstractInt2IntMap; -import it.unimi.dsi.fastutil.ints.Int2IntMap; -import it.unimi.dsi.fastutil.objects.ObjectSet; - -import java.io.Serial; - -public class FixedInt2IntMap extends AbstractInt2IntMap { - protected int[] value; - protected int start = -1; - - @Serial - private static final long serialVersionUID = 1L; - - @Override - public int size() { - return value.length; - } - - @Override - public ObjectSet int2IntEntrySet() { - throw new UnsupportedOperationException(); - } - - @Override - public int get(int i) { - return getOrDefault(i, defRetValue); - } - - @Override - public int getOrDefault(int key, int defaultValue) { - int offset = key - start; - if (offset < 0 || offset >= value.length) { - return defaultValue; - } - - return value[offset]; - } - - @Override - public int put(int key, int value) { - if (start == -1) { - start = key; - this.value = new int[] {value}; - } else { - int offset = key - start; - if (offset >= 0 && offset < this.value.length) { - int curr = this.value[offset]; - this.value[offset] = value; - return curr; - } else if (offset != this.value.length) { - throw new IndexOutOfBoundsException("Expected: " + (this.value.length + start) + ", got " + key); - } - - int[] newValue = new int[offset + 1]; - System.arraycopy(this.value, 0, newValue, 0, this.value.length); - this.value = newValue; - this.value[offset] = value; - } - - return this.defRetValue; - } - - @Override - public boolean containsKey(int k) { - int offset = k - start; - return offset >= 0 && offset < value.length; - } - - @Override - public boolean containsValue(int v) { - for (int i : value) { - if (i == v) { - return true; - } - } - - return false; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder("{"); - int index = start; - for (int i : value) { - builder.append(index++).append("=>").append(i); - if (index < value.length + start) { - // Add commas while there are still more entries in the list - builder.append(", "); - } - } - return builder.append('}').toString(); - } -} diff --git a/core/src/main/java/org/geysermc/geyser/util/collection/LecternHasBookMap.java b/core/src/main/java/org/geysermc/geyser/util/collection/LecternHasBookMap.java deleted file mode 100644 index 42d0da803..000000000 --- a/core/src/main/java/org/geysermc/geyser/util/collection/LecternHasBookMap.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.geyser.util.collection; - -import org.cloudburstmc.math.vector.Vector3i; -import org.cloudburstmc.nbt.NbtMap; -import org.geysermc.erosion.util.LecternUtils; -import org.geysermc.geyser.level.WorldManager; -import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.util.BlockEntityUtils; - -import java.io.Serial; - -/** - * Map that takes advantage of its internals for fast operations on block states to determine if they are lecterns. - */ -public class LecternHasBookMap extends FixedInt2BooleanMap { - - @Serial - private static final long serialVersionUID = 1L; - - /** - * Update a potential lectern within the world. This is a map method so it can use the internal fields to - * optimize lectern determining. - */ - public void handleBlockChange(GeyserSession session, int blockState, Vector3i position) { - WorldManager worldManager = session.getGeyser().getWorldManager(); - - int offset = blockState - this.start; - if (offset < 0 || offset >= this.value.length) { - // Block state is out of bounds of this map - lectern has been destroyed, if it existed - if (!worldManager.shouldExpectLecternHandled(session)) { - session.getLecternCache().remove(position); - } - return; - } - - boolean newLecternHasBook; - if (worldManager.shouldExpectLecternHandled(session)) { - worldManager.sendLecternData(session, position.getX(), position.getY(), position.getZ()); - } else if ((newLecternHasBook = this.value[offset]) != this.get(worldManager.getBlockAt(session, position))) { - // newLecternHasBook = the new lectern block state's "has book" toggle. - if (newLecternHasBook) { - worldManager.sendLecternData(session, position.getX(), position.getY(), position.getZ()); - } else { - session.getLecternCache().remove(position); - NbtMap newLecternTag = LecternUtils.getBaseLecternTag(position.getX(), position.getY(), position.getZ(), 0).build(); - BlockEntityUtils.updateBlockEntity(session, newLecternTag, position); - } - } - } -} diff --git a/core/src/main/java/org/geysermc/geyser/util/collection/package-info.java b/core/src/main/java/org/geysermc/geyser/util/collection/package-info.java deleted file mode 100644 index 46fa5df11..000000000 --- a/core/src/main/java/org/geysermc/geyser/util/collection/package-info.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -/** - * Contains useful collections for use in Geyser. - *

- * Of note are the fixed int maps. Designed for use with block states that are positive and sequential, they do not allow keys to be - * added that are not greater by one versus the previous key. Because of this, speedy operations of {@link java.util.Map#get(java.lang.Object)} - * and {@link java.util.Map#containsKey(java.lang.Object)} can be performed by simply checking the bounds of the map - * size and its "start" integer. - */ -package org.geysermc.geyser.util.collection; \ No newline at end of file diff --git a/core/src/main/resources/mappings b/core/src/main/resources/mappings index 6b661f0d5..968a22bba 160000 --- a/core/src/main/resources/mappings +++ b/core/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 6b661f0d517d895aebc1f55a25d2c86f033beb1d +Subproject commit 968a22bbab02d7d003c5b451a40d8bb2439b0d97 diff --git a/core/src/test/java/org/geysermc/geyser/util/collection/GeyserCollectionsTest.java b/core/src/test/java/org/geysermc/geyser/util/collection/GeyserCollectionsTest.java deleted file mode 100644 index 639c79331..000000000 --- a/core/src/test/java/org/geysermc/geyser/util/collection/GeyserCollectionsTest.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.geyser.util.collection; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInstance; - -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -public class GeyserCollectionsTest { - private final byte[] bytes = new byte[] {(byte) 5, (byte) 4, (byte) 3, (byte) 2, (byte) 2, (byte) 1}; - private final boolean[] booleans = new boolean[] {true, false, false, true}; - private final int[] ints = new int[] {76, 3006, 999, 2323, 888, 0, 111, 999}; - - private final int[] startBlockRanges = new int[] {0, 70, 600, 450, 787, 1980}; - - @Test - public void testBytes() { - for (int startRange : startBlockRanges) { - testBytes(startRange, new FixedInt2ByteMap()); - } - } - - private void testBytes(final int start, final FixedInt2ByteMap map) { - int index = start; - for (byte b : bytes) { - map.put(index++, b); - } - - int lastKey = index; - - // Easy, understandable out-of-bounds checks - Assertions.assertFalse(map.containsKey(lastKey), "Map contains key bigger by one!"); - Assertions.assertTrue(map.containsKey(lastKey - 1), "Map doesn't contain final key!"); - - // Ensure the first and last values do not throw an exception on get, and test getOrDefault - map.get(start - 1); - map.get(lastKey); - Assertions.assertEquals(map.getOrDefault(start - 1, Byte.MAX_VALUE), Byte.MAX_VALUE); - Assertions.assertEquals(map.getOrDefault(lastKey, Byte.MAX_VALUE), Byte.MAX_VALUE); - Assertions.assertEquals(map.getOrDefault(lastKey, Byte.MIN_VALUE), Byte.MIN_VALUE); - - Assertions.assertEquals(map.size(), bytes.length); - - for (int i = start; i < bytes.length; i++) { - Assertions.assertTrue(map.containsKey(i)); - Assertions.assertEquals(map.get(i), bytes[i - start]); - } - - for (int i = start - 1; i >= (start - 6); i--) { - // Lower than expected check - Assertions.assertFalse(map.containsKey(i), i + " is in a map that starts with " + start); - } - - for (int i = bytes.length + start; i < bytes.length + 5 + start; i++) { - // Higher than expected check - Assertions.assertFalse(map.containsKey(i), i + " is in a map that ends with " + (start + bytes.length)); - } - - for (byte b : bytes) { - Assertions.assertTrue(map.containsValue(b)); - } - } - - @Test - public void testBooleans() { - for (int startRange : startBlockRanges) { - testBooleans(startRange, new FixedInt2BooleanMap()); - } - } - - private void testBooleans(final int start, final FixedInt2BooleanMap map) { - int index = start; - for (boolean b : booleans) { - map.put(index++, b); - } - - int lastKey = index; - - // Easy, understandable out-of-bounds checks - Assertions.assertFalse(map.containsKey(lastKey), "Map contains key bigger by one!"); - Assertions.assertTrue(map.containsKey(lastKey - 1), "Map doesn't contain final key!"); - - // Ensure the first and last values do not throw an exception on get - map.get(start - 1); - map.get(lastKey); - Assertions.assertTrue(map.getOrDefault(lastKey, true)); - - Assertions.assertEquals(map.size(), booleans.length); - - for (int i = start; i < booleans.length; i++) { - Assertions.assertTrue(map.containsKey(i)); - Assertions.assertEquals(map.get(i), booleans[i - start]); - } - - for (int i = start - 1; i >= (start - 6); i--) { - // Lower than expected check - Assertions.assertFalse(map.containsKey(i), i + " is in a map that starts with " + start); - } - - for (int i = booleans.length + start; i < booleans.length + start + 5; i++) { - // Higher than expected check - Assertions.assertFalse(map.containsKey(i), i + " is in a map that ends with " + (start + booleans.length)); - } - - for (boolean b : booleans) { - Assertions.assertTrue(map.containsValue(b)); - } - } - - @Test - public void testInts() { - for (int startRange : startBlockRanges) { - testInts(startRange, new FixedInt2IntMap()); - } - } - - private void testInts(final int start, final FixedInt2IntMap map) { - int index = start; - for (int i : ints) { - map.put(index++, i); - } - - int lastKey = index; - - // Easy, understandable out-of-bounds checks - Assertions.assertFalse(map.containsKey(lastKey), "Map contains key bigger by one!"); - Assertions.assertTrue(map.containsKey(lastKey - 1), "Map doesn't contain final key!"); - - // Ensure the first and last values do not throw an exception on get, and test getOrDefault - map.get(start - 1); - map.get(lastKey); - Assertions.assertEquals(map.getOrDefault(start - 1, Integer.MAX_VALUE), Integer.MAX_VALUE); - Assertions.assertEquals(map.getOrDefault(lastKey, Integer.MAX_VALUE), Integer.MAX_VALUE); - Assertions.assertEquals(map.getOrDefault(lastKey, Integer.MIN_VALUE), Integer.MIN_VALUE); - - Assertions.assertEquals(map.size(), ints.length); - - for (int i = start; i < ints.length; i++) { - Assertions.assertTrue(map.containsKey(i)); - Assertions.assertEquals(map.get(i), ints[i - start]); - } - - for (int i = start - 1; i >= (start - 6); i--) { - // Lower than expected check - Assertions.assertFalse(map.containsKey(i), i + " is in a map that starts with " + start); - } - - for (int i = ints.length + start; i < ints.length + 5 + start; i++) { - // Higher than expected check - Assertions.assertFalse(map.containsKey(i), i + " is in a map that ends with " + (start + ints.length)); - } - - for (int i : ints) { - Assertions.assertTrue(map.containsValue(i)); - } - } -} From 1b075badcedbba8332842562c651f8bf9c24d1c3 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sun, 19 May 2024 23:15:52 -0400 Subject: [PATCH 178/272] Actually implement adventure mode predicates, kind of. If it's just block IDs, it'll work. --- .../geyser/registry/BlockRegistries.java | 9 +-- .../geysermc/geyser/registry/Registries.java | 1 - .../populator/BlockRegistryPopulator.java | 36 +++++++---- .../geyser/registry/type/BlockMappings.java | 6 ++ .../translator/item/ItemTranslator.java | 64 +++++++++++-------- .../protocol/java/JavaCommandsTranslator.java | 11 +--- gradle/libs.versions.toml | 2 +- 7 files changed, 71 insertions(+), 58 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java b/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java index 93ac5e457..2f15094ef 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java +++ b/core/src/main/java/org/geysermc/geyser/registry/BlockRegistries.java @@ -66,11 +66,6 @@ public class BlockRegistries { */ public static final ListRegistry BLOCK_STATES = ListRegistry.create(RegistryLoaders.empty(ArrayList::new)); - /** - * A mapped registry which stores Java to Bedrock block identifiers. - */ - public static final SimpleMappedRegistry JAVA_TO_BEDROCK_IDENTIFIERS = SimpleMappedRegistry.create(RegistryLoaders.empty(Object2ObjectOpenHashMap::new)); - /** * A mapped registry containing which holds block IDs to its {@link BlockCollision}. */ @@ -89,6 +84,9 @@ public class BlockRegistries { /** * A registry containing all the waterlogged blockstates. + * Properties.WATERLOGGED should not be relied on for two reasons: + * - Custom blocks + * - Seagrass, kelp, and bubble columns are assumed waterlogged and don't have a waterlogged property */ public static final SimpleRegistry WATERLOGGED = SimpleRegistry.create(RegistryLoaders.empty(BitSet::new)); @@ -144,7 +142,6 @@ public class BlockRegistries { CustomBlockRegistryPopulator.populate(CustomBlockRegistryPopulator.Stage.CUSTOM_REGISTRATION); BlockRegistryPopulator.populate(BlockRegistryPopulator.Stage.INIT_BEDROCK); BlockRegistryPopulator.populate(BlockRegistryPopulator.Stage.POST_INIT); - System.out.println("Block registries loaded"); } public static void init() { diff --git a/core/src/main/java/org/geysermc/geyser/registry/Registries.java b/core/src/main/java/org/geysermc/geyser/registry/Registries.java index 7f0d9013a..54d013140 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/Registries.java +++ b/core/src/main/java/org/geysermc/geyser/registry/Registries.java @@ -204,6 +204,5 @@ public final class Registries { biomesNbt.put(key, value.build()); } BIOMES_NBT.set(biomesNbt.build()); - System.out.println("Registries loaded"); } } diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java index a0af4cfa0..5f50f4f68 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java @@ -236,6 +236,10 @@ public final class BlockRegistryPopulator { GeyserBedrockBlock[] javaToBedrockBlocks = new GeyserBedrockBlock[JAVA_BLOCKS_SIZE]; GeyserBedrockBlock[] javaToVanillaBedrockBlocks = new GeyserBedrockBlock[JAVA_BLOCKS_SIZE]; + //List javaToBedrockIdentifiers = new ArrayList<>(BlockRegistries.JAVA_BLOCKS.get().size()); + var javaToBedrockIdentifiers = new Int2ObjectOpenHashMap(); + Block lastBlockSeen = null; + // Stream isn't ideal. List javaPottable = BlockRegistries.JAVA_BLOCKS.get() .parallelStream() @@ -291,27 +295,35 @@ public final class BlockRegistryPopulator { case "minecraft:moving_piston[facing=north,type=normal]" -> movingBlockDefinition = bedrockDefinition; } - if (blockState.block() == Blocks.JIGSAW) { + Block block = blockState.block(); + if (block != lastBlockSeen) { + lastBlockSeen = block; + String bedrockName = bedrockDefinition.getState().getString("name"); + if (!block.javaIdentifier().toString().equals(bedrockName)) { + javaToBedrockIdentifiers.put(block.javaId(), bedrockName.substring("minecraft:".length()).intern()); + } + } + + if (block == Blocks.JIGSAW) { jigsawDefinitions.add(bedrockDefinition); } - if (blockState.block() == Blocks.STRUCTURE_BLOCK) { + if (block == Blocks.STRUCTURE_BLOCK) { String mode = blockState.getValue(Properties.STRUCTUREBLOCK_MODE); structureBlockDefinitions.put(mode.toUpperCase(Locale.ROOT), bedrockDefinition); } boolean waterlogged = blockState.getValue(Properties.WATERLOGGED, false) - || blockState.block() == Blocks.BUBBLE_COLUMN || blockState.block() == Blocks.KELP || blockState.block() == Blocks.SEAGRASS; + || block == Blocks.BUBBLE_COLUMN || block == Blocks.KELP || block == Blocks.SEAGRASS; if (waterlogged) { - int finalJavaRuntimeId = javaRuntimeId; - BlockRegistries.WATERLOGGED.register(set -> set.set(finalJavaRuntimeId)); + BlockRegistries.WATERLOGGED.get().set(javaRuntimeId); } // Get the tag needed for non-empty flower pots - if (javaPottable.contains(blockState.block())) { + if (javaPottable.contains(block)) { // Specifically NOT putIfAbsent - mangrove propagule breaks otherwise - flowerPotBlocks.put(blockState.block(), blockStates.get(bedrockDefinition.getRuntimeId())); + flowerPotBlocks.put(block, blockStates.get(bedrockDefinition.getRuntimeId())); } javaToVanillaBedrockBlocks[javaRuntimeId] = vanillaBedrockDefinition; @@ -367,9 +379,12 @@ public final class BlockRegistryPopulator { javaToVanillaBedrockBlocks[stateRuntimeId] = bedrockDefinition; // TODO: Check this? javaToBedrockBlocks[stateRuntimeId] = bedrockDefinition; + javaToBedrockIdentifiers.put(entry.getKey().stateGroupId(), entry.getValue().block().identifier()); } } + javaToBedrockIdentifiers.trim(); + // Loop around again to find all item frame runtime IDs Object2ObjectMaps.fastForEach(blockStateOrderedMap, entry -> { String name = entry.getKey().getString("name"); @@ -381,6 +396,7 @@ public final class BlockRegistryPopulator { BlockRegistries.BLOCKS.register(palette.valueInt(), builder.bedrockRuntimeMap(bedrockRuntimeMap) .javaToBedrockBlocks(javaToBedrockBlocks) .javaToVanillaBedrockBlocks(javaToVanillaBedrockBlocks) + .javaToBedrockIdentifiers(javaToBedrockIdentifiers) .stateDefinitionMap(blockStateOrderedMap) .itemFrames(itemFrames) .flowerPotBlocks(flowerPotBlocks) @@ -484,15 +500,9 @@ public final class BlockRegistryPopulator { }; block.setJavaId(javaBlockState.stateGroupId()); - String bedrockIdentifier = customBlockState.block().identifier(); - BlockRegistries.JAVA_BLOCKS.get().add(javaBlockState.stateGroupId(), block); //TODO don't allow duplicates, allow blanks BlockRegistries.JAVA_IDENTIFIER_TO_ID.register(javaId, stateRuntimeId); BlockRegistries.BLOCK_STATES.register(stateRuntimeId, new BlockState(block, stateRuntimeId)); - - // Keeping this here since this is currently unchanged between versions - // It's possible to only have this store differences in names, but the key set of all Java names is used in sending command suggestions - BlockRegistries.JAVA_TO_BEDROCK_IDENTIFIERS.register(cleanJavaIdentifier.intern(), bedrockIdentifier.intern()); } } diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java b/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java index e4b7111b3..f618fde46 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java +++ b/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java @@ -52,6 +52,12 @@ public class BlockMappings implements DefinitionRegistry { GeyserBedrockBlock[] javaToBedrockBlocks; GeyserBedrockBlock[] javaToVanillaBedrockBlocks; + /** + * Java block ID -> Bedrock block ID (without minecraft:), IF they are different + * While Bedrock is progressing slowly through their flattening, some Bedrock identifiers may differ. + */ + Int2ObjectMap javaToBedrockIdentifiers; + Map stateDefinitionMap; GeyserBedrockBlock[] bedrockRuntimeMap; int[] remappedVanillaIds; diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index 768c94791..251aacba8 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -42,6 +42,7 @@ import org.geysermc.geyser.api.block.custom.CustomBlockData; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; +import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.CustomSkull; @@ -52,20 +53,12 @@ import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.util.InventoryUtils; -import org.geysermc.mcprotocollib.protocol.data.game.Identifier; import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.ModifierOperation; import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.AdventureModePredicate; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemAttributeModifiers; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.*; import java.text.DecimalFormat; -import java.util.ArrayList; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; public final class ItemTranslator { @@ -185,11 +178,11 @@ public final class ItemTranslator { translateCustomItem(components, builder, bedrockItem); if (components != null) { - // Translate the canDestroy and canPlaceOn Java NBT + // Translate the canDestroy and canPlaceOn Java components AdventureModePredicate canDestroy = components.get(DataComponentType.CAN_BREAK); AdventureModePredicate canPlaceOn = components.get(DataComponentType.CAN_PLACE_ON); - String[] canBreak = getCanModify(canDestroy); - String[] canPlace = getCanModify(canPlaceOn); + String[] canBreak = getCanModify(session, canDestroy); + String[] canPlace = getCanModify(session, canPlaceOn); if (canBreak != null) { builder.canBreak(canBreak); } @@ -325,27 +318,42 @@ public final class ItemTranslator { * @param canModifyJava the list of items in Java * @return the new list of items in Bedrock */ - // TODO this is now more complicated in 1.20.5. Yippee! - private static String @Nullable [] getCanModify(@Nullable AdventureModePredicate canModifyJava) { + // TODO blocks by tag, maybe NBT, maybe properties + // Blocks by tag will be easy enough, most likely, we just need to... save all block tags. + // Probably do that with Guava interning around sessions + private static String @Nullable [] getCanModify(GeyserSession session, @Nullable AdventureModePredicate canModifyJava) { if (canModifyJava == null) { return null; } List predicates = canModifyJava.getPredicates(); - if (predicates.size() > 0) { - String[] canModifyBedrock = new String[predicates.size()]; - for (int i = 0; i < canModifyBedrock.length; i++) { - // Get the Java identifier of the block that can be placed - String location = predicates.get(i).getLocation(); - if (location == null) { - canModifyBedrock[i] = ""; // So it'll serialize - continue; // ??? + if (!predicates.isEmpty()) { + List canModifyBedrock = new ArrayList<>(); // This used to be an array, but we need to be flexible with what blocks can be supported + for (int i = 0; i < predicates.size(); i++) { + HolderSet holderSet = predicates.get(i).getBlocks(); + if (holderSet == null) { + continue; + } + int[] holders = holderSet.getHolders(); + if (holders == null) { + continue; + } + // Holders is an int state of Java block IDs (not block states) + for (int blockId : holders) { + // Get the Bedrock identifier of the item + // This will unfortunately be limited - for example, beds and banners will be translated weirdly + Block block = BlockRegistries.JAVA_BLOCKS.get(blockId); + if (block == null) { + continue; + } + String identifier = session.getBlockMappings().getJavaToBedrockIdentifiers().get(block.javaId()); + if (identifier == null) { + canModifyBedrock.add(block.javaIdentifier().value()); + } else { + canModifyBedrock.add(identifier); + } } - String block = Identifier.formalize(location); - // Get the Bedrock identifier of the item and replace it. - // This will unfortunately be limited - for example, beds and banners will be translated weirdly - canModifyBedrock[i] = BlockRegistries.JAVA_TO_BEDROCK_IDENTIFIERS.getOrDefault(block, block).replace("minecraft:", ""); } - return canModifyBedrock; + return canModifyBedrock.toArray(new String[0]); } return null; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java index 706997402..d9f190197 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java @@ -59,6 +59,7 @@ import java.util.*; @Translator(packet = ClientboundCommandsPacket.class) public class JavaCommandsTranslator extends PacketTranslator { + private static final String[] ALL_BLOCK_NAMES = BlockRegistries.JAVA_BLOCKS.get().stream().map(block -> block.javaIdentifier().toString()).toArray(String[]::new); private static final String[] ALL_EFFECT_IDENTIFIERS = EntityUtils.getAllEffectIdentifiers(); private static final String[] ATTRIBUTES = AttributeType.Builtin.BUILTIN.values().stream().map(AttributeType::getIdentifier).toList().toArray(new String[0]); private static final String[] ENUM_BOOLEAN = {"true", "false"}; @@ -246,7 +247,7 @@ public class JavaCommandsTranslator extends PacketTranslator CommandParam.FILE_PATH; case BOOL -> ENUM_BOOLEAN; case OPERATION -> CommandParam.OPERATOR; // ">=", "==", etc - case BLOCK_STATE -> context.getBlockStates(); + case BLOCK_STATE -> ALL_BLOCK_NAMES; case ITEM_STACK -> context.getItemNames(); case COLOR -> VALID_COLORS; case SCOREBOARD_SLOT -> VALID_SCOREBOARD_SLOTS; @@ -286,7 +287,6 @@ public class JavaCommandsTranslator extends PacketTranslator Date: Mon, 20 May 2024 00:28:40 -0400 Subject: [PATCH 179/272] Add TrapDoorBlock --- .../geysermc/geyser/level/block/Blocks.java | 40 +++++++++---------- .../level/block/type/TrapDoorBlock.java | 32 +++++++++++++++ 2 files changed, 52 insertions(+), 20 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/type/TrapDoorBlock.java diff --git a/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java b/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java index 178887754..91f02d65e 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java @@ -655,55 +655,55 @@ public final class Blocks { public static final Block GREEN_STAINED_GLASS = register(new Block("green_stained_glass", builder().destroyTime(0.3f))); public static final Block RED_STAINED_GLASS = register(new Block("red_stained_glass", builder().destroyTime(0.3f))); public static final Block BLACK_STAINED_GLASS = register(new Block("black_stained_glass", builder().destroyTime(0.3f))); - public static final Block OAK_TRAPDOOR = register(new Block("oak_trapdoor", builder().destroyTime(3.0f) + public static final Block OAK_TRAPDOOR = register(new TrapDoorBlock("oak_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block SPRUCE_TRAPDOOR = register(new Block("spruce_trapdoor", builder().destroyTime(3.0f) + public static final Block SPRUCE_TRAPDOOR = register(new TrapDoorBlock("spruce_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block BIRCH_TRAPDOOR = register(new Block("birch_trapdoor", builder().destroyTime(3.0f) + public static final Block BIRCH_TRAPDOOR = register(new TrapDoorBlock("birch_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block JUNGLE_TRAPDOOR = register(new Block("jungle_trapdoor", builder().destroyTime(3.0f) + public static final Block JUNGLE_TRAPDOOR = register(new TrapDoorBlock("jungle_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block ACACIA_TRAPDOOR = register(new Block("acacia_trapdoor", builder().destroyTime(3.0f) + public static final Block ACACIA_TRAPDOOR = register(new TrapDoorBlock("acacia_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block CHERRY_TRAPDOOR = register(new Block("cherry_trapdoor", builder().destroyTime(3.0f) + public static final Block CHERRY_TRAPDOOR = register(new TrapDoorBlock("cherry_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block DARK_OAK_TRAPDOOR = register(new Block("dark_oak_trapdoor", builder().destroyTime(3.0f) + public static final Block DARK_OAK_TRAPDOOR = register(new TrapDoorBlock("dark_oak_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block MANGROVE_TRAPDOOR = register(new Block("mangrove_trapdoor", builder().destroyTime(3.0f) + public static final Block MANGROVE_TRAPDOOR = register(new TrapDoorBlock("mangrove_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block BAMBOO_TRAPDOOR = register(new Block("bamboo_trapdoor", builder().destroyTime(3.0f) + public static final Block BAMBOO_TRAPDOOR = register(new TrapDoorBlock("bamboo_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) @@ -1196,7 +1196,7 @@ public final class Blocks { public static final Block LIGHT = register(new Block("light", builder().destroyTime(-1.0f) .intState(LEVEL, 0, 15) .booleanState(WATERLOGGED))); - public static final Block IRON_TRAPDOOR = register(new Block("iron_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(5.0f) + public static final Block IRON_TRAPDOOR = register(new TrapDoorBlock("iron_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(5.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) @@ -2102,13 +2102,13 @@ public final class Blocks { .booleanState(SOUTH) .booleanState(WATERLOGGED) .booleanState(WEST))); - public static final Block CRIMSON_TRAPDOOR = register(new Block("crimson_trapdoor", builder().destroyTime(3.0f) + public static final Block CRIMSON_TRAPDOOR = register(new TrapDoorBlock("crimson_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block WARPED_TRAPDOOR = register(new Block("warped_trapdoor", builder().destroyTime(3.0f) + public static final Block WARPED_TRAPDOOR = register(new TrapDoorBlock("warped_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) @@ -2583,49 +2583,49 @@ public final class Blocks { .enumState(DOOR_HINGE, "left", "right") .booleanState(OPEN) .booleanState(POWERED))); - public static final Block COPPER_TRAPDOOR = register(new Block("copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) + public static final Block COPPER_TRAPDOOR = register(new TrapDoorBlock("copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block EXPOSED_COPPER_TRAPDOOR = register(new Block("exposed_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) + public static final Block EXPOSED_COPPER_TRAPDOOR = register(new TrapDoorBlock("exposed_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block OXIDIZED_COPPER_TRAPDOOR = register(new Block("oxidized_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) + public static final Block OXIDIZED_COPPER_TRAPDOOR = register(new TrapDoorBlock("oxidized_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block WEATHERED_COPPER_TRAPDOOR = register(new Block("weathered_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) + public static final Block WEATHERED_COPPER_TRAPDOOR = register(new TrapDoorBlock("weathered_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block WAXED_COPPER_TRAPDOOR = register(new Block("waxed_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) + public static final Block WAXED_COPPER_TRAPDOOR = register(new TrapDoorBlock("waxed_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block WAXED_EXPOSED_COPPER_TRAPDOOR = register(new Block("waxed_exposed_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) + public static final Block WAXED_EXPOSED_COPPER_TRAPDOOR = register(new TrapDoorBlock("waxed_exposed_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block WAXED_OXIDIZED_COPPER_TRAPDOOR = register(new Block("waxed_oxidized_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) + public static final Block WAXED_OXIDIZED_COPPER_TRAPDOOR = register(new TrapDoorBlock("waxed_oxidized_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); - public static final Block WAXED_WEATHERED_COPPER_TRAPDOOR = register(new Block("waxed_weathered_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) + public static final Block WAXED_WEATHERED_COPPER_TRAPDOOR = register(new TrapDoorBlock("waxed_weathered_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HALF, "top", "bottom") .booleanState(OPEN) diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/TrapDoorBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/TrapDoorBlock.java new file mode 100644 index 000000000..a94414ac2 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/TrapDoorBlock.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.type; + +public class TrapDoorBlock extends Block { + public TrapDoorBlock(String javaIdentifier, Builder builder) { + super(javaIdentifier, builder); + } +} From a780eeaae8d7a13c2c198a1880c14f0a704f5fb7 Mon Sep 17 00:00:00 2001 From: gecko10000 <60494179+gecko10000@users.noreply.github.com> Date: Mon, 20 May 2024 10:52:41 -0700 Subject: [PATCH 180/272] Open advancement tab regardless of currently open tab (#4665) --- .../geyser/session/cache/AdvancementsCache.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java index da3c83ed4..6769b4330 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java @@ -91,15 +91,13 @@ public class AdvancementsCache { builder.validResultHandler((response) -> { String id = rootAdvancementIds.get(response.clickedButtonId()); if (!id.equals("")) { - if (id.equals(currentAdvancementCategoryId)) { - // The server thinks we are already on this tab - buildAndShowListForm(); - } else { - // Send a packet indicating that we intend to open this particular advancement window + if (!id.equals(currentAdvancementCategoryId)) { + // Send a packet indicating that we are opening this particular advancement window ServerboundSeenAdvancementsPacket packet = new ServerboundSeenAdvancementsPacket(id); session.sendDownstreamGamePacket(packet); - // Wait for a response there } + currentAdvancementCategoryId = id; + buildAndShowListForm(); } }); From db166ad8dec5cc23998eeb2480629c8ca5884a97 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 20 May 2024 21:26:01 -0400 Subject: [PATCH 181/272] Small optimizations and BlockStateValues reduction --- .../spigot/world/GeyserPistonListener.java | 3 +- .../manager/GeyserSpigotWorldManager.java | 3 +- .../erosion/GeyserboundPacketHandlerImpl.java | 3 +- .../geyser/level/block/BlockStateValues.java | 45 ++------------- .../geysermc/geyser/level/block/Blocks.java | 5 +- .../level/block/property/FrontAndTop.java | 55 +++++++++++++++++++ .../level/block/property/Properties.java | 2 +- .../geyser/registry/ListRegistry.java | 18 ++++++ .../loader/CollisionRegistryLoader.java | 3 +- .../populator/BlockRegistryPopulator.java | 11 +--- .../JigsawBlockBlockEntityTranslator.java | 4 +- .../java/level/JavaBlockEventTranslator.java | 10 ++-- 12 files changed, 97 insertions(+), 65 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/property/FrontAndTop.java diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserPistonListener.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserPistonListener.java index 2a6dc7a81..963f5bac3 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserPistonListener.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserPistonListener.java @@ -41,6 +41,7 @@ import org.bukkit.event.block.BlockPistonRetractEvent; import org.cloudburstmc.math.vector.Vector3i; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.level.physics.Direction; import org.geysermc.geyser.platform.spigot.world.manager.GeyserSpigotWorldManager; @@ -120,7 +121,7 @@ public class GeyserPistonListener implements Listener { int pistonBlockId = worldManager.getBlockNetworkId(event.getBlock()); // event.getDirection() is unreliable - Direction orientation = BlockStateValues.getPistonOrientation(pistonBlockId); + Direction orientation = BlockState.of(pistonBlockId).getValue(Properties.FACING); session.executeInEventLoop(() -> { PistonCache pistonCache = session.getPistonCache(); diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java index a04c60126..f45b68675 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java @@ -42,7 +42,6 @@ import org.geysermc.erosion.bukkit.SchedulerUtils; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.level.GameRule; import org.geysermc.geyser.level.WorldManager; -import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.BlockEntityUtils; @@ -88,7 +87,7 @@ public class GeyserSpigotWorldManager extends WorldManager { Bukkit.getRegionScheduler().execute(this.plugin, block.getLocation(), () -> blockData.complete(block.getBlockData().getAsString())); return BlockRegistries.JAVA_IDENTIFIER_TO_ID.getOrDefault(blockData.join(), org.geysermc.geyser.level.block.type.Block.JAVA_AIR_ID); } - return BlockRegistries.JAVA_IDENTIFIER_TO_ID.getOrDefault(block.getBlockData().getAsString(), org.geysermc.geyser.level.block.type.Block.JAVA_AIR_ID); + return BlockRegistries.JAVA_IDENTIFIER_TO_ID.getOrDefault(block.getBlockData().getAsString(), org.geysermc.geyser.level.block.type.Block.JAVA_AIR_ID); // TODO could just make this a BlockState lookup? } @Override diff --git a/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java b/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java index 9894a4ba2..c8cbe384b 100644 --- a/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java +++ b/core/src/main/java/org/geysermc/geyser/erosion/GeyserboundPacketHandlerImpl.java @@ -44,6 +44,7 @@ import org.geysermc.erosion.packet.backendbound.BackendboundInitializePacket; import org.geysermc.erosion.packet.backendbound.BackendboundPacket; import org.geysermc.erosion.packet.geyserbound.*; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.level.physics.Direction; @@ -148,7 +149,7 @@ public final class GeyserboundPacketHandlerImpl extends AbstractGeyserboundPacke @Override public void handlePistonEvent(GeyserboundPistonEventPacket packet) { - Direction orientation = BlockStateValues.getPistonOrientation(packet.getBlockId()); + Direction orientation = BlockState.of(packet.getBlockId()).getValue(Properties.FACING); Vector3i position = packet.getPos(); boolean isExtend = packet.isExtend(); diff --git a/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java b/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java index 8bc9cf1e2..d52c46e33 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java @@ -25,7 +25,10 @@ package org.geysermc.geyser.level.block; -import it.unimi.dsi.fastutil.ints.*; +import it.unimi.dsi.fastutil.ints.Int2IntMap; +import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; +import it.unimi.dsi.fastutil.ints.IntOpenHashSet; +import it.unimi.dsi.fastutil.ints.IntSet; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import org.geysermc.geyser.level.block.property.Properties; @@ -36,16 +39,11 @@ import org.geysermc.geyser.level.physics.Direction; import org.geysermc.geyser.level.physics.PistonBehavior; import org.geysermc.geyser.registry.BlockRegistries; -import java.util.Locale; - /** * Used for block entities if the Java block state contains Bedrock block information. */ public final class BlockStateValues { - private static final IntSet HORIZONTAL_FACING_JIGSAWS = new IntOpenHashSet(); - private static final IntSet STICKY_PISTONS = new IntOpenHashSet(); private static final Object2IntMap PISTON_HEADS = new Object2IntOpenHashMap<>(); - private static final Int2ObjectMap PISTON_ORIENTATION = new Int2ObjectOpenHashMap<>(); private static final IntSet ALL_PISTON_HEADS = new IntOpenHashSet(); private static final Int2IntMap WATER_LEVEL = new Int2IntOpenHashMap(); @@ -61,10 +59,6 @@ public final class BlockStateValues { */ public static void storeBlockStateValues(String javaId, int javaBlockState) { if (javaId.contains("piston[")) { // minecraft:moving_piston, minecraft:sticky_piston, minecraft:piston - if (javaId.contains("sticky")) { - STICKY_PISTONS.add(javaBlockState); - } - PISTON_ORIENTATION.put(javaBlockState, getBlockDirection(javaId)); return; } else if (javaId.startsWith("minecraft:piston_head")) { ALL_PISTON_HEADS.add(javaBlockState); @@ -78,27 +72,7 @@ public final class BlockStateValues { String strLevel = javaId.substring(javaId.lastIndexOf("level=") + 6, javaId.length() - 1); int level = Integer.parseInt(strLevel); WATER_LEVEL.put(javaBlockState, level); - return; } - - if (javaId.startsWith("minecraft:jigsaw[orientation=")) { - String blockStateData = javaId.substring(javaId.indexOf("orientation=") + "orientation=".length(), javaId.lastIndexOf('_')); - Direction direction = Direction.valueOf(blockStateData.toUpperCase(Locale.ROOT)); - if (direction.isHorizontal()) { - HORIZONTAL_FACING_JIGSAWS.add(javaBlockState); - } - } - } - - /** - * @return a set of all forward-facing jigsaws, to use as a fallback if NBT is missing. - */ - public static IntSet getHorizontalFacingJigsaws() { - return HORIZONTAL_FACING_JIGSAWS; - } - - public static boolean isStickyPiston(int blockState) { - return STICKY_PISTONS.contains(blockState); } public static boolean isPistonHead(int state) { @@ -116,17 +90,6 @@ public final class BlockStateValues { return PISTON_HEADS.getOrDefault(direction, Block.JAVA_AIR_ID); } - /** - * This is used in GeyserPistonEvents.java and accepts minecraft:piston, - * minecraft:sticky_piston, and minecraft:moving_piston. - * - * @param state The block state of the piston base - * @return The direction in which the piston faces - */ - public static Direction getPistonOrientation(int state) { - return PISTON_ORIENTATION.get(state); - } - /** * Checks if a block sticks to other blocks * (Slime and honey blocks) diff --git a/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java b/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java index 91f02d65e..283ca2503 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java @@ -27,6 +27,7 @@ package org.geysermc.geyser.level.block; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.level.block.property.ChestType; +import org.geysermc.geyser.level.block.property.FrontAndTop; import org.geysermc.geyser.level.block.type.*; import org.geysermc.geyser.level.physics.Axis; import org.geysermc.geyser.level.physics.Direction; @@ -2169,7 +2170,7 @@ public final class Blocks { public static final Block STRUCTURE_BLOCK = register(new Block("structure_block", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(-1.0f) .enumState(STRUCTUREBLOCK_MODE, "save", "load", "corner", "data"))); public static final Block JIGSAW = register(new Block("jigsaw", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(-1.0f) - .enumState(ORIENTATION, "down_east", "down_north", "down_south", "down_west", "up_east", "up_north", "up_south", "up_west", "west_up", "east_up", "north_up", "south_up"))); + .enumState(ORIENTATION, FrontAndTop.VALUES))); public static final Block COMPOSTER = register(new Block("composter", builder().destroyTime(0.6f) .intState(LEVEL_COMPOSTER, 0, 8))); public static final Block TARGET = register(new Block("target", builder().destroyTime(0.5f) @@ -2799,7 +2800,7 @@ public final class Blocks { .booleanState(WATERLOGGED))); public static final Block CRAFTER = register(new Block("crafter", builder().setBlockEntity().destroyTime(1.5f) .booleanState(CRAFTING) - .enumState(ORIENTATION, "down_east", "down_north", "down_south", "down_west", "up_east", "up_north", "up_south", "up_west", "west_up", "east_up", "north_up", "south_up") + .enumState(ORIENTATION, FrontAndTop.VALUES) .booleanState(TRIGGERED))); public static final Block TRIAL_SPAWNER = register(new Block("trial_spawner", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(50.0f) .booleanState(OMINOUS) diff --git a/core/src/main/java/org/geysermc/geyser/level/block/property/FrontAndTop.java b/core/src/main/java/org/geysermc/geyser/level/block/property/FrontAndTop.java new file mode 100644 index 000000000..e674ac424 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/property/FrontAndTop.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.property; + +import org.geysermc.geyser.level.physics.Direction; + +public enum FrontAndTop { + DOWN_EAST(Direction.DOWN), + DOWN_NORTH(Direction.DOWN), + DOWN_SOUTH(Direction.DOWN), + DOWN_WEST(Direction.DOWN), + UP_EAST(Direction.UP), + UP_NORTH(Direction.UP), + UP_SOUTH(Direction.UP), + UP_WEST(Direction.UP), + WEST_UP(Direction.WEST), + EAST_UP(Direction.EAST), + NORTH_UP(Direction.NORTH), + SOUTH_UP(Direction.SOUTH); + + private final boolean horizontal; + + FrontAndTop(Direction front) { + this.horizontal = front.isHorizontal(); + } + + public boolean isHorizontal() { + return horizontal; + } + + public static final FrontAndTop[] VALUES = values(); +} diff --git a/core/src/main/java/org/geysermc/geyser/level/block/property/Properties.java b/core/src/main/java/org/geysermc/geyser/level/block/property/Properties.java index 339d82f96..7df09003d 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/property/Properties.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/property/Properties.java @@ -74,7 +74,7 @@ public final class Properties { public static final Property FACING_HOPPER = Property.create("facing"); public static final Property HORIZONTAL_FACING = Property.create("facing"); public static final Property FLOWER_AMOUNT = Property.create("flower_amount"); - public static final Property ORIENTATION = Property.create("orientation"); + public static final Property ORIENTATION = Property.create("orientation"); public static final Property ATTACH_FACE = Property.create("face"); public static final Property BELL_ATTACHMENT = Property.create("attachment"); public static final Property EAST_WALL = Property.create("east"); diff --git a/core/src/main/java/org/geysermc/geyser/registry/ListRegistry.java b/core/src/main/java/org/geysermc/geyser/registry/ListRegistry.java index d13c47ba8..34a78c370 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/ListRegistry.java +++ b/core/src/main/java/org/geysermc/geyser/registry/ListRegistry.java @@ -28,10 +28,13 @@ package org.geysermc.geyser.registry; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.registry.loader.RegistryLoader; +import java.util.ArrayList; import java.util.List; import java.util.function.Supplier; public class ListRegistry extends Registry> { + private boolean frozen = false; + /** * Creates a new instance of this class with the given input and * {@link RegistryLoader}. The input specified is what the registry @@ -85,9 +88,24 @@ public class ListRegistry extends Registry> { * @return a new value into this registry with the given index. */ public M register(int index, M value) { + if (this.frozen) { + throw new IllegalStateException("Registry should not be modified after frozen!"); + } return this.mappings.set(index, value); } + /** + * Mark this registry as unsuitable for new additions. The backing list will then be optimized for storage. + */ + public void freeze() { + if (!this.frozen) { + this.frozen = true; + if (this.mappings instanceof ArrayList arrayList) { + arrayList.trimToSize(); + } + } + } + /** * Creates a new array registry with the given {@link RegistryLoader}. The * input type is not specified here, meaning the loader return type is either diff --git a/core/src/main/java/org/geysermc/geyser/registry/loader/CollisionRegistryLoader.java b/core/src/main/java/org/geysermc/geyser/registry/loader/CollisionRegistryLoader.java index 2cd7f82d6..bd98ae0a5 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/loader/CollisionRegistryLoader.java +++ b/core/src/main/java/org/geysermc/geyser/registry/loader/CollisionRegistryLoader.java @@ -77,7 +77,7 @@ public class CollisionRegistryLoader extends MultiResourceRegistryLoader blockStates = BlockRegistries.BLOCK_STATES.get(); - List collisions = new ObjectArrayList<>(blockStates.size()); + var collisions = new ObjectArrayList(blockStates.size()); // Map of unique collisions to its instance Map collisionInstances = new Object2ObjectOpenHashMap<>(); @@ -102,6 +102,7 @@ public class CollisionRegistryLoader extends MultiResourceRegistryLoader { - int blockId = session.getGeyser().getWorldManager().getBlockAt(session, position); - boolean sticky = BlockStateValues.isStickyPiston(blockId); + BlockState state = session.getGeyser().getWorldManager().blockAt(session, position); + boolean sticky = state.is(Blocks.STICKY_PISTON); boolean extended = action != PistonValueType.PUSHING; return new PistonBlockEntity(session, pos, direction, sticky, extended); }); From 0094fa1418e313361b94bc2e13010a9a84f20ab7 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 21 May 2024 14:25:57 -0400 Subject: [PATCH 182/272] BlockState values can now be switched at runtime E.G. Blocks.PISTON_HEAD.defaultBlockState().withValue(FACING, Direction.SOUTH) Some of the inspiration may be thanks to FerriteCore, at least with the shared property keys idea, so thank you to them. --- .../entity/type/FurnaceMinecartEntity.java | 7 +- .../entity/type/SpawnerMinecartEntity.java | 4 +- .../holder/BlockInventoryHolder.java | 33 +- .../geyser/level/block/BlockStateValues.java | 75 +- .../geysermc/geyser/level/block/Blocks.java | 1052 ++++++++--------- .../block/property/BasicEnumProperty.java | 63 + .../level/block/property/BooleanProperty.java | 46 + .../level/block/property/EnumProperty.java | 59 + .../level/block/property/IntegerProperty.java | 59 + .../level/block/property/Properties.java | 228 ++-- .../geyser/level/block/property/Property.java | 12 +- .../geyser/level/block/type/Block.java | 50 +- .../geyser/level/block/type/BlockState.java | 115 +- .../geyser/level/block/type/FurnaceBlock.java | 21 +- .../geyser/level/block/type/HoneyBlock.java | 13 - .../geyser/level/block/type/SpawnerBlock.java | 13 - .../geyser/level/block/type/WaterBlock.java | 9 - .../level/physics/CollisionManager.java | 6 +- .../populator/BlockRegistryPopulator.java | 13 - .../geyser/registry/type/BlockMappings.java | 4 + .../AbstractBlockInventoryTranslator.java | 15 +- .../inventory/AnvilInventoryTranslator.java | 2 +- .../inventory/BeaconInventoryTranslator.java | 11 +- .../inventory/BrewingInventoryTranslator.java | 7 +- .../CartographyInventoryTranslator.java | 3 +- .../inventory/CrafterInventoryTranslator.java | 3 +- .../CraftingInventoryTranslator.java | 3 +- .../EnchantingInventoryTranslator.java | 3 +- .../Generic3X3InventoryTranslator.java | 2 +- .../GrindstoneInventoryTranslator.java | 3 +- .../inventory/HopperInventoryTranslator.java | 3 +- .../inventory/LecternInventoryTranslator.java | 3 +- .../inventory/LoomInventoryTranslator.java | 3 +- .../inventory/OldSmithingTableTranslator.java | 3 +- .../inventory/ShulkerInventoryTranslator.java | 10 +- .../SmithingInventoryTranslator.java | 3 +- .../StonecutterInventoryTranslator.java | 3 +- .../chest/DoubleChestInventoryTranslator.java | 12 +- .../chest/SingleChestInventoryTranslator.java | 11 +- .../AbstractFurnaceInventoryTranslator.java | 6 +- .../BlastFurnaceInventoryTranslator.java | 3 +- .../furnace/FurnaceInventoryTranslator.java | 3 +- .../furnace/SmokerInventoryTranslator.java | 3 +- .../level/block/entity/PistonBlockEntity.java | 41 +- ...BedrockInventoryTransactionTranslator.java | 8 +- .../protocol/java/JavaCommandsTranslator.java | 9 +- gradle/libs.versions.toml | 3 +- 47 files changed, 1160 insertions(+), 901 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/property/BasicEnumProperty.java create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/property/BooleanProperty.java create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/property/EnumProperty.java create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/property/IntegerProperty.java diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/FurnaceMinecartEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/FurnaceMinecartEntity.java index 0fc5627ed..e33e6d7b6 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/FurnaceMinecartEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/FurnaceMinecartEntity.java @@ -28,7 +28,9 @@ package org.geysermc.geyser.entity.type; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.level.block.type.FurnaceBlock; +import org.geysermc.geyser.level.block.Blocks; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; @@ -51,7 +53,8 @@ public class FurnaceMinecartEntity extends DefaultBlockMinecartEntity { @Override public void updateDefaultBlockMetadata() { - dirtyMetadata.put(EntityDataTypes.DISPLAY_BLOCK_STATE, session.getBlockMappings().getBedrockBlock(FurnaceBlock.state(hasFuel))); + BlockState furnace = Blocks.FURNACE.defaultBlockState().withValue(Properties.LIT, hasFuel); + dirtyMetadata.put(EntityDataTypes.DISPLAY_BLOCK_STATE, session.getBlockMappings().getBedrockBlock(furnace)); dirtyMetadata.put(EntityDataTypes.DISPLAY_OFFSET, 6); } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/SpawnerMinecartEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/SpawnerMinecartEntity.java index 65dfb800b..4d69c8a1e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/SpawnerMinecartEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/SpawnerMinecartEntity.java @@ -28,7 +28,7 @@ package org.geysermc.geyser.entity.type; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.level.block.type.SpawnerBlock; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.session.GeyserSession; import java.util.UUID; @@ -41,7 +41,7 @@ public class SpawnerMinecartEntity extends DefaultBlockMinecartEntity { @Override public void updateDefaultBlockMetadata() { - dirtyMetadata.put(EntityDataTypes.DISPLAY_BLOCK_STATE, session.getBlockMappings().getBedrockBlock(SpawnerBlock.state())); + dirtyMetadata.put(EntityDataTypes.DISPLAY_BLOCK_STATE, session.getBlockMappings().getBedrockBlock(Blocks.SPAWNER.defaultBlockState())); dirtyMetadata.put(EntityDataTypes.DISPLAY_OFFSET, 6); } } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java b/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java index 0a51d43ef..9c8e5de15 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java @@ -41,7 +41,6 @@ import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.inventory.InventoryTranslator; -import org.geysermc.geyser.util.BlockUtils; import org.geysermc.geyser.util.InventoryUtils; import java.util.Collections; @@ -56,22 +55,24 @@ public class BlockInventoryHolder extends InventoryHolder { /** * The default Java block ID to translate as a fake block */ - private final int defaultJavaBlockState; + private final BlockState defaultJavaBlockState; private final ContainerType containerType; - private final Set validBlocks; + private final Set validBlocks; - public BlockInventoryHolder(String javaBlockIdentifier, ContainerType containerType, Block... validBlocks) { - this.defaultJavaBlockState = BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getInt(javaBlockIdentifier); + public BlockInventoryHolder(Block defaultJavaBlock, ContainerType containerType, Block... validBlocks) { + this(defaultJavaBlock.defaultBlockState(), containerType, validBlocks); + } + + public BlockInventoryHolder(BlockState defaultJavaBlockState, ContainerType containerType, Block... validBlocks) { + this.defaultJavaBlockState = defaultJavaBlockState; this.containerType = containerType; if (validBlocks != null) { - Set validBlocksTemp = new HashSet<>(validBlocks.length + 1); - for (Block block : validBlocks) { - validBlocksTemp.add(block.javaIdentifier().toString()); - } - validBlocksTemp.add(BlockUtils.getCleanIdentifier(javaBlockIdentifier)); + Set validBlocksTemp = new HashSet<>(validBlocks.length + 1); + Collections.addAll(validBlocksTemp, validBlocks); + validBlocksTemp.add(defaultJavaBlockState.block()); this.validBlocks = Set.copyOf(validBlocksTemp); } else { - this.validBlocks = Collections.singleton(BlockUtils.getCleanIdentifier(javaBlockIdentifier)); + this.validBlocks = Collections.singleton(defaultJavaBlockState.block()); } } @@ -85,9 +86,7 @@ public class BlockInventoryHolder extends InventoryHolder { // and the bedrock block is vanilla BlockState state = session.getGeyser().getWorldManager().blockAt(session, session.getLastInteractionBlockPosition()); if (!BlockRegistries.CUSTOM_BLOCK_STATE_OVERRIDES.get().containsKey(state.javaId())) { - // TODO TODO TODO - String[] javaBlockString = state.toString().split("\\["); - if (isValidBlock(javaBlockString)) { + if (isValidBlock(state)) { // We can safely use this block inventory.setHolderPosition(session.getLastInteractionBlockPosition()); ((Container) inventory).setUsingRealBlock(true, state.block()); @@ -111,7 +110,7 @@ public class BlockInventoryHolder extends InventoryHolder { session.sendUpstreamPacket(blockPacket); inventory.setHolderPosition(position); - setCustomName(session, position, inventory, BlockState.of(defaultJavaBlockState)); + setCustomName(session, position, inventory, defaultJavaBlockState); return true; } @@ -129,8 +128,8 @@ public class BlockInventoryHolder extends InventoryHolder { /** * @return true if this Java block ID can be used for player inventory. */ - protected boolean isValidBlock(String[] javaBlockString) { - return this.validBlocks.contains(javaBlockString[0]); + protected boolean isValidBlock(BlockState blockState) { + return this.validBlocks.contains(blockState.block()); } protected void setCustomName(GeyserSession session, Vector3i position, Inventory inventory, BlockState javaBlockState) { diff --git a/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java b/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java index d52c46e33..01e95fc7a 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java @@ -25,17 +25,10 @@ package org.geysermc.geyser.level.block; -import it.unimi.dsi.fastutil.ints.Int2IntMap; -import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; -import it.unimi.dsi.fastutil.ints.IntOpenHashSet; -import it.unimi.dsi.fastutil.ints.IntSet; -import it.unimi.dsi.fastutil.objects.Object2IntMap; -import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.level.block.type.PistonBlock; -import org.geysermc.geyser.level.physics.Direction; import org.geysermc.geyser.level.physics.PistonBehavior; import org.geysermc.geyser.registry.BlockRegistries; @@ -43,53 +36,8 @@ import org.geysermc.geyser.registry.BlockRegistries; * Used for block entities if the Java block state contains Bedrock block information. */ public final class BlockStateValues { - private static final Object2IntMap PISTON_HEADS = new Object2IntOpenHashMap<>(); - private static final IntSet ALL_PISTON_HEADS = new IntOpenHashSet(); - private static final Int2IntMap WATER_LEVEL = new Int2IntOpenHashMap(); - - public static int JAVA_WATER_ID; - public static final int NUM_WATER_LEVELS = 9; - /** - * Determines if the block state contains Bedrock block information - * - * @param javaId The Java Identifier of the block - * @param javaBlockState the Java Block State of the block - */ - public static void storeBlockStateValues(String javaId, int javaBlockState) { - if (javaId.contains("piston[")) { // minecraft:moving_piston, minecraft:sticky_piston, minecraft:piston - return; - } else if (javaId.startsWith("minecraft:piston_head")) { - ALL_PISTON_HEADS.add(javaBlockState); - if (javaId.contains("short=false")) { - PISTON_HEADS.put(getBlockDirection(javaId), javaBlockState); - } - return; - } - - if (javaId.startsWith("minecraft:water") && !javaId.contains("cauldron")) { - String strLevel = javaId.substring(javaId.lastIndexOf("level=") + 6, javaId.length() - 1); - int level = Integer.parseInt(strLevel); - WATER_LEVEL.put(javaBlockState, level); - } - } - - public static boolean isPistonHead(int state) { - return ALL_PISTON_HEADS.contains(state); - } - - /** - * Get the Java Block State for a piston head for a specific direction - * This is used in PistonBlockEntity to get the BlockCollision for the piston head. - * - * @param direction Direction the piston head points in - * @return Block state for the piston head - */ - public static int getPistonHead(Direction direction) { - return PISTON_HEADS.getOrDefault(direction, Block.JAVA_AIR_ID); - } - /** * Checks if a block sticks to other blocks * (Slime and honey blocks) @@ -158,7 +106,11 @@ public final class BlockStateValues { * @return The water level or -1 if the block isn't water */ public static int getWaterLevel(int state) { - return WATER_LEVEL.getOrDefault(state, -1); + BlockState blockState = BlockState.of(state); + if (!blockState.is(Blocks.WATER)) { + return -1; + } + return blockState.getValue(Properties.LEVEL); } /** @@ -206,23 +158,6 @@ public final class BlockStateValues { return 0.6f; } - private static Direction getBlockDirection(String javaId) { - if (javaId.contains("down")) { - return Direction.DOWN; - } else if (javaId.contains("up")) { - return Direction.UP; - } else if (javaId.contains("south")) { - return Direction.SOUTH; - } else if (javaId.contains("west")) { - return Direction.WEST; - } else if (javaId.contains("north")) { - return Direction.NORTH; - } else if (javaId.contains("east")) { - return Direction.EAST; - } - throw new IllegalStateException(); - } - private BlockStateValues() { } } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java b/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java index 283ca2503..fa605c079 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java @@ -65,36 +65,36 @@ public final class Blocks { public static final Block BAMBOO_PLANKS = register(new Block("bamboo_planks", builder().destroyTime(2.0f))); public static final Block BAMBOO_MOSAIC = register(new Block("bamboo_mosaic", builder().destroyTime(2.0f))); public static final Block OAK_SAPLING = register(new Block("oak_sapling", builder().pushReaction(PistonBehavior.DESTROY) - .intState(STAGE, 0, 1))); + .intState(STAGE))); public static final Block SPRUCE_SAPLING = register(new Block("spruce_sapling", builder().pushReaction(PistonBehavior.DESTROY) - .intState(STAGE, 0, 1))); + .intState(STAGE))); public static final Block BIRCH_SAPLING = register(new Block("birch_sapling", builder().pushReaction(PistonBehavior.DESTROY) - .intState(STAGE, 0, 1))); + .intState(STAGE))); public static final Block JUNGLE_SAPLING = register(new Block("jungle_sapling", builder().pushReaction(PistonBehavior.DESTROY) - .intState(STAGE, 0, 1))); + .intState(STAGE))); public static final Block ACACIA_SAPLING = register(new Block("acacia_sapling", builder().pushReaction(PistonBehavior.DESTROY) - .intState(STAGE, 0, 1))); + .intState(STAGE))); public static final Block CHERRY_SAPLING = register(new Block("cherry_sapling", builder().pushReaction(PistonBehavior.DESTROY) - .intState(STAGE, 0, 1))); + .intState(STAGE))); public static final Block DARK_OAK_SAPLING = register(new Block("dark_oak_sapling", builder().pushReaction(PistonBehavior.DESTROY) - .intState(STAGE, 0, 1))); + .intState(STAGE))); public static final Block MANGROVE_PROPAGULE = register(new Block("mangrove_propagule", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_4, 0, 4) + .intState(AGE_4) .booleanState(HANGING) - .intState(STAGE, 0, 1) + .intState(STAGE) .booleanState(WATERLOGGED))); public static final Block BEDROCK = register(new Block("bedrock", builder().destroyTime(-1.0f))); public static final Block WATER = register(new WaterBlock("water", builder().destroyTime(100.0f).pushReaction(PistonBehavior.DESTROY) - .intState(LEVEL, 0, 15))); + .intState(LEVEL))); public static final Block LAVA = register(new Block("lava", builder().destroyTime(100.0f).pushReaction(PistonBehavior.DESTROY) - .intState(LEVEL, 0, 15))); + .intState(LEVEL))); public static final Block SAND = register(new Block("sand", builder().destroyTime(0.5f))); public static final Block SUSPICIOUS_SAND = register(new Block("suspicious_sand", builder().setBlockEntity().destroyTime(0.25f).pushReaction(PistonBehavior.DESTROY) - .intState(DUSTED, 0, 3))); + .intState(DUSTED))); public static final Block RED_SAND = register(new Block("red_sand", builder().destroyTime(0.5f))); public static final Block GRAVEL = register(new Block("gravel", builder().destroyTime(0.6f))); public static final Block SUSPICIOUS_GRAVEL = register(new Block("suspicious_gravel", builder().setBlockEntity().destroyTime(0.25f).pushReaction(PistonBehavior.DESTROY) - .intState(DUSTED, 0, 3))); + .intState(DUSTED))); public static final Block GOLD_ORE = register(new Block("gold_ore", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); public static final Block DEEPSLATE_GOLD_ORE = register(new Block("deepslate_gold_ore", builder().requiresCorrectToolForDrops().destroyTime(4.5f))); public static final Block IRON_ORE = register(new Block("iron_ore", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); @@ -175,43 +175,43 @@ public final class Blocks { public static final Block STRIPPED_MANGROVE_WOOD = register(new Block("stripped_mangrove_wood", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); public static final Block OAK_LEAVES = register(new Block("oak_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) - .intState(DISTANCE, 1, 7) + .intState(DISTANCE) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); public static final Block SPRUCE_LEAVES = register(new Block("spruce_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) - .intState(DISTANCE, 1, 7) + .intState(DISTANCE) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); public static final Block BIRCH_LEAVES = register(new Block("birch_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) - .intState(DISTANCE, 1, 7) + .intState(DISTANCE) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); public static final Block JUNGLE_LEAVES = register(new Block("jungle_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) - .intState(DISTANCE, 1, 7) + .intState(DISTANCE) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); public static final Block ACACIA_LEAVES = register(new Block("acacia_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) - .intState(DISTANCE, 1, 7) + .intState(DISTANCE) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); public static final Block CHERRY_LEAVES = register(new Block("cherry_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) - .intState(DISTANCE, 1, 7) + .intState(DISTANCE) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); public static final Block DARK_OAK_LEAVES = register(new Block("dark_oak_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) - .intState(DISTANCE, 1, 7) + .intState(DISTANCE) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); public static final Block MANGROVE_LEAVES = register(new Block("mangrove_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) - .intState(DISTANCE, 1, 7) + .intState(DISTANCE) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); public static final Block AZALEA_LEAVES = register(new Block("azalea_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) - .intState(DISTANCE, 1, 7) + .intState(DISTANCE) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); public static final Block FLOWERING_AZALEA_LEAVES = register(new Block("flowering_azalea_leaves", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) - .intState(DISTANCE, 1, 7) + .intState(DISTANCE) .booleanState(PERSISTENT) .booleanState(WATERLOGGED))); public static final Block SPONGE = register(new Block("sponge", builder().destroyTime(0.6f))); @@ -227,80 +227,80 @@ public final class Blocks { public static final Block CHISELED_SANDSTONE = register(new Block("chiseled_sandstone", builder().requiresCorrectToolForDrops().destroyTime(0.8f))); public static final Block CUT_SANDSTONE = register(new Block("cut_sandstone", builder().requiresCorrectToolForDrops().destroyTime(0.8f))); public static final Block NOTE_BLOCK = register(new Block("note_block", builder().destroyTime(0.8f) - .enumState(NOTEBLOCK_INSTRUMENT, "harp", "basedrum", "snare", "hat", "bass", "flute", "bell", "guitar", "chime", "xylophone", "iron_xylophone", "cow_bell", "didgeridoo", "bit", "banjo", "pling", "zombie", "skeleton", "creeper", "dragon", "wither_skeleton", "piglin", "custom_head") - .intState(NOTE, 0, 24) + .enumState(NOTEBLOCK_INSTRUMENT) + .intState(NOTE) .booleanState(POWERED))); public static final Block WHITE_BED = register(new BedBlock("white_bed", 0, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block ORANGE_BED = register(new BedBlock("orange_bed", 1, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block MAGENTA_BED = register(new BedBlock("magenta_bed", 2, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block LIGHT_BLUE_BED = register(new BedBlock("light_blue_bed", 3, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block YELLOW_BED = register(new BedBlock("yellow_bed", 4, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block LIME_BED = register(new BedBlock("lime_bed", 5, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block PINK_BED = register(new BedBlock("pink_bed", 6, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block GRAY_BED = register(new BedBlock("gray_bed", 7, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block LIGHT_GRAY_BED = register(new BedBlock("light_gray_bed", 8, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block CYAN_BED = register(new BedBlock("cyan_bed", 9, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block PURPLE_BED = register(new BedBlock("purple_bed", 10, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block BLUE_BED = register(new BedBlock("blue_bed", 11, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block BROWN_BED = register(new BedBlock("brown_bed", 12, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block GREEN_BED = register(new BedBlock("green_bed", 13, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block RED_BED = register(new BedBlock("red_bed", 14, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block BLACK_BED = register(new BedBlock("black_bed", 15, builder().setBlockEntity().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OCCUPIED) - .enumState(BED_PART, "head", "foot"))); + .enumState(BED_PART))); public static final Block POWERED_RAIL = register(new Block("powered_rail", builder().destroyTime(0.7f) .booleanState(POWERED) - .enumState(RAIL_SHAPE_STRAIGHT, "north_south", "east_west", "ascending_east", "ascending_west", "ascending_north", "ascending_south") + .enumState(RAIL_SHAPE_STRAIGHT) .booleanState(WATERLOGGED))); public static final Block DETECTOR_RAIL = register(new Block("detector_rail", builder().destroyTime(0.7f) .booleanState(POWERED) - .enumState(RAIL_SHAPE_STRAIGHT, "north_south", "east_west", "ascending_east", "ascending_west", "ascending_north", "ascending_south") + .enumState(RAIL_SHAPE_STRAIGHT) .booleanState(WATERLOGGED))); public static final Block STICKY_PISTON = register(new PistonBlock("sticky_piston", builder().destroyTime(1.5f).pushReaction(PistonBehavior.BLOCK) .booleanState(EXTENDED) @@ -311,14 +311,14 @@ public final class Blocks { public static final Block DEAD_BUSH = register(new Block("dead_bush", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block SEAGRASS = register(new Block("seagrass", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block TALL_SEAGRASS = register(new Block("tall_seagrass", builder().pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.SEAGRASS) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); + .enumState(DOUBLE_BLOCK_HALF))); public static final Block PISTON = register(new PistonBlock("piston", builder().destroyTime(1.5f).pushReaction(PistonBehavior.BLOCK) .booleanState(EXTENDED) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); public static final Block PISTON_HEAD = register(new Block("piston_head", builder().destroyTime(1.5f).pushReaction(PistonBehavior.BLOCK) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) .booleanState(SHORT) - .enumState(PISTON_TYPE, "normal", "sticky"))); + .enumState(PISTON_TYPE))); public static final Block WHITE_WOOL = register(new Block("white_wool", builder().destroyTime(0.8f))); public static final Block ORANGE_WOOL = register(new Block("orange_wool", builder().destroyTime(0.8f))); public static final Block MAGENTA_WOOL = register(new Block("magenta_wool", builder().destroyTime(0.8f))); @@ -337,7 +337,7 @@ public final class Blocks { public static final Block BLACK_WOOL = register(new Block("black_wool", builder().destroyTime(0.8f))); public static final Block MOVING_PISTON = register(new MovingPistonBlock("moving_piston", builder().setBlockEntity().destroyTime(-1.0f).pushReaction(PistonBehavior.BLOCK) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) - .enumState(PISTON_TYPE, "normal", "sticky"))); + .enumState(PISTON_TYPE))); public static final Block DANDELION = register(new Block("dandelion", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block TORCHFLOWER = register(new Block("torchflower", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block POPPY = register(new Block("poppy", builder().pushReaction(PistonBehavior.DESTROY))); @@ -374,7 +374,7 @@ public final class Blocks { public static final Block WALL_TORCH = register(new Block("wall_torch", builder().pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); public static final Block FIRE = register(new Block("fire", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_15, 0, 15) + .intState(AGE_15) .booleanState(EAST) .booleanState(NORTH) .booleanState(SOUTH) @@ -384,73 +384,73 @@ public final class Blocks { public static final Block SPAWNER = register(new SpawnerBlock("spawner", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(5.0f))); public static final Block OAK_STAIRS = register(new Block("oak_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block CHEST = register(new ChestBlock("chest", builder().setBlockEntity().destroyTime(2.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(CHEST_TYPE, ChestType.VALUES) .booleanState(WATERLOGGED))); public static final Block REDSTONE_WIRE = register(new Block("redstone_wire", builder().pushReaction(PistonBehavior.DESTROY) - .enumState(EAST_REDSTONE, "up", "side", "none") - .enumState(NORTH_REDSTONE, "up", "side", "none") - .intState(POWER, 0, 15) - .enumState(SOUTH_REDSTONE, "up", "side", "none") - .enumState(WEST_REDSTONE, "up", "side", "none"))); + .enumState(EAST_REDSTONE) + .enumState(NORTH_REDSTONE) + .intState(POWER) + .enumState(SOUTH_REDSTONE) + .enumState(WEST_REDSTONE))); public static final Block DIAMOND_ORE = register(new Block("diamond_ore", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); public static final Block DEEPSLATE_DIAMOND_ORE = register(new Block("deepslate_diamond_ore", builder().requiresCorrectToolForDrops().destroyTime(4.5f))); public static final Block DIAMOND_BLOCK = register(new Block("diamond_block", builder().requiresCorrectToolForDrops().destroyTime(5.0f))); public static final Block CRAFTING_TABLE = register(new Block("crafting_table", builder().destroyTime(2.5f))); public static final Block WHEAT = register(new Block("wheat", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_7, 0, 7))); + .intState(AGE_7))); public static final Block FARMLAND = register(new Block("farmland", builder().destroyTime(0.6f) - .intState(MOISTURE, 0, 7))); + .intState(MOISTURE))); public static final Block FURNACE = register(new FurnaceBlock("furnace", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(LIT))); public static final Block OAK_SIGN = register(new Block("oak_sign", builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block SPRUCE_SIGN = register(new Block("spruce_sign", builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block BIRCH_SIGN = register(new Block("birch_sign", builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block ACACIA_SIGN = register(new Block("acacia_sign", builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block CHERRY_SIGN = register(new Block("cherry_sign", builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block JUNGLE_SIGN = register(new Block("jungle_sign", builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block DARK_OAK_SIGN = register(new Block("dark_oak_sign", builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block MANGROVE_SIGN = register(new Block("mangrove_sign", builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block BAMBOO_SIGN = register(new Block("bamboo_sign", builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block OAK_DOOR = register(new DoorBlock("oak_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block LADDER = register(new Block("ladder", builder().destroyTime(0.4f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); public static final Block RAIL = register(new Block("rail", builder().destroyTime(0.7f) - .enumState(RAIL_SHAPE, "north_south", "east_west", "ascending_east", "ascending_west", "ascending_north", "ascending_south", "south_east", "south_west", "north_west", "north_east") + .enumState(RAIL_SHAPE) .booleanState(WATERLOGGED))); public static final Block COBBLESTONE_STAIRS = register(new Block("cobblestone_stairs", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block OAK_WALL_SIGN = register(new Block("oak_wall_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) @@ -481,47 +481,47 @@ public final class Blocks { .booleanState(WATERLOGGED))); public static final Block OAK_HANGING_SIGN = register(new Block("oak_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block SPRUCE_HANGING_SIGN = register(new Block("spruce_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block BIRCH_HANGING_SIGN = register(new Block("birch_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block ACACIA_HANGING_SIGN = register(new Block("acacia_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block CHERRY_HANGING_SIGN = register(new Block("cherry_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block JUNGLE_HANGING_SIGN = register(new Block("jungle_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block DARK_OAK_HANGING_SIGN = register(new Block("dark_oak_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block CRIMSON_HANGING_SIGN = register(new Block("crimson_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block WARPED_HANGING_SIGN = register(new Block("warped_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block MANGROVE_HANGING_SIGN = register(new Block("mangrove_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block BAMBOO_HANGING_SIGN = register(new Block("bamboo_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .booleanState(ATTACHED) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block OAK_WALL_HANGING_SIGN = register(new Block("oak_wall_hanging_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) @@ -557,15 +557,15 @@ public final class Blocks { .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); public static final Block LEVER = register(new Block("lever", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block STONE_PRESSURE_PLATE = register(new Block("stone_pressure_plate", builder().requiresCorrectToolForDrops().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED))); public static final Block IRON_DOOR = register(new DoorBlock("iron_door", builder().requiresCorrectToolForDrops().destroyTime(5.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block OAK_PRESSURE_PLATE = register(new Block("oak_pressure_plate", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) @@ -596,18 +596,18 @@ public final class Blocks { .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(LIT))); public static final Block STONE_BUTTON = register(new Block("stone_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block SNOW = register(new Block("snow", builder().requiresCorrectToolForDrops().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(LAYERS, 1, 8))); + .intState(LAYERS))); public static final Block ICE = register(new Block("ice", builder().destroyTime(0.5f))); public static final Block SNOW_BLOCK = register(new Block("snow_block", builder().requiresCorrectToolForDrops().destroyTime(0.2f))); public static final Block CACTUS = register(new Block("cactus", builder().destroyTime(0.4f).pushReaction(PistonBehavior.DESTROY) - .intState(AGE_15, 0, 15))); + .intState(AGE_15))); public static final Block CLAY = register(new Block("clay", builder().destroyTime(0.6f))); public static final Block SUGAR_CANE = register(new Block("sugar_cane", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_15, 0, 15))); + .intState(AGE_15))); public static final Block JUKEBOX = register(new Block("jukebox", builder().setBlockEntity().destroyTime(2.0f) .booleanState(HAS_RECORD))); public static final Block OAK_FENCE = register(new Block("oak_fence", builder().destroyTime(2.0f) @@ -634,9 +634,9 @@ public final class Blocks { public static final Block JACK_O_LANTERN = register(new Block("jack_o_lantern", builder().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); public static final Block CAKE = register(new Block("cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .intState(BITES, 0, 6))); + .intState(BITES))); public static final Block REPEATER = register(new Block("repeater", builder().pushReaction(PistonBehavior.DESTROY) - .intState(DELAY, 1, 4) + .intState(DELAY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(LOCKED) .booleanState(POWERED))); @@ -658,55 +658,55 @@ public final class Blocks { public static final Block BLACK_STAINED_GLASS = register(new Block("black_stained_glass", builder().destroyTime(0.3f))); public static final Block OAK_TRAPDOOR = register(new TrapDoorBlock("oak_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block SPRUCE_TRAPDOOR = register(new TrapDoorBlock("spruce_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block BIRCH_TRAPDOOR = register(new TrapDoorBlock("birch_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block JUNGLE_TRAPDOOR = register(new TrapDoorBlock("jungle_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block ACACIA_TRAPDOOR = register(new TrapDoorBlock("acacia_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block CHERRY_TRAPDOOR = register(new TrapDoorBlock("cherry_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block DARK_OAK_TRAPDOOR = register(new TrapDoorBlock("dark_oak_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block MANGROVE_TRAPDOOR = register(new TrapDoorBlock("mangrove_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block BAMBOO_TRAPDOOR = register(new TrapDoorBlock("bamboo_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); @@ -765,9 +765,9 @@ public final class Blocks { public static final Block ATTACHED_MELON_STEM = register(new Block("attached_melon_stem", builder().pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.MELON_SEEDS) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); public static final Block PUMPKIN_STEM = register(new Block("pumpkin_stem", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_7, 0, 7))); + .intState(AGE_7))); public static final Block MELON_STEM = register(new Block("melon_stem", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_7, 0, 7))); + .intState(AGE_7))); public static final Block VINE = register(new Block("vine", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) .booleanState(EAST) .booleanState(NORTH) @@ -789,18 +789,18 @@ public final class Blocks { .booleanState(POWERED))); public static final Block BRICK_STAIRS = register(new Block("brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block STONE_BRICK_STAIRS = register(new Block("stone_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block MUD_BRICK_STAIRS = register(new Block("mud_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block MYCELIUM = register(new Block("mycelium", builder().destroyTime(0.6f) .booleanState(SNOWY))); @@ -814,11 +814,11 @@ public final class Blocks { .booleanState(WEST))); public static final Block NETHER_BRICK_STAIRS = register(new Block("nether_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block NETHER_WART = register(new Block("nether_wart", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_3, 0, 3))); + .intState(AGE_3))); public static final Block ENCHANTING_TABLE = register(new Block("enchanting_table", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(5.0f))); public static final Block BREWING_STAND = register(new Block("brewing_stand", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(0.5f) .booleanState(HAS_BOTTLE_0) @@ -826,10 +826,10 @@ public final class Blocks { .booleanState(HAS_BOTTLE_2))); public static final Block CAULDRON = register(new CauldronBlock("cauldron", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); public static final Block WATER_CAULDRON = register(new CauldronBlock("water_cauldron", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .intState(LEVEL_CAULDRON, 1, 3))); + .intState(LEVEL_CAULDRON))); public static final Block LAVA_CAULDRON = register(new CauldronBlock("lava_cauldron", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); public static final Block POWDER_SNOW_CAULDRON = register(new CauldronBlock("powder_snow_cauldron", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .intState(LEVEL_CAULDRON, 1, 3))); + .intState(LEVEL_CAULDRON))); public static final Block END_PORTAL = register(new Block("end_portal", builder().setBlockEntity().destroyTime(-1.0f).pushReaction(PistonBehavior.BLOCK))); public static final Block END_PORTAL_FRAME = register(new Block("end_portal_frame", builder().destroyTime(-1.0f) .booleanState(EYE) @@ -839,12 +839,12 @@ public final class Blocks { public static final Block REDSTONE_LAMP = register(new Block("redstone_lamp", builder().destroyTime(0.3f) .booleanState(LIT))); public static final Block COCOA = register(new Block("cocoa", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) - .intState(AGE_2, 0, 2) + .intState(AGE_2) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); public static final Block SANDSTONE_STAIRS = register(new Block("sandstone_stairs", builder().requiresCorrectToolForDrops().destroyTime(0.8f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block EMERALD_ORE = register(new Block("emerald_ore", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); public static final Block DEEPSLATE_EMERALD_ORE = register(new Block("deepslate_emerald_ore", builder().requiresCorrectToolForDrops().destroyTime(4.5f))); @@ -866,37 +866,37 @@ public final class Blocks { public static final Block EMERALD_BLOCK = register(new Block("emerald_block", builder().requiresCorrectToolForDrops().destroyTime(5.0f))); public static final Block SPRUCE_STAIRS = register(new Block("spruce_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block BIRCH_STAIRS = register(new Block("birch_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block JUNGLE_STAIRS = register(new Block("jungle_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block COMMAND_BLOCK = register(new Block("command_block", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(-1.0f) .booleanState(CONDITIONAL) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); public static final Block BEACON = register(new Block("beacon", builder().setBlockEntity().destroyTime(3.0f))); public static final Block COBBLESTONE_WALL = register(new Block("cobblestone_wall", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block MOSSY_COBBLESTONE_WALL = register(new Block("mossy_cobblestone_wall", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block FLOWER_POT = register(new FlowerPotBlock("flower_pot", AIR, builder().pushReaction(PistonBehavior.DESTROY))); public static final Block POTTED_TORCHFLOWER = register(new FlowerPotBlock("potted_torchflower", TORCHFLOWER, builder().pushReaction(PistonBehavior.DESTROY))); public static final Block POTTED_OAK_SAPLING = register(new FlowerPotBlock("potted_oak_sapling", OAK_SAPLING, builder().pushReaction(PistonBehavior.DESTROY))); @@ -926,84 +926,84 @@ public final class Blocks { public static final Block POTTED_DEAD_BUSH = register(new FlowerPotBlock("potted_dead_bush", DEAD_BUSH, builder().pushReaction(PistonBehavior.DESTROY))); public static final Block POTTED_CACTUS = register(new FlowerPotBlock("potted_cactus", CACTUS, builder().pushReaction(PistonBehavior.DESTROY))); public static final Block CARROTS = register(new Block("carrots", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_7, 0, 7))); + .intState(AGE_7))); public static final Block POTATOES = register(new Block("potatoes", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_7, 0, 7))); + .intState(AGE_7))); public static final Block OAK_BUTTON = register(new Block("oak_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block SPRUCE_BUTTON = register(new Block("spruce_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block BIRCH_BUTTON = register(new Block("birch_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block JUNGLE_BUTTON = register(new Block("jungle_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block ACACIA_BUTTON = register(new Block("acacia_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block CHERRY_BUTTON = register(new Block("cherry_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block DARK_OAK_BUTTON = register(new Block("dark_oak_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block MANGROVE_BUTTON = register(new Block("mangrove_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block BAMBOO_BUTTON = register(new Block("bamboo_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block SKELETON_SKULL = register(new SkullBlock("skeleton_skull", SkullBlock.Type.SKELETON, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block SKELETON_WALL_SKULL = register(new WallSkullBlock("skeleton_wall_skull", SkullBlock.Type.SKELETON, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block WITHER_SKELETON_SKULL = register(new SkullBlock("wither_skeleton_skull", SkullBlock.Type.WITHER_SKELETON, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block WITHER_SKELETON_WALL_SKULL = register(new WallSkullBlock("wither_skeleton_wall_skull", SkullBlock.Type.WITHER_SKELETON, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block ZOMBIE_HEAD = register(new SkullBlock("zombie_head", SkullBlock.Type.ZOMBIE, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block ZOMBIE_WALL_HEAD = register(new WallSkullBlock("zombie_wall_head", SkullBlock.Type.ZOMBIE, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block PLAYER_HEAD = register(new SkullBlock("player_head", SkullBlock.Type.PLAYER, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block PLAYER_WALL_HEAD = register(new WallSkullBlock("player_wall_head", SkullBlock.Type.PLAYER, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block CREEPER_HEAD = register(new SkullBlock("creeper_head", SkullBlock.Type.CREEPER, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block CREEPER_WALL_HEAD = register(new WallSkullBlock("creeper_wall_head", SkullBlock.Type.CREEPER, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block DRAGON_HEAD = register(new SkullBlock("dragon_head", SkullBlock.Type.DRAGON, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block DRAGON_WALL_HEAD = register(new WallSkullBlock("dragon_wall_head", SkullBlock.Type.DRAGON, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block PIGLIN_HEAD = register(new SkullBlock("piglin_head", SkullBlock.Type.PIGLIN, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block PIGLIN_WALL_HEAD = register(new WallSkullBlock("piglin_wall_head", SkullBlock.Type.PIGLIN, builder().setBlockEntity().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); @@ -1018,16 +1018,16 @@ public final class Blocks { .enumState(CHEST_TYPE, ChestType.VALUES) .booleanState(WATERLOGGED))); public static final Block LIGHT_WEIGHTED_PRESSURE_PLATE = register(new Block("light_weighted_pressure_plate", builder().requiresCorrectToolForDrops().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .intState(POWER, 0, 15))); + .intState(POWER))); public static final Block HEAVY_WEIGHTED_PRESSURE_PLATE = register(new Block("heavy_weighted_pressure_plate", builder().requiresCorrectToolForDrops().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .intState(POWER, 0, 15))); + .intState(POWER))); public static final Block COMPARATOR = register(new Block("comparator", builder().setBlockEntity().pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(MODE_COMPARATOR, "compare", "subtract") + .enumState(MODE_COMPARATOR) .booleanState(POWERED))); public static final Block DAYLIGHT_DETECTOR = register(new Block("daylight_detector", builder().setBlockEntity().destroyTime(0.2f) .booleanState(INVERTED) - .intState(POWER, 0, 15))); + .intState(POWER))); public static final Block REDSTONE_BLOCK = register(new Block("redstone_block", builder().requiresCorrectToolForDrops().destroyTime(5.0f))); public static final Block NETHER_QUARTZ_ORE = register(new Block("nether_quartz_ore", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); public static final Block HOPPER = register(new Block("hopper", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(3.0f) @@ -1039,12 +1039,12 @@ public final class Blocks { .enumState(AXIS, Axis.VALUES))); public static final Block QUARTZ_STAIRS = register(new Block("quartz_stairs", builder().requiresCorrectToolForDrops().destroyTime(0.8f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block ACTIVATOR_RAIL = register(new Block("activator_rail", builder().destroyTime(0.7f) .booleanState(POWERED) - .enumState(RAIL_SHAPE_STRAIGHT, "north_south", "east_west", "ascending_east", "ascending_west", "ascending_north", "ascending_south") + .enumState(RAIL_SHAPE_STRAIGHT) .booleanState(WATERLOGGED))); public static final Block DROPPER = register(new Block("dropper", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) @@ -1163,43 +1163,43 @@ public final class Blocks { .booleanState(WEST))); public static final Block ACACIA_STAIRS = register(new Block("acacia_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block CHERRY_STAIRS = register(new Block("cherry_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block DARK_OAK_STAIRS = register(new Block("dark_oak_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block MANGROVE_STAIRS = register(new Block("mangrove_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block BAMBOO_STAIRS = register(new Block("bamboo_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block BAMBOO_MOSAIC_STAIRS = register(new Block("bamboo_mosaic_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block SLIME_BLOCK = register(new Block("slime_block", builder())); public static final Block BARRIER = register(new Block("barrier", builder().destroyTime(-1.0f).pushReaction(PistonBehavior.BLOCK) .booleanState(WATERLOGGED))); public static final Block LIGHT = register(new Block("light", builder().destroyTime(-1.0f) - .intState(LEVEL, 0, 15) + .intState(LEVEL) .booleanState(WATERLOGGED))); public static final Block IRON_TRAPDOOR = register(new TrapDoorBlock("iron_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(5.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); @@ -1208,27 +1208,27 @@ public final class Blocks { public static final Block DARK_PRISMARINE = register(new Block("dark_prismarine", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block PRISMARINE_STAIRS = register(new Block("prismarine_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block PRISMARINE_BRICK_STAIRS = register(new Block("prismarine_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block DARK_PRISMARINE_STAIRS = register(new Block("dark_prismarine_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block PRISMARINE_SLAB = register(new Block("prismarine_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block PRISMARINE_BRICK_SLAB = register(new Block("prismarine_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block DARK_PRISMARINE_SLAB = register(new Block("dark_prismarine_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block SEA_LANTERN = register(new Block("sea_lantern", builder().destroyTime(0.3f))); public static final Block HAY_BLOCK = register(new Block("hay_block", builder().destroyTime(0.5f) @@ -1253,49 +1253,49 @@ public final class Blocks { public static final Block COAL_BLOCK = register(new Block("coal_block", builder().requiresCorrectToolForDrops().destroyTime(5.0f))); public static final Block PACKED_ICE = register(new Block("packed_ice", builder().destroyTime(0.5f))); public static final Block SUNFLOWER = register(new Block("sunflower", builder().pushReaction(PistonBehavior.DESTROY) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); + .enumState(DOUBLE_BLOCK_HALF))); public static final Block LILAC = register(new Block("lilac", builder().pushReaction(PistonBehavior.DESTROY) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); + .enumState(DOUBLE_BLOCK_HALF))); public static final Block ROSE_BUSH = register(new Block("rose_bush", builder().pushReaction(PistonBehavior.DESTROY) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); + .enumState(DOUBLE_BLOCK_HALF))); public static final Block PEONY = register(new Block("peony", builder().pushReaction(PistonBehavior.DESTROY) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); + .enumState(DOUBLE_BLOCK_HALF))); public static final Block TALL_GRASS = register(new Block("tall_grass", builder().pushReaction(PistonBehavior.DESTROY) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); + .enumState(DOUBLE_BLOCK_HALF))); public static final Block LARGE_FERN = register(new Block("large_fern", builder().pushReaction(PistonBehavior.DESTROY) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); + .enumState(DOUBLE_BLOCK_HALF))); public static final Block WHITE_BANNER = register(new BannerBlock("white_banner", 0, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block ORANGE_BANNER = register(new BannerBlock("orange_banner", 1, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block MAGENTA_BANNER = register(new BannerBlock("magenta_banner", 2, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block LIGHT_BLUE_BANNER = register(new BannerBlock("light_blue_banner", 3, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block YELLOW_BANNER = register(new BannerBlock("yellow_banner", 4, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block LIME_BANNER = register(new BannerBlock("lime_banner", 5, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block PINK_BANNER = register(new BannerBlock("pink_banner", 6, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block GRAY_BANNER = register(new BannerBlock("gray_banner", 7, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block LIGHT_GRAY_BANNER = register(new BannerBlock("light_gray_banner", 8, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block CYAN_BANNER = register(new BannerBlock("cyan_banner", 9, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block PURPLE_BANNER = register(new BannerBlock("purple_banner", 10, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block BLUE_BANNER = register(new BannerBlock("blue_banner", 11, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block BROWN_BANNER = register(new BannerBlock("brown_banner", 12, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block GREEN_BANNER = register(new BannerBlock("green_banner", 13, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block RED_BANNER = register(new BannerBlock("red_banner", 14, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block BLACK_BANNER = register(new BannerBlock("black_banner", 15, builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15))); + .intState(ROTATION_16))); public static final Block WHITE_WALL_BANNER = register(new BannerBlock("white_wall_banner", 0, builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); public static final Block ORANGE_WALL_BANNER = register(new BannerBlock("orange_wall_banner", 1, builder().setBlockEntity().destroyTime(1.0f) @@ -1333,80 +1333,80 @@ public final class Blocks { public static final Block CUT_RED_SANDSTONE = register(new Block("cut_red_sandstone", builder().requiresCorrectToolForDrops().destroyTime(0.8f))); public static final Block RED_SANDSTONE_STAIRS = register(new Block("red_sandstone_stairs", builder().requiresCorrectToolForDrops().destroyTime(0.8f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block OAK_SLAB = register(new Block("oak_slab", builder().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block SPRUCE_SLAB = register(new Block("spruce_slab", builder().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block BIRCH_SLAB = register(new Block("birch_slab", builder().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block JUNGLE_SLAB = register(new Block("jungle_slab", builder().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block ACACIA_SLAB = register(new Block("acacia_slab", builder().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block CHERRY_SLAB = register(new Block("cherry_slab", builder().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block DARK_OAK_SLAB = register(new Block("dark_oak_slab", builder().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block MANGROVE_SLAB = register(new Block("mangrove_slab", builder().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block BAMBOO_SLAB = register(new Block("bamboo_slab", builder().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block BAMBOO_MOSAIC_SLAB = register(new Block("bamboo_mosaic_slab", builder().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block STONE_SLAB = register(new Block("stone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block SMOOTH_STONE_SLAB = register(new Block("smooth_stone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block SANDSTONE_SLAB = register(new Block("sandstone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block CUT_SANDSTONE_SLAB = register(new Block("cut_sandstone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block PETRIFIED_OAK_SLAB = register(new Block("petrified_oak_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block COBBLESTONE_SLAB = register(new Block("cobblestone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block BRICK_SLAB = register(new Block("brick_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block STONE_BRICK_SLAB = register(new Block("stone_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block MUD_BRICK_SLAB = register(new Block("mud_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block NETHER_BRICK_SLAB = register(new Block("nether_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block QUARTZ_SLAB = register(new Block("quartz_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block RED_SANDSTONE_SLAB = register(new Block("red_sandstone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block CUT_RED_SANDSTONE_SLAB = register(new Block("cut_red_sandstone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block PURPUR_SLAB = register(new Block("purpur_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block SMOOTH_STONE = register(new Block("smooth_stone", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); public static final Block SMOOTH_SANDSTONE = register(new Block("smooth_sandstone", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); @@ -1502,50 +1502,50 @@ public final class Blocks { .booleanState(WEST))); public static final Block SPRUCE_DOOR = register(new DoorBlock("spruce_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block BIRCH_DOOR = register(new DoorBlock("birch_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block JUNGLE_DOOR = register(new DoorBlock("jungle_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block ACACIA_DOOR = register(new DoorBlock("acacia_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block CHERRY_DOOR = register(new DoorBlock("cherry_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block DARK_OAK_DOOR = register(new DoorBlock("dark_oak_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block MANGROVE_DOOR = register(new DoorBlock("mangrove_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block BAMBOO_DOOR = register(new DoorBlock("bamboo_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block END_ROD = register(new Block("end_rod", builder() @@ -1558,25 +1558,25 @@ public final class Blocks { .booleanState(UP) .booleanState(WEST))); public static final Block CHORUS_FLOWER = register(new Block("chorus_flower", builder().destroyTime(0.4f).pushReaction(PistonBehavior.DESTROY) - .intState(AGE_5, 0, 5))); + .intState(AGE_5))); public static final Block PURPUR_BLOCK = register(new Block("purpur_block", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block PURPUR_PILLAR = register(new Block("purpur_pillar", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(AXIS, Axis.VALUES))); public static final Block PURPUR_STAIRS = register(new Block("purpur_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block END_STONE_BRICKS = register(new Block("end_stone_bricks", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); public static final Block TORCHFLOWER_CROP = register(new Block("torchflower_crop", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_1, 0, 1))); + .intState(AGE_1))); public static final Block PITCHER_CROP = register(new Block("pitcher_crop", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_4, 0, 4) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); + .intState(AGE_4) + .enumState(DOUBLE_BLOCK_HALF))); public static final Block PITCHER_PLANT = register(new Block("pitcher_plant", builder().pushReaction(PistonBehavior.DESTROY) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower"))); + .enumState(DOUBLE_BLOCK_HALF))); public static final Block BEETROOTS = register(new Block("beetroots", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_3, 0, 3))); + .intState(AGE_3))); public static final Block DIRT_PATH = register(new Block("dirt_path", builder().destroyTime(0.65f))); public static final Block END_GATEWAY = register(new Block("end_gateway", builder().setBlockEntity().destroyTime(-1.0f).pushReaction(PistonBehavior.BLOCK))); public static final Block REPEATING_COMMAND_BLOCK = register(new Block("repeating_command_block", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(-1.0f) @@ -1586,7 +1586,7 @@ public final class Blocks { .booleanState(CONDITIONAL) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); public static final Block FROSTED_ICE = register(new Block("frosted_ice", builder().destroyTime(0.5f) - .intState(AGE_3, 0, 3))); + .intState(AGE_3))); public static final Block MAGMA_BLOCK = register(new Block("magma_block", builder().requiresCorrectToolForDrops().destroyTime(0.5f))); public static final Block NETHER_WART_BLOCK = register(new Block("nether_wart_block", builder().destroyTime(1.0f))); public static final Block RED_NETHER_BRICKS = register(new Block("red_nether_bricks", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); @@ -1695,14 +1695,14 @@ public final class Blocks { public static final Block RED_CONCRETE_POWDER = register(new Block("red_concrete_powder", builder().destroyTime(0.5f))); public static final Block BLACK_CONCRETE_POWDER = register(new Block("black_concrete_powder", builder().destroyTime(0.5f))); public static final Block KELP = register(new Block("kelp", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_25, 0, 25))); + .intState(AGE_25))); public static final Block KELP_PLANT = register(new Block("kelp_plant", builder().pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.KELP))); public static final Block DRIED_KELP_BLOCK = register(new Block("dried_kelp_block", builder().destroyTime(0.5f))); public static final Block TURTLE_EGG = register(new Block("turtle_egg", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .intState(EGGS, 1, 4) - .intState(HATCH, 0, 2))); + .intState(EGGS) + .intState(HATCH))); public static final Block SNIFFER_EGG = register(new Block("sniffer_egg", builder().destroyTime(0.5f) - .intState(HATCH, 0, 2))); + .intState(HATCH))); public static final Block DEAD_TUBE_CORAL_BLOCK = register(new Block("dead_tube_coral_block", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block DEAD_BRAIN_CORAL_BLOCK = register(new Block("dead_brain_coral_block", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block DEAD_BUBBLE_CORAL_BLOCK = register(new Block("dead_bubble_coral_block", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); @@ -1784,16 +1784,16 @@ public final class Blocks { .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); public static final Block SEA_PICKLE = register(new Block("sea_pickle", builder().pushReaction(PistonBehavior.DESTROY) - .intState(PICKLES, 1, 4) + .intState(PICKLES) .booleanState(WATERLOGGED))); public static final Block BLUE_ICE = register(new Block("blue_ice", builder().destroyTime(2.8f))); public static final Block CONDUIT = register(new Block("conduit", builder().setBlockEntity().destroyTime(3.0f) .booleanState(WATERLOGGED))); public static final Block BAMBOO_SAPLING = register(new Block("bamboo_sapling", builder().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.BAMBOO))); public static final Block BAMBOO = register(new Block("bamboo", builder().destroyTime(1.0f).pushReaction(PistonBehavior.DESTROY) - .intState(AGE_1, 0, 1) - .enumState(BAMBOO_LEAVES, "none", "small", "large") - .intState(STAGE, 0, 1))); + .intState(AGE_1) + .enumState(BAMBOO_LEAVES) + .intState(STAGE))); public static final Block POTTED_BAMBOO = register(new FlowerPotBlock("potted_bamboo", BAMBOO, builder().pushReaction(PistonBehavior.DESTROY))); public static final Block VOID_AIR = register(new Block("void_air", builder())); public static final Block CAVE_AIR = register(new Block("cave_air", builder())); @@ -1801,207 +1801,207 @@ public final class Blocks { .booleanState(DRAG))); public static final Block POLISHED_GRANITE_STAIRS = register(new Block("polished_granite_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block SMOOTH_RED_SANDSTONE_STAIRS = register(new Block("smooth_red_sandstone_stairs", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block MOSSY_STONE_BRICK_STAIRS = register(new Block("mossy_stone_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_DIORITE_STAIRS = register(new Block("polished_diorite_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block MOSSY_COBBLESTONE_STAIRS = register(new Block("mossy_cobblestone_stairs", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block END_STONE_BRICK_STAIRS = register(new Block("end_stone_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block STONE_STAIRS = register(new Block("stone_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block SMOOTH_SANDSTONE_STAIRS = register(new Block("smooth_sandstone_stairs", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block SMOOTH_QUARTZ_STAIRS = register(new Block("smooth_quartz_stairs", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block GRANITE_STAIRS = register(new Block("granite_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block ANDESITE_STAIRS = register(new Block("andesite_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block RED_NETHER_BRICK_STAIRS = register(new Block("red_nether_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_ANDESITE_STAIRS = register(new Block("polished_andesite_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block DIORITE_STAIRS = register(new Block("diorite_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_GRANITE_SLAB = register(new Block("polished_granite_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block SMOOTH_RED_SANDSTONE_SLAB = register(new Block("smooth_red_sandstone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block MOSSY_STONE_BRICK_SLAB = register(new Block("mossy_stone_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_DIORITE_SLAB = register(new Block("polished_diorite_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block MOSSY_COBBLESTONE_SLAB = register(new Block("mossy_cobblestone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block END_STONE_BRICK_SLAB = register(new Block("end_stone_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block SMOOTH_SANDSTONE_SLAB = register(new Block("smooth_sandstone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block SMOOTH_QUARTZ_SLAB = register(new Block("smooth_quartz_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block GRANITE_SLAB = register(new Block("granite_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block ANDESITE_SLAB = register(new Block("andesite_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block RED_NETHER_BRICK_SLAB = register(new Block("red_nether_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_ANDESITE_SLAB = register(new Block("polished_andesite_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block DIORITE_SLAB = register(new Block("diorite_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block BRICK_WALL = register(new Block("brick_wall", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block PRISMARINE_WALL = register(new Block("prismarine_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block RED_SANDSTONE_WALL = register(new Block("red_sandstone_wall", builder().requiresCorrectToolForDrops().destroyTime(0.8f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block MOSSY_STONE_BRICK_WALL = register(new Block("mossy_stone_brick_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block GRANITE_WALL = register(new Block("granite_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block STONE_BRICK_WALL = register(new Block("stone_brick_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block MUD_BRICK_WALL = register(new Block("mud_brick_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block NETHER_BRICK_WALL = register(new Block("nether_brick_wall", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block ANDESITE_WALL = register(new Block("andesite_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block RED_NETHER_BRICK_WALL = register(new Block("red_nether_brick_wall", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block SANDSTONE_WALL = register(new Block("sandstone_wall", builder().requiresCorrectToolForDrops().destroyTime(0.8f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block END_STONE_BRICK_WALL = register(new Block("end_stone_brick_wall", builder().requiresCorrectToolForDrops().destroyTime(3.0f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block DIORITE_WALL = register(new Block("diorite_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block SCAFFOLDING = register(new Block("scaffolding", builder().pushReaction(PistonBehavior.DESTROY) .booleanState(BOTTOM) - .intState(STABILITY_DISTANCE, 0, 7) + .intState(STABILITY_DISTANCE) .booleanState(WATERLOGGED))); public static final Block LOOM = register(new Block("loom", builder().destroyTime(2.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); @@ -2017,7 +2017,7 @@ public final class Blocks { public static final Block CARTOGRAPHY_TABLE = register(new Block("cartography_table", builder().destroyTime(2.5f))); public static final Block FLETCHING_TABLE = register(new Block("fletching_table", builder().destroyTime(2.5f))); public static final Block GRINDSTONE = register(new Block("grindstone", builder().requiresCorrectToolForDrops().destroyTime(2.0f).pushReaction(PistonBehavior.BLOCK) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); public static final Block LECTERN = register(new LecternBlock("lectern", builder().setBlockEntity().destroyTime(2.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) @@ -2027,7 +2027,7 @@ public final class Blocks { public static final Block STONECUTTER = register(new Block("stonecutter", builder().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST))); public static final Block BELL = register(new Block("bell", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(5.0f).pushReaction(PistonBehavior.DESTROY) - .enumState(BELL_ATTACHMENT, "floor", "ceiling", "single_wall", "double_wall") + .enumState(BELL_ATTACHMENT) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block LANTERN = register(new Block("lantern", builder().requiresCorrectToolForDrops().destroyTime(3.5f).pushReaction(PistonBehavior.DESTROY) @@ -2047,7 +2047,7 @@ public final class Blocks { .booleanState(SIGNAL_FIRE) .booleanState(WATERLOGGED))); public static final Block SWEET_BERRY_BUSH = register(new Block("sweet_berry_bush", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_3, 0, 3))); + .intState(AGE_3))); public static final Block WARPED_STEM = register(new Block("warped_stem", builder().destroyTime(2.0f) .enumState(AXIS, Axis.VALUES))); public static final Block STRIPPED_WARPED_STEM = register(new Block("stripped_warped_stem", builder().destroyTime(2.0f) @@ -2073,19 +2073,19 @@ public final class Blocks { public static final Block CRIMSON_FUNGUS = register(new Block("crimson_fungus", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block SHROOMLIGHT = register(new Block("shroomlight", builder().destroyTime(1.0f))); public static final Block WEEPING_VINES = register(new Block("weeping_vines", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_25, 0, 25))); + .intState(AGE_25))); public static final Block WEEPING_VINES_PLANT = register(new Block("weeping_vines_plant", builder().pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.WEEPING_VINES))); public static final Block TWISTING_VINES = register(new Block("twisting_vines", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_25, 0, 25))); + .intState(AGE_25))); public static final Block TWISTING_VINES_PLANT = register(new Block("twisting_vines_plant", builder().pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.TWISTING_VINES))); public static final Block CRIMSON_ROOTS = register(new Block("crimson_roots", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block CRIMSON_PLANKS = register(new Block("crimson_planks", builder().destroyTime(2.0f))); public static final Block WARPED_PLANKS = register(new Block("warped_planks", builder().destroyTime(2.0f))); public static final Block CRIMSON_SLAB = register(new Block("crimson_slab", builder().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block WARPED_SLAB = register(new Block("warped_slab", builder().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block CRIMSON_PRESSURE_PLATE = register(new Block("crimson_pressure_plate", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED))); @@ -2105,13 +2105,13 @@ public final class Blocks { .booleanState(WEST))); public static final Block CRIMSON_TRAPDOOR = register(new TrapDoorBlock("crimson_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block WARPED_TRAPDOOR = register(new TrapDoorBlock("warped_trapdoor", builder().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); @@ -2127,39 +2127,39 @@ public final class Blocks { .booleanState(POWERED))); public static final Block CRIMSON_STAIRS = register(new Block("crimson_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block WARPED_STAIRS = register(new Block("warped_stairs", builder().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block CRIMSON_BUTTON = register(new Block("crimson_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block WARPED_BUTTON = register(new Block("warped_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block CRIMSON_DOOR = register(new DoorBlock("crimson_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block WARPED_DOOR = register(new DoorBlock("warped_door", builder().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block CRIMSON_SIGN = register(new Block("crimson_sign", builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block WARPED_SIGN = register(new Block("warped_sign", builder().setBlockEntity().destroyTime(1.0f) - .intState(ROTATION_16, 0, 15) + .intState(ROTATION_16) .booleanState(WATERLOGGED))); public static final Block CRIMSON_WALL_SIGN = register(new Block("crimson_wall_sign", builder().setBlockEntity().destroyTime(1.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) @@ -2168,26 +2168,26 @@ public final class Blocks { .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); public static final Block STRUCTURE_BLOCK = register(new Block("structure_block", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(-1.0f) - .enumState(STRUCTUREBLOCK_MODE, "save", "load", "corner", "data"))); + .enumState(STRUCTUREBLOCK_MODE))); public static final Block JIGSAW = register(new Block("jigsaw", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(-1.0f) .enumState(ORIENTATION, FrontAndTop.VALUES))); public static final Block COMPOSTER = register(new Block("composter", builder().destroyTime(0.6f) - .intState(LEVEL_COMPOSTER, 0, 8))); + .intState(LEVEL_COMPOSTER))); public static final Block TARGET = register(new Block("target", builder().destroyTime(0.5f) - .intState(POWER, 0, 15))); + .intState(POWER))); public static final Block BEE_NEST = register(new Block("bee_nest", builder().setBlockEntity().destroyTime(0.3f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .intState(LEVEL_HONEY, 0, 5))); + .intState(LEVEL_HONEY))); public static final Block BEEHIVE = register(new Block("beehive", builder().setBlockEntity().destroyTime(0.6f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .intState(LEVEL_HONEY, 0, 5))); + .intState(LEVEL_HONEY))); public static final Block HONEY_BLOCK = register(new HoneyBlock("honey_block", builder())); public static final Block HONEYCOMB_BLOCK = register(new Block("honeycomb_block", builder().destroyTime(0.6f))); public static final Block NETHERITE_BLOCK = register(new Block("netherite_block", builder().requiresCorrectToolForDrops().destroyTime(50.0f))); public static final Block ANCIENT_DEBRIS = register(new Block("ancient_debris", builder().requiresCorrectToolForDrops().destroyTime(30.0f))); public static final Block CRYING_OBSIDIAN = register(new Block("crying_obsidian", builder().requiresCorrectToolForDrops().destroyTime(50.0f))); public static final Block RESPAWN_ANCHOR = register(new Block("respawn_anchor", builder().requiresCorrectToolForDrops().destroyTime(50.0f) - .intState(RESPAWN_ANCHOR_CHARGES, 0, 4))); + .intState(RESPAWN_ANCHOR_CHARGES))); public static final Block POTTED_CRIMSON_FUNGUS = register(new FlowerPotBlock("potted_crimson_fungus", CRIMSON_FUNGUS, builder().pushReaction(PistonBehavior.DESTROY))); public static final Block POTTED_WARPED_FUNGUS = register(new FlowerPotBlock("potted_warped_fungus", WARPED_FUNGUS, builder().pushReaction(PistonBehavior.DESTROY))); public static final Block POTTED_CRIMSON_ROOTS = register(new FlowerPotBlock("potted_crimson_roots", CRIMSON_ROOTS, builder().pushReaction(PistonBehavior.DESTROY))); @@ -2196,129 +2196,129 @@ public final class Blocks { public static final Block BLACKSTONE = register(new Block("blackstone", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block BLACKSTONE_STAIRS = register(new Block("blackstone_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block BLACKSTONE_WALL = register(new Block("blackstone_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block BLACKSTONE_SLAB = register(new Block("blackstone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_BLACKSTONE = register(new Block("polished_blackstone", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); public static final Block POLISHED_BLACKSTONE_BRICKS = register(new Block("polished_blackstone_bricks", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block CRACKED_POLISHED_BLACKSTONE_BRICKS = register(new Block("cracked_polished_blackstone_bricks", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block CHISELED_POLISHED_BLACKSTONE = register(new Block("chiseled_polished_blackstone", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block POLISHED_BLACKSTONE_BRICK_SLAB = register(new Block("polished_blackstone_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_BLACKSTONE_BRICK_STAIRS = register(new Block("polished_blackstone_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_BLACKSTONE_BRICK_WALL = register(new Block("polished_blackstone_brick_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block GILDED_BLACKSTONE = register(new Block("gilded_blackstone", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block POLISHED_BLACKSTONE_STAIRS = register(new Block("polished_blackstone_stairs", builder().requiresCorrectToolForDrops().destroyTime(2.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_BLACKSTONE_SLAB = register(new Block("polished_blackstone_slab", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_BLACKSTONE_PRESSURE_PLATE = register(new Block("polished_blackstone_pressure_plate", builder().requiresCorrectToolForDrops().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) .booleanState(POWERED))); public static final Block POLISHED_BLACKSTONE_BUTTON = register(new Block("polished_blackstone_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(ATTACH_FACE, "floor", "wall", "ceiling") + .enumState(ATTACH_FACE) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(POWERED))); public static final Block POLISHED_BLACKSTONE_WALL = register(new Block("polished_blackstone_wall", builder().requiresCorrectToolForDrops().destroyTime(2.0f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block CHISELED_NETHER_BRICKS = register(new Block("chiseled_nether_bricks", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); public static final Block CRACKED_NETHER_BRICKS = register(new Block("cracked_nether_bricks", builder().requiresCorrectToolForDrops().destroyTime(2.0f))); public static final Block QUARTZ_BRICKS = register(new Block("quartz_bricks", builder().requiresCorrectToolForDrops().destroyTime(0.8f))); public static final Block CANDLE = register(new Block("candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block WHITE_CANDLE = register(new Block("white_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block ORANGE_CANDLE = register(new Block("orange_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block MAGENTA_CANDLE = register(new Block("magenta_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block LIGHT_BLUE_CANDLE = register(new Block("light_blue_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block YELLOW_CANDLE = register(new Block("yellow_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block LIME_CANDLE = register(new Block("lime_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block PINK_CANDLE = register(new Block("pink_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block GRAY_CANDLE = register(new Block("gray_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block LIGHT_GRAY_CANDLE = register(new Block("light_gray_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block CYAN_CANDLE = register(new Block("cyan_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block PURPLE_CANDLE = register(new Block("purple_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block BLUE_CANDLE = register(new Block("blue_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block BROWN_CANDLE = register(new Block("brown_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block GREEN_CANDLE = register(new Block("green_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block RED_CANDLE = register(new Block("red_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block BLACK_CANDLE = register(new Block("black_candle", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) - .intState(CANDLES, 1, 4) + .intState(CANDLES) .booleanState(LIT) .booleanState(WATERLOGGED))); public static final Block CANDLE_CAKE = register(new Block("candle_cake", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.CAKE) @@ -2371,65 +2371,65 @@ public final class Blocks { .booleanState(WATERLOGGED))); public static final Block TUFF = register(new Block("tuff", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block TUFF_SLAB = register(new Block("tuff_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block TUFF_STAIRS = register(new Block("tuff_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block TUFF_WALL = register(new Block("tuff_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block POLISHED_TUFF = register(new Block("polished_tuff", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block POLISHED_TUFF_SLAB = register(new Block("polished_tuff_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_TUFF_STAIRS = register(new Block("polished_tuff_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_TUFF_WALL = register(new Block("polished_tuff_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block CHISELED_TUFF = register(new Block("chiseled_tuff", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block TUFF_BRICKS = register(new Block("tuff_bricks", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block TUFF_BRICK_SLAB = register(new Block("tuff_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block TUFF_BRICK_STAIRS = register(new Block("tuff_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block TUFF_BRICK_WALL = register(new Block("tuff_brick_wall", builder().requiresCorrectToolForDrops().destroyTime(1.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block CHISELED_TUFF_BRICKS = register(new Block("chiseled_tuff_bricks", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block CALCITE = register(new Block("calcite", builder().requiresCorrectToolForDrops().destroyTime(0.75f))); public static final Block TINTED_GLASS = register(new Block("tinted_glass", builder().destroyTime(0.3f))); public static final Block POWDER_SNOW = register(new Block("powder_snow", builder().destroyTime(0.25f))); public static final Block SCULK_SENSOR = register(new Block("sculk_sensor", builder().setBlockEntity().destroyTime(1.5f) - .intState(POWER, 0, 15) - .enumState(SCULK_SENSOR_PHASE, "inactive", "active", "cooldown") + .intState(POWER) + .enumState(SCULK_SENSOR_PHASE) .booleanState(WATERLOGGED))); public static final Block CALIBRATED_SCULK_SENSOR = register(new Block("calibrated_sculk_sensor", builder().setBlockEntity().destroyTime(1.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .intState(POWER, 0, 15) - .enumState(SCULK_SENSOR_PHASE, "inactive", "active", "cooldown") + .intState(POWER) + .enumState(SCULK_SENSOR_PHASE) .booleanState(WATERLOGGED))); public static final Block SCULK = register(new Block("sculk", builder().destroyTime(0.2f))); public static final Block SCULK_VEIN = register(new Block("sculk_vein", builder().destroyTime(0.2f).pushReaction(PistonBehavior.DESTROY) @@ -2466,35 +2466,35 @@ public final class Blocks { public static final Block WAXED_CHISELED_COPPER = register(new Block("waxed_chiseled_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); public static final Block OXIDIZED_CUT_COPPER_STAIRS = register(new Block("oxidized_cut_copper_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block WEATHERED_CUT_COPPER_STAIRS = register(new Block("weathered_cut_copper_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block EXPOSED_CUT_COPPER_STAIRS = register(new Block("exposed_cut_copper_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block CUT_COPPER_STAIRS = register(new Block("cut_copper_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block OXIDIZED_CUT_COPPER_SLAB = register(new Block("oxidized_cut_copper_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block WEATHERED_CUT_COPPER_SLAB = register(new Block("weathered_cut_copper_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block EXPOSED_CUT_COPPER_SLAB = register(new Block("exposed_cut_copper_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block CUT_COPPER_SLAB = register(new Block("cut_copper_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block WAXED_COPPER_BLOCK = register(new Block("waxed_copper_block", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); public static final Block WAXED_WEATHERED_COPPER = register(new Block("waxed_weathered_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); @@ -2506,129 +2506,129 @@ public final class Blocks { public static final Block WAXED_CUT_COPPER = register(new Block("waxed_cut_copper", builder().requiresCorrectToolForDrops().destroyTime(3.0f))); public static final Block WAXED_OXIDIZED_CUT_COPPER_STAIRS = register(new Block("waxed_oxidized_cut_copper_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block WAXED_WEATHERED_CUT_COPPER_STAIRS = register(new Block("waxed_weathered_cut_copper_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block WAXED_EXPOSED_CUT_COPPER_STAIRS = register(new Block("waxed_exposed_cut_copper_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block WAXED_CUT_COPPER_STAIRS = register(new Block("waxed_cut_copper_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block WAXED_OXIDIZED_CUT_COPPER_SLAB = register(new Block("waxed_oxidized_cut_copper_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block WAXED_WEATHERED_CUT_COPPER_SLAB = register(new Block("waxed_weathered_cut_copper_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block WAXED_EXPOSED_CUT_COPPER_SLAB = register(new Block("waxed_exposed_cut_copper_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block WAXED_CUT_COPPER_SLAB = register(new Block("waxed_cut_copper_slab", builder().requiresCorrectToolForDrops().destroyTime(3.0f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block COPPER_DOOR = register(new DoorBlock("copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block EXPOSED_COPPER_DOOR = register(new DoorBlock("exposed_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block OXIDIZED_COPPER_DOOR = register(new DoorBlock("oxidized_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block WEATHERED_COPPER_DOOR = register(new DoorBlock("weathered_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block WAXED_COPPER_DOOR = register(new DoorBlock("waxed_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block WAXED_EXPOSED_COPPER_DOOR = register(new DoorBlock("waxed_exposed_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block WAXED_OXIDIZED_COPPER_DOOR = register(new DoorBlock("waxed_oxidized_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block WAXED_WEATHERED_COPPER_DOOR = register(new DoorBlock("waxed_weathered_copper_door", builder().requiresCorrectToolForDrops().destroyTime(3.0f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") - .enumState(DOOR_HINGE, "left", "right") + .enumState(DOUBLE_BLOCK_HALF) + .enumState(DOOR_HINGE) .booleanState(OPEN) .booleanState(POWERED))); public static final Block COPPER_TRAPDOOR = register(new TrapDoorBlock("copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block EXPOSED_COPPER_TRAPDOOR = register(new TrapDoorBlock("exposed_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block OXIDIZED_COPPER_TRAPDOOR = register(new TrapDoorBlock("oxidized_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block WEATHERED_COPPER_TRAPDOOR = register(new TrapDoorBlock("weathered_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block WAXED_COPPER_TRAPDOOR = register(new TrapDoorBlock("waxed_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block WAXED_EXPOSED_COPPER_TRAPDOOR = register(new TrapDoorBlock("waxed_exposed_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block WAXED_OXIDIZED_COPPER_TRAPDOOR = register(new TrapDoorBlock("waxed_oxidized_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block WAXED_WEATHERED_COPPER_TRAPDOOR = register(new TrapDoorBlock("waxed_weathered_copper_trapdoor", builder().requiresCorrectToolForDrops().destroyTime(3.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") + .enumState(HALF) .booleanState(OPEN) .booleanState(POWERED) .booleanState(WATERLOGGED))); @@ -2677,12 +2677,12 @@ public final class Blocks { .booleanState(POWERED) .booleanState(WATERLOGGED))); public static final Block POINTED_DRIPSTONE = register(new Block("pointed_dripstone", builder().destroyTime(1.5f).pushReaction(PistonBehavior.DESTROY) - .enumState(DRIPSTONE_THICKNESS, "tip_merge", "tip", "frustum", "middle", "base") + .enumState(DRIPSTONE_THICKNESS) .enumState(VERTICAL_DIRECTION, Direction.UP, Direction.DOWN) .booleanState(WATERLOGGED))); public static final Block DRIPSTONE_BLOCK = register(new Block("dripstone_block", builder().requiresCorrectToolForDrops().destroyTime(1.5f))); public static final Block CAVE_VINES = register(new Block("cave_vines", builder().pushReaction(PistonBehavior.DESTROY) - .intState(AGE_25, 0, 25) + .intState(AGE_25) .booleanState(BERRIES))); public static final Block CAVE_VINES_PLANT = register(new Block("cave_vines_plant", builder().pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.GLOW_BERRIES) .booleanState(BERRIES))); @@ -2692,18 +2692,18 @@ public final class Blocks { public static final Block MOSS_CARPET = register(new Block("moss_carpet", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY))); public static final Block PINK_PETALS = register(new Block("pink_petals", builder().pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .intState(FLOWER_AMOUNT, 1, 4))); + .intState(FLOWER_AMOUNT))); public static final Block MOSS_BLOCK = register(new Block("moss_block", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY))); public static final Block BIG_DRIPLEAF = register(new Block("big_dripleaf", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(TILT, "none", "unstable", "partial", "full") + .enumState(TILT) .booleanState(WATERLOGGED))); public static final Block BIG_DRIPLEAF_STEM = register(new Block("big_dripleaf_stem", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(WATERLOGGED))); public static final Block SMALL_DRIPLEAF = register(new Block("small_dripleaf", builder().pushReaction(PistonBehavior.DESTROY) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(DOUBLE_BLOCK_HALF, "upper", "lower") + .enumState(DOUBLE_BLOCK_HALF) .booleanState(WATERLOGGED))); public static final Block HANGING_ROOTS = register(new Block("hanging_roots", builder().pushReaction(PistonBehavior.DESTROY) .booleanState(WATERLOGGED))); @@ -2714,67 +2714,67 @@ public final class Blocks { public static final Block COBBLED_DEEPSLATE = register(new Block("cobbled_deepslate", builder().requiresCorrectToolForDrops().destroyTime(3.5f))); public static final Block COBBLED_DEEPSLATE_STAIRS = register(new Block("cobbled_deepslate_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block COBBLED_DEEPSLATE_SLAB = register(new Block("cobbled_deepslate_slab", builder().requiresCorrectToolForDrops().destroyTime(3.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block COBBLED_DEEPSLATE_WALL = register(new Block("cobbled_deepslate_wall", builder().requiresCorrectToolForDrops().destroyTime(3.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block POLISHED_DEEPSLATE = register(new Block("polished_deepslate", builder().requiresCorrectToolForDrops().destroyTime(3.5f))); public static final Block POLISHED_DEEPSLATE_STAIRS = register(new Block("polished_deepslate_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_DEEPSLATE_SLAB = register(new Block("polished_deepslate_slab", builder().requiresCorrectToolForDrops().destroyTime(3.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block POLISHED_DEEPSLATE_WALL = register(new Block("polished_deepslate_wall", builder().requiresCorrectToolForDrops().destroyTime(3.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block DEEPSLATE_TILES = register(new Block("deepslate_tiles", builder().requiresCorrectToolForDrops().destroyTime(3.5f))); public static final Block DEEPSLATE_TILE_STAIRS = register(new Block("deepslate_tile_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block DEEPSLATE_TILE_SLAB = register(new Block("deepslate_tile_slab", builder().requiresCorrectToolForDrops().destroyTime(3.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block DEEPSLATE_TILE_WALL = register(new Block("deepslate_tile_wall", builder().requiresCorrectToolForDrops().destroyTime(3.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block DEEPSLATE_BRICKS = register(new Block("deepslate_bricks", builder().requiresCorrectToolForDrops().destroyTime(3.5f))); public static final Block DEEPSLATE_BRICK_STAIRS = register(new Block("deepslate_brick_stairs", builder().requiresCorrectToolForDrops().destroyTime(3.5f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) - .enumState(HALF, "top", "bottom") - .enumState(STAIRS_SHAPE, "straight", "inner_left", "inner_right", "outer_left", "outer_right") + .enumState(HALF) + .enumState(STAIRS_SHAPE) .booleanState(WATERLOGGED))); public static final Block DEEPSLATE_BRICK_SLAB = register(new Block("deepslate_brick_slab", builder().requiresCorrectToolForDrops().destroyTime(3.5f) - .enumState(SLAB_TYPE, "top", "bottom", "double") + .enumState(SLAB_TYPE) .booleanState(WATERLOGGED))); public static final Block DEEPSLATE_BRICK_WALL = register(new Block("deepslate_brick_wall", builder().requiresCorrectToolForDrops().destroyTime(3.5f) - .enumState(EAST_WALL, "none", "low", "tall") - .enumState(NORTH_WALL, "none", "low", "tall") - .enumState(SOUTH_WALL, "none", "low", "tall") + .enumState(EAST_WALL) + .enumState(NORTH_WALL) + .enumState(SOUTH_WALL) .booleanState(UP) .booleanState(WATERLOGGED) - .enumState(WEST_WALL, "none", "low", "tall"))); + .enumState(WEST_WALL))); public static final Block CHISELED_DEEPSLATE = register(new Block("chiseled_deepslate", builder().requiresCorrectToolForDrops().destroyTime(3.5f))); public static final Block CRACKED_DEEPSLATE_BRICKS = register(new Block("cracked_deepslate_bricks", builder().requiresCorrectToolForDrops().destroyTime(3.5f))); public static final Block CRACKED_DEEPSLATE_TILES = register(new Block("cracked_deepslate_tiles", builder().requiresCorrectToolForDrops().destroyTime(3.5f))); @@ -2804,11 +2804,11 @@ public final class Blocks { .booleanState(TRIGGERED))); public static final Block TRIAL_SPAWNER = register(new Block("trial_spawner", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(50.0f) .booleanState(OMINOUS) - .enumState(TRIAL_SPAWNER_STATE, "inactive", "waiting_for_players", "active", "waiting_for_reward_ejection", "ejecting_reward", "cooldown"))); + .enumState(TRIAL_SPAWNER_STATE))); public static final Block VAULT = register(new Block("vault", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(50.0f) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .booleanState(OMINOUS) - .enumState(VAULT_STATE, "inactive", "active", "unlocking", "ejecting"))); + .enumState(VAULT_STATE))); public static final Block HEAVY_CORE = register(new Block("heavy_core", builder().destroyTime(10.0f) .booleanState(WATERLOGGED))); diff --git a/core/src/main/java/org/geysermc/geyser/level/block/property/BasicEnumProperty.java b/core/src/main/java/org/geysermc/geyser/level/block/property/BasicEnumProperty.java new file mode 100644 index 000000000..f55b85d7b --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/property/BasicEnumProperty.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.property; + +import java.util.List; + +/** + * Represents enums we don't need classes for in Geyser. + */ +public final class BasicEnumProperty extends Property { + private final List values; + + private BasicEnumProperty(String name, List values) { + super(name); + this.values = values; + } + + @Override + public int valuesCount() { + return this.values.size(); + } + + @Override + public int indexOf(String value) { + int index = this.values.indexOf(value); + if (index == -1) { + throw new IllegalStateException("Property " + this + " does not have value " + value); + } + return index; + } + + @SuppressWarnings("unchecked") + public T values() { + return (T) this.values; + } + + public static BasicEnumProperty create(String name, String... values) { + return new BasicEnumProperty(name, List.of(values)); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/level/block/property/BooleanProperty.java b/core/src/main/java/org/geysermc/geyser/level/block/property/BooleanProperty.java new file mode 100644 index 000000000..56877f537 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/property/BooleanProperty.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.property; + +public final class BooleanProperty extends Property { + private BooleanProperty(String name) { + super(name); + } + + @Override + public int valuesCount() { + return 2; + } + + @Override + public int indexOf(Boolean value) { + return value ? 0 : 1; + } + + public static BooleanProperty create(String name) { + return new BooleanProperty(name); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/level/block/property/EnumProperty.java b/core/src/main/java/org/geysermc/geyser/level/block/property/EnumProperty.java new file mode 100644 index 000000000..e31f665f9 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/property/EnumProperty.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.property; + +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; + +public final class EnumProperty> extends Property { + private final IntList ordinalValues; + + /** + * @param values all possible values of this enum. + */ + private EnumProperty(String name, T[] values) { + super(name); + this.ordinalValues = new IntArrayList(values.length); + for (T anEnum : values) { + this.ordinalValues.add(anEnum.ordinal()); + } + } + + @Override + public int valuesCount() { + return this.ordinalValues.size(); + } + + @Override + public int indexOf(T value) { + return this.ordinalValues.indexOf(value.ordinal()); + } + + @SafeVarargs + public static > EnumProperty create(String name, T... values) { + return new EnumProperty<>(name, values); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/level/block/property/IntegerProperty.java b/core/src/main/java/org/geysermc/geyser/level/block/property/IntegerProperty.java new file mode 100644 index 000000000..a772f414d --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/property/IntegerProperty.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.property; + +public final class IntegerProperty extends Property { + private final int offset; + private final int valuesCount; + + private IntegerProperty(String name, int low, int high) { + super(name); + this.offset = low; + this.valuesCount = high - low; + } + + @Override + public int valuesCount() { + return this.valuesCount; + } + + @Override + public int indexOf(Integer value) { + return value - this.offset; + } + + public int low() { + return this.offset; + } + + public int high() { + return this.offset + this.valuesCount; + } + + public static IntegerProperty create(String name, int low, int high) { + return new IntegerProperty(name, low, high); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/level/block/property/Properties.java b/core/src/main/java/org/geysermc/geyser/level/block/property/Properties.java index 7df09003d..7efa2ef80 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/property/Properties.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/property/Properties.java @@ -29,118 +29,118 @@ import org.geysermc.geyser.level.physics.Axis; import org.geysermc.geyser.level.physics.Direction; public final class Properties { - public static final Property ATTACHED = Property.create("attached"); - public static final Property BOTTOM = Property.create("bottom"); - public static final Property CONDITIONAL = Property.create("conditional"); - public static final Property DISARMED = Property.create("disarmed"); - public static final Property DRAG = Property.create("drag"); - public static final Property ENABLED = Property.create("enabled"); - public static final Property EXTENDED = Property.create("extended"); - public static final Property EYE = Property.create("eye"); - public static final Property FALLING = Property.create("falling"); - public static final Property HANGING = Property.create("hanging"); - public static final Property HAS_BOTTLE_0 = Property.create("has_bottle_0"); - public static final Property HAS_BOTTLE_1 = Property.create("has_bottle_1"); - public static final Property HAS_BOTTLE_2 = Property.create("has_bottle_2"); - public static final Property HAS_RECORD = Property.create("has_record"); - public static final Property HAS_BOOK = Property.create("has_book"); - public static final Property INVERTED = Property.create("inverted"); - public static final Property IN_WALL = Property.create("in_wall"); - public static final Property LIT = Property.create("lit"); - public static final Property LOCKED = Property.create("locked"); - public static final Property OCCUPIED = Property.create("occupied"); - public static final Property OPEN = Property.create("open"); - public static final Property PERSISTENT = Property.create("persistent"); - public static final Property POWERED = Property.create("powered"); - public static final Property SHORT = Property.create("short"); - public static final Property SIGNAL_FIRE = Property.create("signal_fire"); - public static final Property SNOWY = Property.create("snowy"); - public static final Property TRIGGERED = Property.create("triggered"); - public static final Property UNSTABLE = Property.create("unstable"); - public static final Property WATERLOGGED = Property.create("waterlogged"); - public static final Property BERRIES = Property.create("berries"); - public static final Property BLOOM = Property.create("bloom"); - public static final Property SHRIEKING = Property.create("shrieking"); - public static final Property CAN_SUMMON = Property.create("can_summon"); - public static final Property HORIZONTAL_AXIS = Property.create("axis"); - public static final Property AXIS = Property.create("axis"); - public static final Property UP = Property.create("up"); - public static final Property DOWN = Property.create("down"); - public static final Property NORTH = Property.create("north"); - public static final Property EAST = Property.create("east"); - public static final Property SOUTH = Property.create("south"); - public static final Property WEST = Property.create("west"); - public static final Property FACING = Property.create("facing"); - public static final Property FACING_HOPPER = Property.create("facing"); - public static final Property HORIZONTAL_FACING = Property.create("facing"); - public static final Property FLOWER_AMOUNT = Property.create("flower_amount"); - public static final Property ORIENTATION = Property.create("orientation"); - public static final Property ATTACH_FACE = Property.create("face"); - public static final Property BELL_ATTACHMENT = Property.create("attachment"); - public static final Property EAST_WALL = Property.create("east"); - public static final Property NORTH_WALL = Property.create("north"); - public static final Property SOUTH_WALL = Property.create("south"); - public static final Property WEST_WALL = Property.create("west"); - public static final Property EAST_REDSTONE = Property.create("east"); - public static final Property NORTH_REDSTONE = Property.create("north"); - public static final Property SOUTH_REDSTONE = Property.create("south"); - public static final Property WEST_REDSTONE = Property.create("west"); - public static final Property DOUBLE_BLOCK_HALF = Property.create("half"); - public static final Property HALF = Property.create("half"); - public static final Property RAIL_SHAPE = Property.create("shape"); - public static final Property RAIL_SHAPE_STRAIGHT = Property.create("shape"); - public static final Property AGE_1 = Property.create("age"); - public static final Property AGE_2 = Property.create("age"); - public static final Property AGE_3 = Property.create("age"); - public static final Property AGE_4 = Property.create("age"); - public static final Property AGE_5 = Property.create("age"); - public static final Property AGE_7 = Property.create("age"); - public static final Property AGE_15 = Property.create("age"); - public static final Property AGE_25 = Property.create("age"); - public static final Property BITES = Property.create("bites"); - public static final Property CANDLES = Property.create("candles"); - public static final Property DELAY = Property.create("delay"); - public static final Property DISTANCE = Property.create("distance"); - public static final Property EGGS = Property.create("eggs"); - public static final Property HATCH = Property.create("hatch"); - public static final Property LAYERS = Property.create("layers"); - public static final Property LEVEL_CAULDRON = Property.create("level"); - public static final Property LEVEL_COMPOSTER = Property.create("level"); - public static final Property LEVEL_FLOWING = Property.create("level"); - public static final Property LEVEL_HONEY = Property.create("honey_level"); - public static final Property LEVEL = Property.create("level"); - public static final Property MOISTURE = Property.create("moisture"); - public static final Property NOTE = Property.create("note"); - public static final Property PICKLES = Property.create("pickles"); - public static final Property POWER = Property.create("power"); - public static final Property STAGE = Property.create("stage"); - public static final Property STABILITY_DISTANCE = Property.create("distance"); - public static final Property RESPAWN_ANCHOR_CHARGES = Property.create("charges"); - public static final Property ROTATION_16 = Property.create("rotation"); - public static final Property BED_PART = Property.create("part"); - public static final Property CHEST_TYPE = Property.create("type"); - public static final Property MODE_COMPARATOR = Property.create("mode"); - public static final Property DOOR_HINGE = Property.create("hinge"); - public static final Property NOTEBLOCK_INSTRUMENT = Property.create("instrument"); - public static final Property PISTON_TYPE = Property.create("type"); - public static final Property SLAB_TYPE = Property.create("type"); - public static final Property STAIRS_SHAPE = Property.create("shape"); - public static final Property STRUCTUREBLOCK_MODE = Property.create("mode"); - public static final Property BAMBOO_LEAVES = Property.create("leaves"); - public static final Property TILT = Property.create("tilt"); - public static final Property VERTICAL_DIRECTION = Property.create("vertical_direction"); - public static final Property DRIPSTONE_THICKNESS = Property.create("thickness"); - public static final Property SCULK_SENSOR_PHASE = Property.create("sculk_sensor_phase"); - public static final Property CHISELED_BOOKSHELF_SLOT_0_OCCUPIED = Property.create("slot_0_occupied"); - public static final Property CHISELED_BOOKSHELF_SLOT_1_OCCUPIED = Property.create("slot_1_occupied"); - public static final Property CHISELED_BOOKSHELF_SLOT_2_OCCUPIED = Property.create("slot_2_occupied"); - public static final Property CHISELED_BOOKSHELF_SLOT_3_OCCUPIED = Property.create("slot_3_occupied"); - public static final Property CHISELED_BOOKSHELF_SLOT_4_OCCUPIED = Property.create("slot_4_occupied"); - public static final Property CHISELED_BOOKSHELF_SLOT_5_OCCUPIED = Property.create("slot_5_occupied"); - public static final Property DUSTED = Property.create("dusted"); - public static final Property CRACKED = Property.create("cracked"); - public static final Property CRAFTING = Property.create("crafting"); - public static final Property TRIAL_SPAWNER_STATE = Property.create("trial_spawner_state"); - public static final Property VAULT_STATE = Property.create("vault_state"); - public static final Property OMINOUS = Property.create("ominous"); + public static final BooleanProperty ATTACHED = BooleanProperty.create("attached"); + public static final BooleanProperty BOTTOM = BooleanProperty.create("bottom"); + public static final BooleanProperty CONDITIONAL = BooleanProperty.create("conditional"); + public static final BooleanProperty DISARMED = BooleanProperty.create("disarmed"); + public static final BooleanProperty DRAG = BooleanProperty.create("drag"); + public static final BooleanProperty ENABLED = BooleanProperty.create("enabled"); + public static final BooleanProperty EXTENDED = BooleanProperty.create("extended"); + public static final BooleanProperty EYE = BooleanProperty.create("eye"); + public static final BooleanProperty FALLING = BooleanProperty.create("falling"); + public static final BooleanProperty HANGING = BooleanProperty.create("hanging"); + public static final BooleanProperty HAS_BOTTLE_0 = BooleanProperty.create("has_bottle_0"); + public static final BooleanProperty HAS_BOTTLE_1 = BooleanProperty.create("has_bottle_1"); + public static final BooleanProperty HAS_BOTTLE_2 = BooleanProperty.create("has_bottle_2"); + public static final BooleanProperty HAS_RECORD = BooleanProperty.create("has_record"); + public static final BooleanProperty HAS_BOOK = BooleanProperty.create("has_book"); + public static final BooleanProperty INVERTED = BooleanProperty.create("inverted"); + public static final BooleanProperty IN_WALL = BooleanProperty.create("in_wall"); + public static final BooleanProperty LIT = BooleanProperty.create("lit"); + public static final BooleanProperty LOCKED = BooleanProperty.create("locked"); + public static final BooleanProperty OCCUPIED = BooleanProperty.create("occupied"); + public static final BooleanProperty OPEN = BooleanProperty.create("open"); + public static final BooleanProperty PERSISTENT = BooleanProperty.create("persistent"); + public static final BooleanProperty POWERED = BooleanProperty.create("powered"); + public static final BooleanProperty SHORT = BooleanProperty.create("short"); + public static final BooleanProperty SIGNAL_FIRE = BooleanProperty.create("signal_fire"); + public static final BooleanProperty SNOWY = BooleanProperty.create("snowy"); + public static final BooleanProperty TRIGGERED = BooleanProperty.create("triggered"); + public static final BooleanProperty UNSTABLE = BooleanProperty.create("unstable"); + public static final BooleanProperty WATERLOGGED = BooleanProperty.create("waterlogged"); + public static final BooleanProperty BERRIES = BooleanProperty.create("berries"); + public static final BooleanProperty BLOOM = BooleanProperty.create("bloom"); + public static final BooleanProperty SHRIEKING = BooleanProperty.create("shrieking"); + public static final BooleanProperty CAN_SUMMON = BooleanProperty.create("can_summon"); + public static final EnumProperty HORIZONTAL_AXIS = EnumProperty.create("axis", Axis.X, Axis.Z); + public static final EnumProperty AXIS = EnumProperty.create("axis", Axis.VALUES); + public static final BooleanProperty UP = BooleanProperty.create("up"); + public static final BooleanProperty DOWN = BooleanProperty.create("down"); + public static final BooleanProperty NORTH = BooleanProperty.create("north"); + public static final BooleanProperty EAST = BooleanProperty.create("east"); + public static final BooleanProperty SOUTH = BooleanProperty.create("south"); + public static final BooleanProperty WEST = BooleanProperty.create("west"); + public static final EnumProperty FACING = EnumProperty.create("facing", Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN); + public static final EnumProperty FACING_HOPPER = EnumProperty.create("facing", Direction.DOWN, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST); + public static final EnumProperty HORIZONTAL_FACING = EnumProperty.create("facing", Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST); + public static final IntegerProperty FLOWER_AMOUNT = IntegerProperty.create("flower_amount", 1, 4); + public static final EnumProperty ORIENTATION = EnumProperty.create("orientation", FrontAndTop.VALUES); + public static final BasicEnumProperty ATTACH_FACE = BasicEnumProperty.create("face", "floor", "wall", "ceiling"); + public static final BasicEnumProperty BELL_ATTACHMENT = BasicEnumProperty.create("attachment", "floor", "ceiling", "single_wall", "double_wall"); + public static final BasicEnumProperty EAST_WALL = BasicEnumProperty.create("east", "none", "low", "tall"); + public static final BasicEnumProperty NORTH_WALL = BasicEnumProperty.create("north", "none", "low", "tall"); + public static final BasicEnumProperty SOUTH_WALL = BasicEnumProperty.create("south", "none", "low", "tall"); + public static final BasicEnumProperty WEST_WALL = BasicEnumProperty.create("west", "none", "low", "tall"); + public static final BasicEnumProperty EAST_REDSTONE = BasicEnumProperty.create("east", "up", "side", "none"); + public static final BasicEnumProperty NORTH_REDSTONE = BasicEnumProperty.create("north", "up", "side", "none"); + public static final BasicEnumProperty SOUTH_REDSTONE = BasicEnumProperty.create("south", "up", "side", "none"); + public static final BasicEnumProperty WEST_REDSTONE = BasicEnumProperty.create("west", "up", "side", "none"); + public static final BasicEnumProperty DOUBLE_BLOCK_HALF = BasicEnumProperty.create("half", "upper", "lower"); + public static final BasicEnumProperty HALF = BasicEnumProperty.create("half", "top", "bottom"); + public static final BasicEnumProperty RAIL_SHAPE = BasicEnumProperty.create("shape", "north_south", "east_west", "ascending_east", "ascending_west", "ascending_north", "ascending_south", "south_east", "south_west", "north_west", "north_east"); + public static final BasicEnumProperty RAIL_SHAPE_STRAIGHT = BasicEnumProperty.create("shape", "north_south", "east_west", "ascending_east", "ascending_west", "ascending_north", "ascending_south"); + public static final IntegerProperty AGE_1 = IntegerProperty.create("age", 0, 1); + public static final IntegerProperty AGE_2 = IntegerProperty.create("age", 0, 2); + public static final IntegerProperty AGE_3 = IntegerProperty.create("age", 0, 3); + public static final IntegerProperty AGE_4 = IntegerProperty.create("age", 0, 4); + public static final IntegerProperty AGE_5 = IntegerProperty.create("age", 0, 5); + public static final IntegerProperty AGE_7 = IntegerProperty.create("age", 0, 7); + public static final IntegerProperty AGE_15 = IntegerProperty.create("age", 0, 15); + public static final IntegerProperty AGE_25 = IntegerProperty.create("age", 0, 25); + public static final IntegerProperty BITES = IntegerProperty.create("bites", 0, 6); + public static final IntegerProperty CANDLES = IntegerProperty.create("candles", 1, 4); + public static final IntegerProperty DELAY = IntegerProperty.create("delay", 1, 4); + public static final IntegerProperty DISTANCE = IntegerProperty.create("distance", 1, 7); + public static final IntegerProperty EGGS = IntegerProperty.create("eggs", 1, 4); + public static final IntegerProperty HATCH = IntegerProperty.create("hatch", 0, 2); + public static final IntegerProperty LAYERS = IntegerProperty.create("layers", 1, 8); + public static final IntegerProperty LEVEL_CAULDRON = IntegerProperty.create("level", 1, 3); + public static final IntegerProperty LEVEL_COMPOSTER = IntegerProperty.create("level", 0, 8); + public static final IntegerProperty LEVEL_FLOWING = IntegerProperty.create("level", 1, 8); + public static final IntegerProperty LEVEL_HONEY = IntegerProperty.create("honey_level", 0, 5); + public static final IntegerProperty LEVEL = IntegerProperty.create("level", 0, 15); + public static final IntegerProperty MOISTURE = IntegerProperty.create("moisture", 0, 7); + public static final IntegerProperty NOTE = IntegerProperty.create("note", 0, 24); + public static final IntegerProperty PICKLES = IntegerProperty.create("pickles", 1, 4); + public static final IntegerProperty POWER = IntegerProperty.create("power", 0, 15); + public static final IntegerProperty STAGE = IntegerProperty.create("stage", 0, 1); + public static final IntegerProperty STABILITY_DISTANCE = IntegerProperty.create("distance", 0, 7); + public static final IntegerProperty RESPAWN_ANCHOR_CHARGES = IntegerProperty.create("charges", 0, 4); + public static final IntegerProperty ROTATION_16 = IntegerProperty.create("rotation", 0, 15); + public static final BasicEnumProperty BED_PART = BasicEnumProperty.create("part", "head", "foot"); + public static final EnumProperty CHEST_TYPE = EnumProperty.create("type", ChestType.VALUES); + public static final BasicEnumProperty MODE_COMPARATOR = BasicEnumProperty.create("mode", "compare", "subtract"); + public static final BasicEnumProperty DOOR_HINGE = BasicEnumProperty.create("hinge", "left", "right"); + public static final BasicEnumProperty NOTEBLOCK_INSTRUMENT = BasicEnumProperty.create("instrument", "harp", "basedrum", "snare", "hat", "bass", "flute", "bell", "guitar", "chime", "xylophone", "iron_xylophone", "cow_bell", "didgeridoo", "bit", "banjo", "pling", "zombie", "skeleton", "creeper", "dragon", "wither_skeleton", "piglin", "custom_head"); + public static final BasicEnumProperty PISTON_TYPE = BasicEnumProperty.create("type", "normal", "sticky"); + public static final BasicEnumProperty SLAB_TYPE = BasicEnumProperty.create("type", "top", "bottom", "double"); + public static final BasicEnumProperty STAIRS_SHAPE = BasicEnumProperty.create("shape", "straight", "inner_left", "inner_right", "outer_left", "outer_right"); + public static final BasicEnumProperty STRUCTUREBLOCK_MODE = BasicEnumProperty.create("mode", "save", "load", "corner", "data"); + public static final BasicEnumProperty BAMBOO_LEAVES = BasicEnumProperty.create("leaves", "none", "small", "large"); + public static final BasicEnumProperty TILT = BasicEnumProperty.create("tilt", "none", "unstable", "partial", "full"); + public static final EnumProperty VERTICAL_DIRECTION = EnumProperty.create("vertical_direction", Direction.UP, Direction.DOWN); + public static final BasicEnumProperty DRIPSTONE_THICKNESS = BasicEnumProperty.create("thickness", "tip_merge", "tip", "frustum", "middle", "base"); + public static final BasicEnumProperty SCULK_SENSOR_PHASE = BasicEnumProperty.create("sculk_sensor_phase", "inactive", "active", "cooldown"); + public static final BooleanProperty CHISELED_BOOKSHELF_SLOT_0_OCCUPIED = BooleanProperty.create("slot_0_occupied"); + public static final BooleanProperty CHISELED_BOOKSHELF_SLOT_1_OCCUPIED = BooleanProperty.create("slot_1_occupied"); + public static final BooleanProperty CHISELED_BOOKSHELF_SLOT_2_OCCUPIED = BooleanProperty.create("slot_2_occupied"); + public static final BooleanProperty CHISELED_BOOKSHELF_SLOT_3_OCCUPIED = BooleanProperty.create("slot_3_occupied"); + public static final BooleanProperty CHISELED_BOOKSHELF_SLOT_4_OCCUPIED = BooleanProperty.create("slot_4_occupied"); + public static final BooleanProperty CHISELED_BOOKSHELF_SLOT_5_OCCUPIED = BooleanProperty.create("slot_5_occupied"); + public static final IntegerProperty DUSTED = IntegerProperty.create("dusted", 0, 3); + public static final BooleanProperty CRACKED = BooleanProperty.create("cracked"); + public static final BooleanProperty CRAFTING = BooleanProperty.create("crafting"); + public static final BasicEnumProperty TRIAL_SPAWNER_STATE = BasicEnumProperty.create("trial_spawner_state", "inactive", "waiting_for_players", "active", "waiting_for_reward_ejection", "ejecting_reward", "cooldown"); + public static final BasicEnumProperty VAULT_STATE = BasicEnumProperty.create("vault_state", "inactive", "active", "unlocking", "ejecting"); + public static final BooleanProperty OMINOUS = BooleanProperty.create("ominous"); } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/property/Property.java b/core/src/main/java/org/geysermc/geyser/level/block/property/Property.java index ca5f62daa..0c4713124 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/property/Property.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/property/Property.java @@ -25,10 +25,10 @@ package org.geysermc.geyser.level.block.property; -public class Property> { +public abstract class Property> { private final String name; - public Property(String name) { + protected Property(String name) { this.name = name; } @@ -36,12 +36,12 @@ public class Property> { return name; } + public abstract int valuesCount(); + + public abstract int indexOf(T value); + @Override public String toString() { return getClass().getSimpleName() + "[" + name + "]"; } - - public static > Property create(String name) { - return new Property<>(name); - } } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java b/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java index b31c9aeb5..9fe70c0f1 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java @@ -27,9 +27,6 @@ package org.geysermc.geyser.level.block.type; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; -import it.unimi.dsi.fastutil.objects.Reference2ObjectArrayMap; -import it.unimi.dsi.fastutil.objects.Reference2ObjectMap; -import it.unimi.dsi.fastutil.objects.Reference2ObjectMaps; import net.kyori.adventure.key.Key; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3i; @@ -37,6 +34,8 @@ import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.level.block.Blocks; +import org.geysermc.geyser.level.block.property.BasicEnumProperty; +import org.geysermc.geyser.level.block.property.IntegerProperty; import org.geysermc.geyser.level.block.property.Property; import org.geysermc.geyser.level.physics.PistonBehavior; import org.geysermc.geyser.registry.BlockRegistries; @@ -67,6 +66,12 @@ public class Block { protected Item item = null; private int javaId = -1; + /** + * Used for switching a given block state to different states. + */ + private final Property[] propertyKeys; + private final BlockState defaultState; + public Block(@Subst("empty") String javaIdentifier, Builder builder) { this.javaIdentifier = Key.key(javaIdentifier); this.requiresCorrectToolForDrops = builder.requiresCorrectToolForDrops; @@ -74,7 +79,10 @@ public class Block { this.destroyTime = builder.destroyTime; this.pushReaction = builder.pushReaction; this.pickItem = builder.pickItem; - processStates(builder.build(this)); + + BlockState firstState = builder.build(this).get(0); + this.propertyKeys = builder.propertyKeys; // Ensure this is not null before iterating over states + this.defaultState = setDefaultState(firstState); } public void updateBlock(GeyserSession session, BlockState state, Vector3i position) { @@ -167,9 +175,11 @@ public class Block { } /** - * A list of BlockStates is created pertaining to this block. Do we need any of them? If so, override this method. + * Should only be ran on block creation. Can be overridden. + * @param firstState the first state created from this block */ - protected void processStates(List states) { + protected BlockState setDefaultState(BlockState firstState) { + return firstState; } @NonNull @@ -194,6 +204,10 @@ public class Block { return this.pushReaction; } + public BlockState defaultBlockState() { + return this.defaultState; + } + public int javaId() { return javaId; } @@ -213,6 +227,10 @@ public class Block { '}'; } + Property[] propertyKeys() { + return propertyKeys; + } + public static Builder builder() { return new Builder(); } @@ -225,11 +243,14 @@ public class Block { private float destroyTime; private Supplier pickItem; + // We'll use this field after building + private Property[] propertyKeys; + /** * For states that we're just tracking for mirroring Java states. */ - public Builder enumState(Property property, String... values) { - states.put(property, List.of(values)); + public Builder enumState(BasicEnumProperty property) { + states.put(property, property.values()); return this; } @@ -244,7 +265,9 @@ public class Block { return this; } - public Builder intState(Property property, int low, int high) { + public Builder intState(IntegerProperty property) { + int low = property.low(); + int high = property.high(); IntList list = new IntArrayList(); // There is a state for every number between the low and high. for (int i = low; i <= high; i++) { @@ -283,17 +306,18 @@ public class Block { if (states.isEmpty()) { BlockState state = new BlockState(block, BlockRegistries.BLOCK_STATES.get().size()); BlockRegistries.BLOCK_STATES.get().add(state); + propertyKeys = null; return List.of(state); } else if (states.size() == 1) { // We can optimize because we don't need to worry about combinations Map.Entry, List>> property = this.states.entrySet().stream().findFirst().orElseThrow(); List states = new ArrayList<>(property.getValue().size()); property.getValue().forEach(value -> { - Reference2ObjectMap, Comparable> propertyMap = Reference2ObjectMaps.singleton(property.getKey(), value); - BlockState state = new BlockState(block, BlockRegistries.BLOCK_STATES.get().size(), propertyMap); + BlockState state = new BlockState(block, BlockRegistries.BLOCK_STATES.get().size(), new Comparable[] {value}); BlockRegistries.BLOCK_STATES.get().add(state); states.add(state); }); + this.propertyKeys = new Property[]{property.getKey()}; return states; } else { // Think of this stream as another list containing, at the start, one empty list. @@ -327,11 +351,11 @@ public class Block { Property[] keys = this.states.keySet().toArray(new Property[0]); result.forEach(properties -> { Comparable[] values = properties.toArray(new Comparable[0]); - Reference2ObjectMap, Comparable> propertyMap = new Reference2ObjectArrayMap<>(keys, values); - BlockState state = new BlockState(block, BlockRegistries.BLOCK_STATES.get().size(), propertyMap); + BlockState state = new BlockState(block, BlockRegistries.BLOCK_STATES.get().size(), values); BlockRegistries.BLOCK_STATES.get().add(state); states.add(state); }); + this.propertyKeys = keys; return states; } } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java b/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java index 4fed30e7a..44271bd80 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java @@ -25,8 +25,7 @@ package org.geysermc.geyser.level.block.type; -import it.unimi.dsi.fastutil.objects.Reference2ObjectMap; -import it.unimi.dsi.fastutil.objects.Reference2ObjectMaps; +import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.level.block.property.Property; import org.geysermc.geyser.registry.BlockRegistries; @@ -35,13 +34,18 @@ import java.util.Locale; public final class BlockState { private final Block block; private final int javaId; - private final Reference2ObjectMap, Comparable> states; + /** + * The values of each property of this block state. These should be treated as keys to {@link Block#propertyKeys()} + * Of note - the comparable part probably doesn't do anything because we occasionally use strings in place of enums. + * Will be null if there's only one block state for a block. + */ + private final Comparable[] states; public BlockState(Block block, int javaId) { - this(block, javaId, Reference2ObjectMaps.emptyMap()); + this(block, javaId, null); } - BlockState(Block block, int javaId, Reference2ObjectMap, Comparable> states) { + BlockState(Block block, int javaId, Comparable[] states) { this.block = block; this.javaId = javaId; this.states = states; @@ -49,23 +53,97 @@ public final class BlockState { public > T getValue(Property property) { //noinspection unchecked - return (T) states.get(property); + return (T) get(property); } public boolean getValue(Property property, boolean def) { - var value = states.get(property); + var value = get(property); if (value == null) { return def; } return (Boolean) value; } + @Nullable + private Comparable get(Property property) { + Property[] keys = this.block.propertyKeys(); + if (keys == null) { + return null; + } + // We're copying the behavior Reference2ObjectArrayMap uses + for (int i = keys.length; i-- != 0;) { + if (keys[i] == property) { + return this.states[i]; + } + } + return null; + } + + /** + * @return the {@link BlockState} instance with the given value. + */ + public > BlockState withValue(Property property, T value) { + Property[] keys = this.block.propertyKeys(); + if (keys == null) { + throw new IllegalStateException(this + " does not have any different states!"); + } + + T currentValue = getValue(property); + if (currentValue == null) { + throw new IllegalArgumentException("This BlockState does not have the property " + property); + } + if (currentValue.equals(value)) { + // No action required. This block state is the state we're looking for. + return this; + } + + // Diff is how much we will have to traverse as a sort of offset + + // Block states are calculated in a predictable structure: + // minecraft:cobblestone_wall[east=none,north=none,south=none,up=true,waterlogged=true,west=none] + // minecraft:cobblestone_wall[east=none,north=none,south=none,up=true,waterlogged=true,west=low] + // minecraft:cobblestone_wall[east=none,north=none,south=none,up=true,waterlogged=true,west=tall] + // minecraft:cobblestone_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=none] + // minecraft:cobblestone_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=low] + // minecraft:cobblestone_wall[east=none,north=none,south=none,up=true,waterlogged=false,west=tall] + // minecraft:cobblestone_wall[east=none,north=none,south=none,up=false,waterlogged=true,west=none] + + // The last value goes through all its iterations, then the next state goes through all its iterations. + // West goes none -> low -> tall, then waterlogged is toggled as west cycles again. + // Then when waterlogged goes through all its properties, up is toggled, and west goes through again + // If we want to find the "up" property in order, then we need to find how many iterations each property + // after it goes in. West goes for 3, waterlogged goes for 2. Adding those together, we find that we need to + // add five to get to the next toggle of the up property + int diff = 0; + for (int i = keys.length - 1; i >= 0; i--) { + if (keys[i] != property) { + diff += keys[i].valuesCount(); + } else { + break; + } + } + + // How many times do we have to jump by diff? This depends on how far away each value is from each other. + // piston_head[facing=north] might be right next to piston_head[facing=south], which just one diff'd hop. + // But piston_head[facing=west] is further away, requiring more hops. + int thatOffset = property.indexOf(value); + int thisOffset = property.indexOf(currentValue); + if (diff == 0) { + // This can happen if the property is at the tail end of the block and there are no other properties to look through + // If we have minecraft:cobblestone_wall[east=none,north=none,south=none,up=true,waterlogged=true,west=none] + // And want minecraft:cobblestone_wall[east=none,north=none,south=none,up=true,waterlogged=true,west=low] + // The above for loop will always stop at the first break because the last property has already been found + diff = 1; + } + return BlockState.of(this.javaId + ((thatOffset - thisOffset) * diff)); + } + public Block block() { - return block; + return this.block; } public int javaId() { - return javaId; + return this.javaId; } public boolean is(Block block) { @@ -74,7 +152,7 @@ public final class BlockState { @Override public String toString() { - if (this.states.isEmpty()) { + if (this.states == null) { return this.block.javaIdentifier().toString(); } return this.block.javaIdentifier().toString() + "[" + paramsToString() + "]"; @@ -82,14 +160,15 @@ public final class BlockState { private String paramsToString() { StringBuilder builder = new StringBuilder(); - var it = this.states.entrySet().iterator(); - while (it.hasNext()) { - var entry = it.next(); - builder.append(entry.getKey().name()) - .append("=") - .append(entry.getValue().toString().toLowerCase(Locale.ROOT)); // lowercase covers enums - if (it.hasNext()) { - builder.append(","); + Property[] propertyKeys = this.block.propertyKeys(); + if (propertyKeys != null) { + for (int i = 0; i < propertyKeys.length; i++) { + builder.append(propertyKeys[i].name()) + .append("=") + .append(this.states[i].toString().toLowerCase(Locale.ROOT)); // lowercase covers enums + if (i < propertyKeys.length - 1) { + builder.append(","); + } } } return builder.toString(); diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/FurnaceBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/FurnaceBlock.java index 2b898e089..25d54ff2d 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/FurnaceBlock.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/FurnaceBlock.java @@ -28,29 +28,14 @@ package org.geysermc.geyser.level.block.type; import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.physics.Direction; -import java.util.List; - public class FurnaceBlock extends Block { - private static BlockState LIT; - private static BlockState UNLIT; - public FurnaceBlock(String javaIdentifier, Builder builder) { super(javaIdentifier, builder); } @Override - protected void processStates(List states) { - LIT = states.stream() - .filter(state -> state.getValue(Properties.HORIZONTAL_FACING) == Direction.NORTH - && state.getValue(Properties.LIT)) - .findFirst().orElseThrow(); - UNLIT = states.stream() - .filter(state -> state.getValue(Properties.HORIZONTAL_FACING) == Direction.NORTH - && !state.getValue(Properties.LIT)) - .findFirst().orElseThrow(); - } - - public static BlockState state(boolean lit) { - return lit ? LIT : UNLIT; + protected BlockState setDefaultState(BlockState firstState) { + // Both furnace minecart states look north. + return firstState.withValue(Properties.HORIZONTAL_FACING, Direction.NORTH); } } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/HoneyBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/HoneyBlock.java index 73c4d02aa..642240915 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/HoneyBlock.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/HoneyBlock.java @@ -25,21 +25,8 @@ package org.geysermc.geyser.level.block.type; -import java.util.List; - public class HoneyBlock extends Block { - private static BlockState STATE; - public HoneyBlock(String javaIdentifier, Builder builder) { super(javaIdentifier, builder); } - - @Override - protected void processStates(List states) { - STATE = states.get(0); - } - - public static BlockState state() { - return STATE; - } } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/SpawnerBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/SpawnerBlock.java index 2103fe6e5..968499d11 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/SpawnerBlock.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/SpawnerBlock.java @@ -25,21 +25,8 @@ package org.geysermc.geyser.level.block.type; -import java.util.List; - public class SpawnerBlock extends Block { - private static BlockState STATE; - public SpawnerBlock(String javaIdentifier, Builder builder) { super(javaIdentifier, builder); } - - @Override - protected void processStates(List states) { - STATE = states.get(0); - } - - public static BlockState state() { - return STATE; - } } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/WaterBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/WaterBlock.java index 801a7f9e7..9d2d23116 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/WaterBlock.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/WaterBlock.java @@ -25,17 +25,8 @@ package org.geysermc.geyser.level.block.type; -import java.util.List; - public class WaterBlock extends Block { - private static BlockState LEVEL_0; - public WaterBlock(String javaIdentifier, Builder builder) { super(javaIdentifier, builder); } - - @Override - protected void processStates(List states) { - super.processStates(states); - } } diff --git a/core/src/main/java/org/geysermc/geyser/level/physics/CollisionManager.java b/core/src/main/java/org/geysermc/geyser/level/physics/CollisionManager.java index ce89689eb..2be4e7a38 100644 --- a/core/src/main/java/org/geysermc/geyser/level/physics/CollisionManager.java +++ b/core/src/main/java/org/geysermc/geyser/level/physics/CollisionManager.java @@ -39,6 +39,9 @@ import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.player.PlayerEntity; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.Blocks; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.PistonCache; import org.geysermc.geyser.translator.collision.BlockCollision; @@ -405,7 +408,8 @@ public class CollisionManager { * @return if the player is currently in a water block */ public boolean isPlayerInWater() { - return session.getGeyser().getWorldManager().getBlockAt(session, session.getPlayerEntity().getPosition().toInt()) == BlockStateValues.JAVA_WATER_ID; + BlockState state = session.getGeyser().getWorldManager().blockAt(session, session.getPlayerEntity().getPosition().toInt()); + return state.is(Blocks.WATER) && state.getValue(Properties.LEVEL) == 0; } public boolean isWaterInEyes() { diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java index 1d40386d4..6eadbd0e5 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java @@ -50,7 +50,6 @@ import org.geysermc.geyser.api.block.custom.CustomBlockData; import org.geysermc.geyser.api.block.custom.CustomBlockState; import org.geysermc.geyser.api.block.custom.nonvanilla.JavaBlockState; import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.type.Block; @@ -433,25 +432,13 @@ public final class BlockRegistryPopulator { } int javaRuntimeId = -1; - int waterRuntimeId = -1; for (BlockState javaBlockState : BlockRegistries.BLOCK_STATES.get()) { javaRuntimeId++; String javaId = javaBlockState.toString().intern(); - BlockStateValues.storeBlockStateValues(javaId, javaRuntimeId); - BlockRegistries.JAVA_IDENTIFIER_TO_ID.register(javaId, javaRuntimeId); - - if ("minecraft:water[level=0]".equals(javaId)) { - waterRuntimeId = javaRuntimeId; - } } - if (waterRuntimeId == -1) { - throw new AssertionError("Unable to find Java water in palette"); - } - BlockStateValues.JAVA_WATER_ID = waterRuntimeId; - if (!BlockRegistries.NON_VANILLA_BLOCK_STATE_OVERRIDES.get().isEmpty()) { IntSet usedNonVanillaRuntimeIDs = new IntOpenHashSet(); diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java b/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java index f618fde46..5c4e835e4 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java +++ b/core/src/main/java/org/geysermc/geyser/registry/type/BlockMappings.java @@ -90,6 +90,10 @@ public class BlockMappings implements DefinitionRegistry { return this.getBedrockBlock(javaState.javaId()); } + public GeyserBedrockBlock getVanillaBedrockBlock(BlockState javaState) { + return getVanillaBedrockBlock(javaState.javaId()); + } + public GeyserBedrockBlock getVanillaBedrockBlock(int javaState) { if (javaState < 0 || javaState >= this.javaToVanillaBedrockBlocks.length) { return bedrockAir; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/AbstractBlockInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/AbstractBlockInventoryTranslator.java index 2dfa2a85a..4476391c8 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/AbstractBlockInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/AbstractBlockInventoryTranslator.java @@ -31,6 +31,7 @@ import org.geysermc.geyser.inventory.holder.BlockInventoryHolder; import org.geysermc.geyser.inventory.holder.InventoryHolder; import org.geysermc.geyser.inventory.updater.InventoryUpdater; import org.geysermc.geyser.level.block.type.Block; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; /** @@ -40,17 +41,25 @@ public abstract class AbstractBlockInventoryTranslator extends BaseInventoryTran private final InventoryHolder holder; private final InventoryUpdater updater; + /** + * @param javaBlock a Java block that is used as a temporary block + */ + public AbstractBlockInventoryTranslator(int size, Block javaBlock, ContainerType containerType, InventoryUpdater updater, + Block... additionalValidBlocks) { + this(size, javaBlock.defaultBlockState(), containerType, updater, additionalValidBlocks); + } + /** * @param size the amount of slots that the inventory adds alongside the base inventory slots - * @param javaBlockIdentifier a Java block identifier that is used as a temporary block + * @param javaBlockState a Java block state that is used as a temporary block * @param containerType the container type of this inventory * @param updater updater * @param additionalValidBlocks any other blocks that can safely use this inventory without a fake block */ - public AbstractBlockInventoryTranslator(int size, String javaBlockIdentifier, ContainerType containerType, InventoryUpdater updater, + public AbstractBlockInventoryTranslator(int size, BlockState javaBlockState, ContainerType containerType, InventoryUpdater updater, Block... additionalValidBlocks) { super(size); - this.holder = new BlockInventoryHolder(javaBlockIdentifier, containerType, additionalValidBlocks); + this.holder = new BlockInventoryHolder(javaBlockState, containerType, additionalValidBlocks); this.updater = updater; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/AnvilInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/AnvilInventoryTranslator.java index 705fac362..40ee28362 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/AnvilInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/AnvilInventoryTranslator.java @@ -45,7 +45,7 @@ import java.util.Objects; public class AnvilInventoryTranslator extends AbstractBlockInventoryTranslator { public AnvilInventoryTranslator() { - super(3, "minecraft:anvil[facing=north]", org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.ANVIL, AnvilInventoryUpdater.INSTANCE, + super(3, Blocks.ANVIL, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.ANVIL, AnvilInventoryUpdater.INSTANCE, Blocks.CHIPPED_ANVIL, Blocks.DAMAGED_ANVIL); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/BeaconInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/BeaconInventoryTranslator.java index 9aeeff007..ceae1b640 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/BeaconInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/BeaconInventoryTranslator.java @@ -27,7 +27,6 @@ package org.geysermc.geyser.translator.inventory; import it.unimi.dsi.fastutil.ints.IntSets; import org.cloudburstmc.math.vector.Vector3i; -import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequest; @@ -43,7 +42,9 @@ import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.PlayerInventory; import org.geysermc.geyser.inventory.holder.BlockInventoryHolder; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator; import org.geysermc.geyser.util.InventoryUtils; import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSetBeaconPacket; @@ -52,7 +53,7 @@ import java.util.OptionalInt; public class BeaconInventoryTranslator extends AbstractBlockInventoryTranslator { public BeaconInventoryTranslator() { - super(1, new BlockInventoryHolder("minecraft:beacon", org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.BEACON) { + super(1, new BlockInventoryHolder(Blocks.BEACON, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.BEACON) { @Override protected boolean checkInteractionPosition(GeyserSession session) { // Since we can't fall back to a virtual inventory, let's make opening one easier @@ -89,12 +90,8 @@ public class BeaconInventoryTranslator extends AbstractBlockInventoryTranslator // Send a block entity data packet update to the fake beacon inventory Vector3i position = inventory.getHolderPosition(); - NbtMapBuilder builder = NbtMap.builder() - .putInt("x", position.getX()) - .putInt("y", position.getY()) - .putInt("z", position.getZ()) + NbtMapBuilder builder = BlockEntityTranslator.getConstantBedrockTag("Beacon", position) .putString("CustomName", inventory.getTitle()) - .putString("id", "Beacon") .putInt("primary", beaconContainer.getPrimaryId()) .putInt("secondary", beaconContainer.getSecondaryId()); diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/BrewingInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/BrewingInventoryTranslator.java index a2c45384d..e425342f3 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/BrewingInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/BrewingInventoryTranslator.java @@ -32,11 +32,16 @@ import org.cloudburstmc.protocol.bedrock.packet.ContainerSetDataPacket; import org.geysermc.geyser.inventory.BedrockContainerSlot; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater; +import org.geysermc.geyser.level.block.Blocks; +import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.session.GeyserSession; public class BrewingInventoryTranslator extends AbstractBlockInventoryTranslator { public BrewingInventoryTranslator() { - super(5, "minecraft:brewing_stand[has_bottle_0=false,has_bottle_1=false,has_bottle_2=false]", ContainerType.BREWING_STAND, ContainerInventoryUpdater.INSTANCE); + super(5, Blocks.BREWING_STAND.defaultBlockState() + .withValue(Properties.HAS_BOTTLE_0, false) + .withValue(Properties.HAS_BOTTLE_1, false) + .withValue(Properties.HAS_BOTTLE_2, false), ContainerType.BREWING_STAND, ContainerInventoryUpdater.INSTANCE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/CartographyInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/CartographyInventoryTranslator.java index a115bd953..b0914e5dd 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/CartographyInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/CartographyInventoryTranslator.java @@ -30,12 +30,13 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemSt import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; import org.geysermc.geyser.item.Items; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; public class CartographyInventoryTranslator extends AbstractBlockInventoryTranslator { public CartographyInventoryTranslator() { - super(3, "minecraft:cartography_table", org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.CARTOGRAPHY, UIInventoryUpdater.INSTANCE); + super(3, Blocks.CARTOGRAPHY_TABLE, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.CARTOGRAPHY, UIInventoryUpdater.INSTANCE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/CrafterInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/CrafterInventoryTranslator.java index 2a2f5beb5..8b0a0ac44 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/CrafterInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/CrafterInventoryTranslator.java @@ -31,6 +31,7 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData; import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.updater.CrafterInventoryUpdater; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.BlockEntityUtils; import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; @@ -53,7 +54,7 @@ public class CrafterInventoryTranslator extends AbstractBlockInventoryTranslator private static final int TRIGGERED = 1; // triggered value public CrafterInventoryTranslator() { - super(10, "minecraft:crafter", org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.CRAFTER, CrafterInventoryUpdater.INSTANCE); + super(10, Blocks.CRAFTER, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.CRAFTER, CrafterInventoryUpdater.INSTANCE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/CraftingInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/CraftingInventoryTranslator.java index 521db494a..4a0f1d7d9 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/CraftingInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/CraftingInventoryTranslator.java @@ -31,10 +31,11 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemSt import org.geysermc.geyser.inventory.BedrockContainerSlot; import org.geysermc.geyser.inventory.SlotType; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; +import org.geysermc.geyser.level.block.Blocks; public class CraftingInventoryTranslator extends AbstractBlockInventoryTranslator { public CraftingInventoryTranslator() { - super(10, "minecraft:crafting_table", ContainerType.WORKBENCH, UIInventoryUpdater.INSTANCE); + super(10, Blocks.CRAFTING_TABLE, ContainerType.WORKBENCH, UIInventoryUpdater.INSTANCE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/EnchantingInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/EnchantingInventoryTranslator.java index 8fee2a391..e1407346a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/EnchantingInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/EnchantingInventoryTranslator.java @@ -38,6 +38,7 @@ import org.cloudburstmc.protocol.bedrock.packet.PlayerEnchantOptionsPacket; import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.item.Enchantment; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; @@ -47,7 +48,7 @@ import java.util.Locale; public class EnchantingInventoryTranslator extends AbstractBlockInventoryTranslator { public EnchantingInventoryTranslator() { - super(2, "minecraft:enchanting_table", org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.ENCHANTMENT, UIInventoryUpdater.INSTANCE); + super(2, Blocks.ENCHANTING_TABLE, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.ENCHANTMENT, UIInventoryUpdater.INSTANCE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/Generic3X3InventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/Generic3X3InventoryTranslator.java index f47a367d8..80040e375 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/Generic3X3InventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/Generic3X3InventoryTranslator.java @@ -41,7 +41,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; */ public class Generic3X3InventoryTranslator extends AbstractBlockInventoryTranslator { public Generic3X3InventoryTranslator() { - super(9, "minecraft:dispenser[facing=north,triggered=false]", org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.DISPENSER, ContainerInventoryUpdater.INSTANCE, + super(9, Blocks.DISPENSER, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.DISPENSER, ContainerInventoryUpdater.INSTANCE, Blocks.DROPPER); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/GrindstoneInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/GrindstoneInventoryTranslator.java index a32b97b70..5344d27cb 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/GrindstoneInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/GrindstoneInventoryTranslator.java @@ -30,10 +30,11 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData; import org.geysermc.geyser.inventory.BedrockContainerSlot; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; +import org.geysermc.geyser.level.block.Blocks; public class GrindstoneInventoryTranslator extends AbstractBlockInventoryTranslator { public GrindstoneInventoryTranslator() { - super(3, "minecraft:grindstone[face=floor,facing=north]", ContainerType.GRINDSTONE, UIInventoryUpdater.INSTANCE); + super(3, Blocks.GRINDSTONE, ContainerType.GRINDSTONE, UIInventoryUpdater.INSTANCE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/HopperInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/HopperInventoryTranslator.java index dab1ee972..fdcd7bf57 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/HopperInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/HopperInventoryTranslator.java @@ -29,13 +29,14 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; import org.geysermc.geyser.inventory.BedrockContainerSlot; import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater; +import org.geysermc.geyser.level.block.Blocks; /** * Implemented on top of any block that does not have special properties implemented */ public class HopperInventoryTranslator extends AbstractBlockInventoryTranslator { public HopperInventoryTranslator() { - super(5, "minecraft:hopper[enabled=false,facing=down]", ContainerType.HOPPER, ContainerInventoryUpdater.INSTANCE); + super(5, Blocks.HOPPER, ContainerType.HOPPER, ContainerInventoryUpdater.INSTANCE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java index f3bbc9b87..c6c3c7dd6 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java @@ -34,6 +34,7 @@ import org.geysermc.erosion.util.LecternUtils; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.BlockEntityUtils; @@ -56,7 +57,7 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator private boolean initialized = false; public LecternInventoryTranslator() { - super(1, "minecraft:lectern[facing=north,has_book=true,powered=true]", org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.LECTERN , ContainerInventoryUpdater.INSTANCE); + super(1, Blocks.LECTERN, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.LECTERN , ContainerInventoryUpdater.INSTANCE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java index e8571c8fb..0694e2ac6 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java @@ -45,6 +45,7 @@ import org.geysermc.geyser.inventory.SlotType; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; import org.geysermc.geyser.item.type.BannerItem; import org.geysermc.geyser.item.type.DyeItem; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; @@ -101,7 +102,7 @@ public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator { } public LoomInventoryTranslator() { - super(4, "minecraft:loom[facing=north]", ContainerType.LOOM, UIInventoryUpdater.INSTANCE); + super(4, Blocks.LOOM, ContainerType.LOOM, UIInventoryUpdater.INSTANCE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/OldSmithingTableTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/OldSmithingTableTranslator.java index 201c900d6..21fe9ca21 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/OldSmithingTableTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/OldSmithingTableTranslator.java @@ -37,6 +37,7 @@ import org.cloudburstmc.protocol.bedrock.packet.InventorySlotPacket; import org.geysermc.geyser.inventory.BedrockContainerSlot; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InventoryUtils; @@ -53,7 +54,7 @@ public class OldSmithingTableTranslator extends AbstractBlockInventoryTranslator private static final IntFunction UPGRADE_TEMPLATE = InventoryUtils.getUpgradeTemplate(); private OldSmithingTableTranslator() { - super(3, "minecraft:smithing_table", ContainerType.SMITHING_TABLE, UIInventoryUpdater.INSTANCE); + super(3, Blocks.SMITHING_TABLE, ContainerType.SMITHING_TABLE, UIInventoryUpdater.INSTANCE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java index 72f5260a0..464bf07f7 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/ShulkerInventoryTranslator.java @@ -35,7 +35,10 @@ import org.geysermc.geyser.inventory.BedrockContainerSlot; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.holder.BlockInventoryHolder; import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater; +import org.geysermc.geyser.level.block.Blocks; +import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.type.BlockState; +import org.geysermc.geyser.level.physics.Direction; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator; @@ -43,12 +46,13 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType public class ShulkerInventoryTranslator extends AbstractBlockInventoryTranslator { public ShulkerInventoryTranslator() { - super(27, new BlockInventoryHolder("minecraft:shulker_box[facing=north]", ContainerType.CONTAINER) { + // Ensure that the shulker box default state won't be trying to open in a state facing the player + super(27, new BlockInventoryHolder(Blocks.SHULKER_BOX.defaultBlockState().withValue(Properties.FACING, Direction.NORTH), ContainerType.CONTAINER) { private final BlockEntityTranslator shulkerBoxTranslator = Registries.BLOCK_ENTITIES.get(BlockEntityType.SHULKER_BOX); @Override - protected boolean isValidBlock(String[] javaBlockString) { - return javaBlockString[0].contains("shulker_box"); + protected boolean isValidBlock(BlockState blockState) { + return blockState.block().javaIdentifier().value().contains("shulker_box"); // TODO ew } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/SmithingInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/SmithingInventoryTranslator.java index 730e4a451..c68347fd3 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/SmithingInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/SmithingInventoryTranslator.java @@ -30,10 +30,11 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData; import org.geysermc.geyser.inventory.BedrockContainerSlot; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; +import org.geysermc.geyser.level.block.Blocks; public class SmithingInventoryTranslator extends AbstractBlockInventoryTranslator { public SmithingInventoryTranslator() { - super(4, "minecraft:smithing_table", ContainerType.SMITHING_TABLE, UIInventoryUpdater.INSTANCE); + super(4, Blocks.SMITHING_TABLE, ContainerType.SMITHING_TABLE, UIInventoryUpdater.INSTANCE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java index 54f2f447b..b977ee1a1 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java @@ -35,6 +35,7 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.response.ItemS import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.recipe.GeyserStonecutterData; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; @@ -42,7 +43,7 @@ import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.S public class StonecutterInventoryTranslator extends AbstractBlockInventoryTranslator { public StonecutterInventoryTranslator() { - super(2, "minecraft:stonecutter[facing=north]", org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.STONECUTTER, UIInventoryUpdater.INSTANCE); + super(2, Blocks.STONECUTTER, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.STONECUTTER, UIInventoryUpdater.INSTANCE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java index 4c49c8e5a..4bc727397 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java @@ -40,6 +40,7 @@ import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.level.block.property.ChestType; import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.type.BlockState; +import org.geysermc.geyser.level.physics.Direction; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator; @@ -51,7 +52,10 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator { public DoubleChestInventoryTranslator(int size) { super(size, 54); - this.defaultJavaBlockState = BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getInt("minecraft:chest[facing=north,type=single,waterlogged=false]"); + this.defaultJavaBlockState = Blocks.CHEST.defaultBlockState() + .withValue(Properties.HORIZONTAL_FACING, Direction.NORTH) + .withValue(Properties.CHEST_TYPE, ChestType.SINGLE) + .javaId(); } @Override @@ -96,11 +100,7 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator { blockPacket.getFlags().addAll(UpdateBlockPacket.FLAG_ALL_PRIORITY); session.sendUpstreamPacket(blockPacket); - NbtMap tag = NbtMap.builder() - .putString("id", "Chest") - .putInt("x", position.getX()) - .putInt("y", position.getY()) - .putInt("z", position.getZ()) + NbtMap tag = BlockEntityTranslator.getConstantBedrockTag("Chest", position) .putInt("pairx", pairPosition.getX()) .putInt("pairz", pairPosition.getZ()) .putString("CustomName", inventory.getTitle()).build(); diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/SingleChestInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/SingleChestInventoryTranslator.java index e18096862..264b2eb29 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/SingleChestInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/SingleChestInventoryTranslator.java @@ -30,6 +30,9 @@ import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.holder.BlockInventoryHolder; import org.geysermc.geyser.inventory.holder.InventoryHolder; import org.geysermc.geyser.level.block.Blocks; +import org.geysermc.geyser.level.block.property.ChestType; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; public class SingleChestInventoryTranslator extends ChestInventoryTranslator { @@ -38,17 +41,17 @@ public class SingleChestInventoryTranslator extends ChestInventoryTranslator { // TODO add barrel??? public SingleChestInventoryTranslator(int size) { super(size, 27); - this.holder = new BlockInventoryHolder("minecraft:chest[facing=north,type=single,waterlogged=false]", ContainerType.CONTAINER, + this.holder = new BlockInventoryHolder(Blocks.CHEST.defaultBlockState().withValue(Properties.CHEST_TYPE, ChestType.SINGLE), ContainerType.CONTAINER, Blocks.ENDER_CHEST, Blocks.TRAPPED_CHEST) { @Override - protected boolean isValidBlock(String[] javaBlockString) { - if (javaBlockString[0].equals("minecraft:ender_chest")) { + protected boolean isValidBlock(BlockState blockState) { + if (blockState.is(Blocks.ENDER_CHEST)) { // Can't have double ender chests return true; } // Add provision to ensure this isn't a double chest - return super.isValidBlock(javaBlockString) && (javaBlockString.length > 1 && javaBlockString[1].contains("type=single")); + return super.isValidBlock(blockState) && blockState.getValue(Properties.CHEST_TYPE) == ChestType.SINGLE; } }; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/AbstractFurnaceInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/AbstractFurnaceInventoryTranslator.java index 6cda03a19..8991ef787 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/AbstractFurnaceInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/AbstractFurnaceInventoryTranslator.java @@ -32,12 +32,14 @@ import org.geysermc.geyser.inventory.BedrockContainerSlot; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.SlotType; import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.inventory.AbstractBlockInventoryTranslator; public abstract class AbstractFurnaceInventoryTranslator extends AbstractBlockInventoryTranslator { - AbstractFurnaceInventoryTranslator(String javaBlockIdentifier, ContainerType containerType) { - super(3, javaBlockIdentifier, containerType, ContainerInventoryUpdater.INSTANCE); + AbstractFurnaceInventoryTranslator(Block javaBlock, ContainerType containerType) { + super(3, javaBlock.defaultBlockState().withValue(Properties.LIT, false), containerType, ContainerInventoryUpdater.INSTANCE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/BlastFurnaceInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/BlastFurnaceInventoryTranslator.java index 0b6e0c674..185cafc51 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/BlastFurnaceInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/BlastFurnaceInventoryTranslator.java @@ -28,10 +28,11 @@ package org.geysermc.geyser.translator.inventory.furnace; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; import org.geysermc.geyser.inventory.BedrockContainerSlot; +import org.geysermc.geyser.level.block.Blocks; public class BlastFurnaceInventoryTranslator extends AbstractFurnaceInventoryTranslator { public BlastFurnaceInventoryTranslator() { - super("minecraft:blast_furnace[facing=north,lit=false]", ContainerType.BLAST_FURNACE); + super(Blocks.BLAST_FURNACE, ContainerType.BLAST_FURNACE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/FurnaceInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/FurnaceInventoryTranslator.java index 95a79a93e..bc96f7105 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/FurnaceInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/FurnaceInventoryTranslator.java @@ -28,10 +28,11 @@ package org.geysermc.geyser.translator.inventory.furnace; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; import org.geysermc.geyser.inventory.BedrockContainerSlot; +import org.geysermc.geyser.level.block.Blocks; public class FurnaceInventoryTranslator extends AbstractFurnaceInventoryTranslator { public FurnaceInventoryTranslator() { - super("minecraft:furnace[facing=north,lit=false]", ContainerType.FURNACE); + super(Blocks.FURNACE, ContainerType.FURNACE); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/SmokerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/SmokerInventoryTranslator.java index 2f87f3b13..380446f09 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/SmokerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/furnace/SmokerInventoryTranslator.java @@ -28,10 +28,11 @@ package org.geysermc.geyser.translator.inventory.furnace; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; import org.geysermc.geyser.inventory.BedrockContainerSlot; +import org.geysermc.geyser.level.block.Blocks; public class SmokerInventoryTranslator extends AbstractFurnaceInventoryTranslator { public SmokerInventoryTranslator() { - super("minecraft:smoker[facing=north,lit=false]", ContainerType.SMOKER); + super(Blocks.SMOKER, ContainerType.SMOKER); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java index ca8679319..350ce8c3e 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntity.java @@ -26,22 +26,24 @@ package org.geysermc.geyser.translator.level.block.entity; import it.unimi.dsi.fastutil.ints.IntArrays; -import it.unimi.dsi.fastutil.objects.*; -import org.geysermc.geyser.level.block.Blocks; -import org.geysermc.geyser.level.block.type.Block; -import org.geysermc.geyser.level.block.type.BlockState; -import org.geysermc.geyser.level.block.type.HoneyBlock; -import org.geysermc.geyser.level.block.type.PistonBlock; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.PistonValueType; +import it.unimi.dsi.fastutil.objects.Object2ObjectMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectMaps; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import lombok.Getter; import org.cloudburstmc.math.vector.Vector3d; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; -import lombok.Getter; import org.geysermc.geyser.api.util.PlatformType; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.Blocks; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.level.block.type.Block; +import org.geysermc.geyser.level.block.type.BlockState; +import org.geysermc.geyser.level.block.type.PistonBlock; import org.geysermc.geyser.level.physics.Axis; import org.geysermc.geyser.level.physics.BoundingBox; import org.geysermc.geyser.level.physics.CollisionManager; @@ -53,6 +55,7 @@ import org.geysermc.geyser.translator.collision.BlockCollision; import org.geysermc.geyser.util.BlockEntityUtils; import org.geysermc.geyser.util.BlockUtils; import org.geysermc.geyser.util.ChunkUtils; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.PistonValueType; import java.util.LinkedList; import java.util.Map; @@ -99,7 +102,7 @@ public class PistonBlockEntity { static { // Create a ~1 x ~0.5 x ~1 bounding box above the honey block - BlockCollision blockCollision = BlockRegistries.COLLISIONS.get(HoneyBlock.state().javaId()); + BlockCollision blockCollision = BlockRegistries.COLLISIONS.get(Blocks.HONEY_BLOCK.defaultBlockState().javaId()); if (blockCollision == null) { throw new RuntimeException("Failed to find honey block collision"); } @@ -224,10 +227,10 @@ public class PistonBlockEntity { private void removePistonHead() { Vector3i blockInFront = position.add(orientation.getUnitVector()); - int blockId = session.getGeyser().getWorldManager().getBlockAt(session, blockInFront); - if (BlockStateValues.isPistonHead(blockId)) { + BlockState state = session.getGeyser().getWorldManager().blockAt(session, blockInFront); + if (state.is(Blocks.PISTON_HEAD)) { ChunkUtils.updateBlock(session, Block.JAVA_AIR_ID, blockInFront); - } else if ((session.getGeyser().getPlatformType() == PlatformType.SPIGOT || session.getErosionHandler().isActive()) && blockId == Block.JAVA_AIR_ID) { + } else if ((session.getGeyser().getPlatformType() == PlatformType.SPIGOT || session.getErosionHandler().isActive()) && state.is(Blocks.AIR)) { // Spigot removes the piston head from the cache, but we need to send the block update ourselves ChunkUtils.updateBlock(session, Block.JAVA_AIR_ID, blockInFront); } @@ -353,7 +356,9 @@ public class PistonBlockEntity { playerBoundingBox.setSizeZ(playerBoundingBox.getSizeZ() - shrink.getZ()); // Resolve collision with the piston head - BlockState pistonHeadId = BlockState.of(BlockStateValues.getPistonHead(orientation)); + BlockState pistonHeadId = Blocks.PISTON_HEAD.defaultBlockState() + .withValue(Properties.SHORT, false) + .withValue(Properties.FACING, orientation); pushPlayerBlock(pistonHeadId, getPistonHeadPos().toDouble(), blockMovement, playerBoundingBox); // Resolve collision with any attached moving blocks, but skip slime blocks @@ -562,9 +567,11 @@ public class PistonBlockEntity { private BlockState getAttachedBlockId(Vector3i blockPos) { if (blockPos.equals(getPistonHeadPos())) { - return BlockState.of(BlockStateValues.getPistonHead(orientation)); + return Blocks.PISTON_HEAD.defaultBlockState() + .withValue(Properties.SHORT, false) + .withValue(Properties.FACING, orientation); } else { - return attachedBlocks.getOrDefault(blockPos, BlockState.of(Block.JAVA_AIR_ID)); //FIXME + return attachedBlocks.getOrDefault(blockPos, Blocks.AIR.defaultBlockState()); } } @@ -633,7 +640,9 @@ public class PistonBlockEntity { if (action == PistonValueType.PUSHING) { Vector3i pistonHeadPos = getPistonHeadPos().add(movement); if (!SOLID_BOUNDING_BOX.checkIntersection(pistonHeadPos.toDouble(), session.getCollisionManager().getPlayerBoundingBox())) { - ChunkUtils.updateBlock(session, BlockStateValues.getPistonHead(orientation), pistonHeadPos); + ChunkUtils.updateBlock(session, Blocks.PISTON_HEAD.defaultBlockState() + .withValue(Properties.SHORT, false) + .withValue(Properties.FACING, orientation), pistonHeadPos); } } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java index 25f9f5497..878d326ac 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java @@ -56,8 +56,8 @@ import org.geysermc.geyser.item.type.BlockItem; import org.geysermc.geyser.item.type.BoatItem; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.item.type.SpawnEggItem; -import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.Blocks; +import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.level.block.type.CauldronBlock; @@ -295,10 +295,10 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator { - private static final String[] ALL_BLOCK_NAMES = BlockRegistries.JAVA_BLOCKS.get().stream().map(block -> block.javaIdentifier().toString()).toArray(String[]::new); + /** + * Wait until the registries load before getting all the block names. + */ + private static final Supplier ALL_BLOCK_NAMES = Suppliers.memoize(() -> BlockRegistries.JAVA_BLOCKS.get().stream().map(block -> block.javaIdentifier().toString()).toArray(String[]::new)); private static final String[] ALL_EFFECT_IDENTIFIERS = EntityUtils.getAllEffectIdentifiers(); private static final String[] ATTRIBUTES = AttributeType.Builtin.BUILTIN.values().stream().map(AttributeType::getIdentifier).toList().toArray(new String[0]); private static final String[] ENUM_BOOLEAN = {"true", "false"}; @@ -247,7 +252,7 @@ public class JavaCommandsTranslator extends PacketTranslator CommandParam.FILE_PATH; case BOOL -> ENUM_BOOLEAN; case OPERATION -> CommandParam.OPERATOR; // ">=", "==", etc - case BLOCK_STATE -> ALL_BLOCK_NAMES; + case BLOCK_STATE -> ALL_BLOCK_NAMES.get(); case ITEM_STACK -> context.getItemNames(); case COLOR -> VALID_COLORS; case SCOREBOARD_SLOT -> VALID_SCOREBOARD_SLOTS; diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3a3a2d20c..aa68a0bc0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -65,7 +65,6 @@ fastutil-int-byte-maps = { group = "com.nukkitx.fastutil", name = "fastutil-int- fastutil-int-boolean-maps = { group = "com.nukkitx.fastutil", name = "fastutil-int-boolean-maps", version.ref = "fastutil" } fastutil-object-int-maps = { group = "com.nukkitx.fastutil", name = "fastutil-object-int-maps", version.ref = "fastutil" } fastutil-object-object-maps = { group = "com.nukkitx.fastutil", name = "fastutil-object-object-maps", version.ref = "fastutil" } -fastutil-reference-object-maps = { group = "com.nukkitx.fastutil", name = "fastutil-reference-object-maps", version.ref = "fastutil" } adventure-text-serializer-gson = { group = "net.kyori", name = "adventure-text-serializer-gson", version.ref = "adventure" } # Remove when we remove our Adventure bump adventure-text-serializer-legacy = { group = "net.kyori", name = "adventure-text-serializer-legacy", version.ref = "adventure" } @@ -143,7 +142,7 @@ blossom = { id = "net.kyori.blossom", version.ref = "blossom" } [bundles] jackson = [ "jackson-annotations", "jackson-core", "jackson-dataformat-yaml" ] -fastutil = [ "fastutil-int-int-maps", "fastutil-int-long-maps", "fastutil-int-byte-maps", "fastutil-int-boolean-maps", "fastutil-object-int-maps", "fastutil-object-object-maps", "fastutil-reference-object-maps" ] +fastutil = [ "fastutil-int-int-maps", "fastutil-int-long-maps", "fastutil-int-byte-maps", "fastutil-int-boolean-maps", "fastutil-object-int-maps", "fastutil-object-object-maps" ] adventure = [ "adventure-text-serializer-gson", "adventure-text-serializer-legacy", "adventure-text-serializer-plain" ] log4j = [ "log4j-api", "log4j-core", "log4j-slf4j2-impl" ] jline = [ "jline-terminal", "jline-terminal-jna", "jline-reader" ] From 96bfda2ed3f53a90266876b8b8741d2052dfa8ef Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 21 May 2024 20:37:18 -0400 Subject: [PATCH 183/272] Fix #4683 --- .../geyser/session/cache/LodestoneCache.java | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java index 50cdf4b5b..f66daf027 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java @@ -28,7 +28,6 @@ package org.geysermc.geyser.session.cache; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import org.checkerframework.checker.nullness.qual.Nullable; -import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.GlobalPos; import org.geysermc.mcprotocollib.protocol.data.game.item.component.LodestoneTracker; @@ -53,11 +52,13 @@ public final class LodestoneCache { private int id = 1; public void cacheInventoryItem(GeyserItemStack itemStack, LodestoneTracker tracker) { - GlobalPos position = tracker.getPos(); + if (!tracker.isTracked()) { + return; + } + GlobalPos position = tracker.getPos(); if (position == null) { - GeyserImpl.getInstance().getLogger().error("Position is null. Find out why."); - Thread.dumpStack(); + // As of 1.20.6, position can still be null even if tracking is enabled. return; } int x = position.getX(); @@ -84,13 +85,16 @@ public final class LodestoneCache { } public int store(LodestoneTracker tracker) { - GlobalPos position = tracker.getPos(); - - if (position == null) { - GeyserImpl.getInstance().getLogger().error("Position is null. Find out why."); - Thread.dumpStack(); - return -1; + if (!tracker.isTracked()) { + // No coordinates; nothing to convert + return 0; } + + GlobalPos position = tracker.getPos(); + if (position == null) { + return 0; + } + int x = position.getX(); int y = position.getY(); int z = position.getZ(); From f7b026d61b7f07459542928bdd3766843724a43b Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 21 May 2024 20:56:13 -0400 Subject: [PATCH 184/272] Remove old sneaking/crawling workarounds Since Bedrock implements these natively, there's no need for extra checks. :) --- .../type/player/SessionPlayerEntity.java | 34 ----------- .../geyser/session/GeyserSession.java | 58 ++----------------- 2 files changed, 4 insertions(+), 88 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java index e10adb134..ca541b5d3 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java @@ -31,7 +31,6 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.AttributeData; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; -import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket; import org.geysermc.geyser.entity.attribute.GeyserAttributeType; import org.geysermc.geyser.item.Items; @@ -60,10 +59,6 @@ public class SessionPlayerEntity extends PlayerEntity { */ @Getter protected final Map attributes = new Object2ObjectOpenHashMap<>(); - /** - * Whether to check for updated speed after all entity metadata has been processed - */ - private boolean refreshSpeed = false; /** * Used in PlayerInputTranslator for movement checks. */ @@ -120,9 +115,7 @@ public class SessionPlayerEntity extends PlayerEntity { // TODO: proper fix, BDS somehow does it? https://paste.gg/p/anonymous/3adfb7612f1540be80fa03a2281f93dc (BDS 1.20.13) if (!this.session.getGameMode().equals(GameMode.SPECTATOR)) { super.setFlags(entityMetadata); - session.setSwimmingInWater((entityMetadata.getPrimitiveValue() & 0x10) == 0x10 && getFlag(EntityFlag.SPRINTING)); } - refreshSpeed = true; } /** @@ -150,7 +143,6 @@ public class SessionPlayerEntity extends PlayerEntity { public void setPose(Pose pose) { super.setPose(pose); session.setPose(pose); - refreshSpeed = true; } public float getMaxHealth() { @@ -199,21 +191,6 @@ public class SessionPlayerEntity extends PlayerEntity { } } - @Override - public void updateBedrockMetadata() { - super.updateBedrockMetadata(); - if (refreshSpeed) { - AttributeData speedAttribute = session.adjustSpeed(); - if (speedAttribute != null) { - UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket(); - attributesPacket.setRuntimeEntityId(geyserId); - attributesPacket.setAttributes(Collections.singletonList(speedAttribute)); - session.sendUpstreamPacket(attributesPacket); - } - refreshSpeed = false; - } - } - @Override protected void updateAttribute(Attribute javaAttribute, List newAttributes) { if (javaAttribute.getType() == AttributeType.Builtin.GENERIC_ATTACK_SPEED) { @@ -226,17 +203,6 @@ public class SessionPlayerEntity extends PlayerEntity { @Override protected AttributeData calculateAttribute(Attribute javaAttribute, GeyserAttributeType type) { AttributeData attributeData = super.calculateAttribute(javaAttribute, type); - - if (javaAttribute.getType() == AttributeType.Builtin.GENERIC_MOVEMENT_SPEED) { - session.setOriginalSpeedAttribute(attributeData.getValue()); - AttributeData speedAttribute = session.adjustSpeed(); - if (speedAttribute != null) { - // Overwrite the attribute with our own - this.attributes.put(type, speedAttribute); - return speedAttribute; - } - } - this.attributes.put(type, attributeData); return attributeData; } diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index c85c0fd28..aa256df55 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -317,22 +317,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { @Setter private boolean sprinting; - /** - * Whether the player is swimming in water. - * Used to update speed when crawling. - */ - @Setter - private boolean swimmingInWater; - - /** - * Tracks the original speed attribute. - *

- * We need to do this in order to emulate speeds when sneaking under 1.5-blocks-tall areas if the player isn't sneaking, - * and when crawling. - */ - @Setter - private float originalSpeedAttribute; - /** * The dimension of the player. * As all entities are in the same world, this can be safely applied to all other entities. @@ -1283,21 +1267,11 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { this.sneaking = sneaking; // Update pose and bounding box on our end - AttributeData speedAttribute; - if (!sneaking && (speedAttribute = adjustSpeed()) != null) { - // Update attributes since we're still "sneaking" under a 1.5-block-tall area - UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket(); - attributesPacket.setRuntimeEntityId(playerEntity.getGeyserId()); - attributesPacket.setAttributes(Collections.singletonList(speedAttribute)); - sendUpstreamPacket(attributesPacket); - // the server *should* update our pose once it has returned to normal - } else { - if (!flying) { - // The pose and bounding box should not be updated if the player is flying - setSneakingPose(sneaking); - } - collisionManager.updateScaffoldingFlags(false); + if (!flying) { + // The pose and bounding box should not be updated if the player is flying + setSneakingPose(sneaking); } + collisionManager.updateScaffoldingFlags(false); playerEntity.updateBedrockMetadata(); @@ -1340,30 +1314,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { } } - /** - * Adjusts speed if the player is crawling. - * - * @return not null if attributes should be updated. - */ - public @Nullable AttributeData adjustSpeed() { - AttributeData currentPlayerSpeed = playerEntity.getAttributes().get(GeyserAttributeType.MOVEMENT_SPEED); - if (currentPlayerSpeed != null) { - if ((pose.equals(Pose.SNEAKING) && !sneaking && collisionManager.mustPlayerSneakHere()) || - (!swimmingInWater && playerEntity.getFlag(EntityFlag.SWIMMING) && !collisionManager.isPlayerInWater())) { - // Either of those conditions means that Bedrock goes zoom when they shouldn't be - AttributeData speedAttribute = GeyserAttributeType.MOVEMENT_SPEED.getAttribute(originalSpeedAttribute / 3.32f); - playerEntity.getAttributes().put(GeyserAttributeType.MOVEMENT_SPEED, speedAttribute); - return speedAttribute; - } else if (originalSpeedAttribute != currentPlayerSpeed.getValue()) { - // Speed has reset to normal - AttributeData speedAttribute = GeyserAttributeType.MOVEMENT_SPEED.getAttribute(originalSpeedAttribute); - playerEntity.getAttributes().put(GeyserAttributeType.MOVEMENT_SPEED, speedAttribute); - return speedAttribute; - } - } - return null; - } - /** * Checks to see if a shield is in either hand to activate blocking. If so, it sets the Bedrock client to display * blocking and sends a packet to the Java server. From 6f4c29c834b4f111ee9807da89fc3aa83d93c83d Mon Sep 17 00:00:00 2001 From: gecko10000 <60494179+gecko10000@users.noreply.github.com> Date: Wed, 22 May 2024 02:26:32 -0700 Subject: [PATCH 185/272] Match Advancement Packet Behavior Towards Java (#4684) * Send advancement packet regardless of current tab * Send advancement close packet when single-advancement form closed --- .../geyser/session/cache/AdvancementsCache.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java index 6769b4330..be1eb3a5b 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java @@ -91,11 +91,9 @@ public class AdvancementsCache { builder.validResultHandler((response) -> { String id = rootAdvancementIds.get(response.clickedButtonId()); if (!id.equals("")) { - if (!id.equals(currentAdvancementCategoryId)) { - // Send a packet indicating that we are opening this particular advancement window - ServerboundSeenAdvancementsPacket packet = new ServerboundSeenAdvancementsPacket(id); - session.sendDownstreamGamePacket(packet); - } + // Send a packet indicating that we are opening this particular advancement window + ServerboundSeenAdvancementsPacket packet = new ServerboundSeenAdvancementsPacket(id); + session.sendDownstreamGamePacket(packet); currentAdvancementCategoryId = id; buildAndShowListForm(); } @@ -188,6 +186,10 @@ public class AdvancementsCache { .content(content) .button(GeyserLocale.getPlayerLocaleString("gui.back", language)) .validResultHandler((response) -> buildAndShowListForm()) + .closedResultHandler(() -> { + // Indicate that we have closed the current advancement tab + session.sendDownstreamGamePacket(new ServerboundSeenAdvancementsPacket()); + }) ); } From ec3327efebd017f43966299f5b6a528128ea2f50 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Thu, 23 May 2024 11:41:26 -0400 Subject: [PATCH 186/272] Minor minor changes --- .../geyser/level/block/property/BasicEnumProperty.java | 2 +- .../java/org/geysermc/geyser/level/block/type/BlockState.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/level/block/property/BasicEnumProperty.java b/core/src/main/java/org/geysermc/geyser/level/block/property/BasicEnumProperty.java index f55b85d7b..c34392504 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/property/BasicEnumProperty.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/property/BasicEnumProperty.java @@ -47,7 +47,7 @@ public final class BasicEnumProperty extends Property { public int indexOf(String value) { int index = this.values.indexOf(value); if (index == -1) { - throw new IllegalStateException("Property " + this + " does not have value " + value); + throw new IllegalArgumentException("Property " + this + " does not have value " + value); } return index; } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java b/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java index 44271bd80..a312a7d5a 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java @@ -35,7 +35,7 @@ public final class BlockState { private final Block block; private final int javaId; /** - * The values of each property of this block state. These should be treated as keys to {@link Block#propertyKeys()} + * The values of each property of this block state. These should be treated as keys to {@link Block#propertyKeys()}. * Of note - the comparable part probably doesn't do anything because we occasionally use strings in place of enums. * Will be null if there's only one block state for a block. */ @@ -135,7 +135,7 @@ public final class BlockState { // The above for loop will always stop at the first break because the last property has already been found diff = 1; } - return BlockState.of(this.javaId + ((thatOffset - thisOffset) * diff)); + return of(this.javaId + ((thatOffset - thisOffset) * diff)); } public Block block() { From d5fdbeb49c5b304aa18070ae4abae1e3d0f36763 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Sat, 25 May 2024 13:19:59 +0100 Subject: [PATCH 187/272] Make allow-third-party-capes default to false (#4690) --- .../geyser/configuration/GeyserJacksonConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java b/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java index a55e4af8f..81ac824e4 100644 --- a/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java +++ b/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java @@ -94,7 +94,7 @@ public abstract class GeyserJacksonConfiguration implements GeyserConfiguration private boolean debugMode = false; @JsonProperty("allow-third-party-capes") - private boolean allowThirdPartyCapes = true; + private boolean allowThirdPartyCapes = false; @JsonProperty("show-cooldown") private String showCooldown = "title"; From 0ea01bfa4876fd9722698f096dbbfefbf5ccd7d1 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 25 May 2024 18:59:37 -0400 Subject: [PATCH 188/272] Allow skull pick item NBT --- .../geyser/inventory/GeyserItemStack.java | 2 +- .../geyser/level/block/type/SkullBlock.java | 36 +++++++++++++++++++ .../BedrockBlockPickRequestTranslator.java | 7 +++- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java b/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java index fa62769fe..744ad70b6 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/GeyserItemStack.java @@ -69,7 +69,7 @@ public class GeyserItemStack { return of(javaId, amount, null); } - public static @NonNull GeyserItemStack of(int javaId, int amount, DataComponents components) { + public static @NonNull GeyserItemStack of(int javaId, int amount, @Nullable DataComponents components) { return new GeyserItemStack(javaId, amount, components); } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/SkullBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/SkullBlock.java index 76b532919..c4aae46a2 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/SkullBlock.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/SkullBlock.java @@ -25,10 +25,20 @@ package org.geysermc.geyser.level.block.type; +import com.github.steveice10.mc.auth.data.GameProfile; import org.cloudburstmc.math.vector.Vector3i; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; +import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.SkullCache; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; + +import java.util.Collections; +import java.util.UUID; public class SkullBlock extends Block { private final Type type; @@ -55,6 +65,32 @@ public class SkullBlock extends Block { // It's not an empty skull. } + public ItemStack pickItem(GeyserSession session, BlockState state, Vector3i position) { + SkullCache.Skull skull = session.getSkullCache().getSkulls().get(position); + if (skull == null) { + return new ItemStack(pickItem(state).getId()); + } + + GeyserItemStack itemStack = GeyserItemStack.of(pickItem(state).getId(), 1); + // This is a universal block entity behavior, but hardcode how it works for now. + NbtMapBuilder builder = NbtMap.builder() + .putString("id", "minecraft:skull") + .putInt("x", position.getX()) + .putInt("y", position.getY()) + .putInt("z", position.getZ()); + DataComponents components = itemStack.getOrCreateComponents(); + components.put(DataComponentType.BLOCK_ENTITY_DATA, builder.build()); + + UUID uuid = skull.getUuid(); + String texturesProperty = skull.getTexturesProperty(); + GameProfile profile = new GameProfile(uuid, null); + if (texturesProperty != null) { + profile.setProperties(Collections.singletonList(new GameProfile.Property("textures", texturesProperty))); + } + components.put(DataComponentType.PROFILE, profile); + return itemStack.getItemStack(); + } + public Type skullType() { return type; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java index 0a721e4b0..94368a6d4 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockPickRequestTranslator.java @@ -33,6 +33,7 @@ import org.geysermc.geyser.item.Items; import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.level.block.type.BannerBlock; import org.geysermc.geyser.level.block.type.BlockState; +import org.geysermc.geyser.level.block.type.SkullBlock; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; @@ -65,7 +66,11 @@ public class BedrockBlockPickRequestTranslator extends PacketTranslator session.ensureInEventLoop(() -> { if (components == null) { From 5f7a31a1d837048a147258f3caf2f750c7738fb7 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 25 May 2024 20:55:05 -0400 Subject: [PATCH 189/272] Fix #4688 --- .../org/geysermc/geyser/entity/type/InteractionEntity.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/InteractionEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/InteractionEntity.java index 4e7a805b4..06035a47c 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/InteractionEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/InteractionEntity.java @@ -80,7 +80,10 @@ public class InteractionEntity extends Entity { } public void setHeight(FloatEntityMetadata height) { - setBoundingBoxHeight(height.getPrimitiveValue()); + // Bedrock does *not* like high values being placed here + // https://gist.github.com/Owen1212055/f5d59169d3a6a5c32f0c173d57eb199d recommend(s/ed) using the tactic + // https://github.com/GeyserMC/Geyser/issues/4688 + setBoundingBoxHeight(Math.min(height.getPrimitiveValue(), 64f)); } public void setResponse(BooleanEntityMetadata response) { From fa6808a62029373af4492329bbf2cbf80bb51e7f Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Sun, 26 May 2024 20:00:47 -0700 Subject: [PATCH 190/272] Bedrock 1.21.0 Support (#4687) * 1.21.0 Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Deprecate Bedrock 1.20.70 and below Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Strictly disconnect on all exceptions Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> * Remove old version resources Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> --------- Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> --- README.md | 2 +- .../holder/BlockInventoryHolder.java | 1 + .../geyser/network/CodecProcessor.java | 23 +- .../geysermc/geyser/network/GameProtocol.java | 36 +- .../geyser/network/InvalidPacketHandler.java | 4 +- .../populator/BlockRegistryPopulator.java | 13 +- .../registry/populator/Conversion630_622.java | 217 - .../registry/populator/Conversion649_630.java | 64 - .../registry/populator/Conversion662_649.java | 187 - .../registry/populator/Conversion671_662.java | 205 - .../registry/populator/Conversion685_671.java | 205 + .../CustomBlockRegistryPopulator.java | 9 +- .../CustomItemRegistryPopulator.java | 118 +- .../populator/ItemRegistryPopulator.java | 30 +- .../populator/RecipeRegistryPopulator.java | 5 +- .../geyser/session/GeyserSession.java | 4 + .../inventory/LecternInventoryTranslator.java | 19 - .../inventory/PlayerInventoryTranslator.java | 1 + .../chest/DoubleChestInventoryTranslator.java | 1 + .../player/BedrockActionTranslator.java | 5 - .../java/JavaUpdateRecipesTranslator.java | 7 +- .../JavaContainerSetSlotTranslator.java | 4 +- .../inventory/JavaOpenBookTranslator.java | 6 - .../inventory/JavaOpenScreenTranslator.java | 6 - .../bedrock/block_palette.1_20_40.nbt | Bin 158101 -> 0 bytes .../bedrock/block_palette.1_20_50.nbt | Bin 170466 -> 0 bytes .../bedrock/block_palette.1_20_60.nbt | Bin 124510 -> 0 bytes .../bedrock/block_palette.1_20_70.nbt | Bin 176502 -> 0 bytes .../bedrock/block_palette.1_21_0.nbt | Bin 0 -> 177397 bytes .../bedrock/creative_items.1_20_40.json | 5787 ---------------- .../bedrock/creative_items.1_20_50.json | 5995 ---------------- .../bedrock/creative_items.1_20_60.json | 5787 ---------------- ..._20_70.json => creative_items.1_21_0.json} | 2033 +++--- .../resources/bedrock/entity_identifiers.dat | Bin 7951 -> 8314 bytes .../bedrock/runtime_item_states.1_20_40.json | 5570 --------------- .../bedrock/runtime_item_states.1_20_50.json | 5846 ---------------- .../bedrock/runtime_item_states.1_20_60.json | 5998 ----------------- ...0.json => runtime_item_states.1_21_0.json} | 1300 ++-- core/src/main/resources/mappings | 2 +- gradle/libs.versions.toml | 12 +- 40 files changed, 2325 insertions(+), 37177 deletions(-) delete mode 100644 core/src/main/java/org/geysermc/geyser/registry/populator/Conversion630_622.java delete mode 100644 core/src/main/java/org/geysermc/geyser/registry/populator/Conversion649_630.java delete mode 100644 core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java delete mode 100644 core/src/main/java/org/geysermc/geyser/registry/populator/Conversion671_662.java create mode 100644 core/src/main/java/org/geysermc/geyser/registry/populator/Conversion685_671.java delete mode 100644 core/src/main/resources/bedrock/block_palette.1_20_40.nbt delete mode 100644 core/src/main/resources/bedrock/block_palette.1_20_50.nbt delete mode 100644 core/src/main/resources/bedrock/block_palette.1_20_60.nbt delete mode 100644 core/src/main/resources/bedrock/block_palette.1_20_70.nbt create mode 100644 core/src/main/resources/bedrock/block_palette.1_21_0.nbt delete mode 100644 core/src/main/resources/bedrock/creative_items.1_20_40.json delete mode 100644 core/src/main/resources/bedrock/creative_items.1_20_50.json delete mode 100644 core/src/main/resources/bedrock/creative_items.1_20_60.json rename core/src/main/resources/bedrock/{creative_items.1_20_70.json => creative_items.1_21_0.json} (78%) delete mode 100644 core/src/main/resources/bedrock/runtime_item_states.1_20_40.json delete mode 100644 core/src/main/resources/bedrock/runtime_item_states.1_20_50.json delete mode 100644 core/src/main/resources/bedrock/runtime_item_states.1_20_60.json rename core/src/main/resources/bedrock/{runtime_item_states.1_20_70.json => runtime_item_states.1_21_0.json} (95%) diff --git a/README.md b/README.md index 9257af9ac..dd2d096ec 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here! -### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.80/81 and Minecraft Java 1.20.5/1.20.6 +### Currently supporting Minecraft Bedrock 1.20.80 - 1.21.0 and Minecraft Java 1.20.5/1.20.6 ## Setting Up Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser. diff --git a/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java b/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java index 9c8e5de15..cdda4fe4c 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/holder/BlockInventoryHolder.java @@ -163,6 +163,7 @@ public class BlockInventoryHolder extends InventoryHolder { ContainerClosePacket packet = new ContainerClosePacket(); packet.setId((byte) inventory.getBedrockId()); packet.setServerInitiated(true); + packet.setType(ContainerType.CONTAINER); session.sendUpstreamPacket(packet); return; } diff --git a/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java b/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java index 6bd767fb7..4c459573a 100644 --- a/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java +++ b/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java @@ -224,7 +224,7 @@ class CodecProcessor { @SuppressWarnings("unchecked") static BedrockCodec processCodec(BedrockCodec codec) { - return codec.toBuilder() + BedrockCodec.Builder codecBuilder = codec.toBuilder() // Illegal unused serverbound EDU packets .updateSerializer(PhotoTransferPacket.class, ILLEGAL_SERIALIZER) .updateSerializer(LabTablePacket.class, ILLEGAL_SERIALIZER) @@ -236,6 +236,7 @@ class CodecProcessor { .updateSerializer(PurchaseReceiptPacket.class, ILLEGAL_SERIALIZER) // Illegal unused serverbound packets that are deprecated .updateSerializer(ClientCheatAbilityPacket.class, ILLEGAL_SERIALIZER) + .updateSerializer(CraftingEventPacket.class, ILLEGAL_SERIALIZER) // Illegal unusued serverbound packets that relate to unused features .updateSerializer(PlayerAuthInputPacket.class, ILLEGAL_SERIALIZER) .updateSerializer(ClientCacheBlobStatusPacket.class, ILLEGAL_SERIALIZER) @@ -243,7 +244,6 @@ class CodecProcessor { .updateSerializer(SubChunkRequestPacket.class, ILLEGAL_SERIALIZER) .updateSerializer(GameTestRequestPacket.class, ILLEGAL_SERIALIZER) // Ignored serverbound packets - .updateSerializer(CraftingEventPacket.class, IGNORED_SERIALIZER) // Make illegal when 1.20.40 is removed .updateSerializer(ClientToServerHandshakePacket.class, IGNORED_SERIALIZER) .updateSerializer(EntityFallPacket.class, IGNORED_SERIALIZER) .updateSerializer(MapCreateLockedCopyPacket.class, IGNORED_SERIALIZER) @@ -260,22 +260,25 @@ class CodecProcessor { .updateSerializer(PlayerHotbarPacket.class, PLAYER_HOTBAR_SERIALIZER) .updateSerializer(PlayerSkinPacket.class, PLAYER_SKIN_SERIALIZER) .updateSerializer(SetEntityDataPacket.class, SET_ENTITY_DATA_SERIALIZER) - .updateSerializer(SetEntityMotionPacket.class, codec.getProtocolVersion() < 662 ? - SET_ENTITY_MOTION_SERIALIZER_V291 : - SET_ENTITY_MOTION_SERIALIZER_V662) + .updateSerializer(SetEntityMotionPacket.class, SET_ENTITY_MOTION_SERIALIZER_V662) .updateSerializer(SetEntityLinkPacket.class, SET_ENTITY_LINK_SERIALIZER) // Valid serverbound packets where reading of some fields can be skipped .updateSerializer(MobEquipmentPacket.class, MOB_EQUIPMENT_SERIALIZER) - // // Illegal bidirectional packets + // Illegal bidirectional packets .updateSerializer(DebugInfoPacket.class, ILLEGAL_SERIALIZER) .updateSerializer(EditorNetworkPacket.class, ILLEGAL_SERIALIZER) .updateSerializer(ScriptMessagePacket.class, ILLEGAL_SERIALIZER) - // // Ignored bidirectional packets + // Ignored bidirectional packets .updateSerializer(ClientCacheStatusPacket.class, IGNORED_SERIALIZER) .updateSerializer(SimpleEventPacket.class, IGNORED_SERIALIZER) - .updateSerializer(TickSyncPacket.class, IGNORED_SERIALIZER) - .updateSerializer(MultiplayerSettingsPacket.class, IGNORED_SERIALIZER) - .build(); + .updateSerializer(MultiplayerSettingsPacket.class, IGNORED_SERIALIZER); + + if (codec.getProtocolVersion() < 685) { + // Ignored bidirectional packets + codecBuilder.updateSerializer(TickSyncPacket.class, IGNORED_SERIALIZER); + } + + return codecBuilder.build(); } /** diff --git a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java index f9292671f..1c58288c7 100644 --- a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java +++ b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java @@ -27,11 +27,8 @@ package org.geysermc.geyser.network; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec; -import org.cloudburstmc.protocol.bedrock.codec.v622.Bedrock_v622; -import org.cloudburstmc.protocol.bedrock.codec.v630.Bedrock_v630; -import org.cloudburstmc.protocol.bedrock.codec.v649.Bedrock_v649; -import org.cloudburstmc.protocol.bedrock.codec.v662.Bedrock_v662; import org.cloudburstmc.protocol.bedrock.codec.v671.Bedrock_v671; +import org.cloudburstmc.protocol.bedrock.codec.v685.Bedrock_v685; import org.cloudburstmc.protocol.bedrock.netty.codec.packet.BedrockPacketCodec; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodec; @@ -50,8 +47,8 @@ public final class GameProtocol { * Default Bedrock codec that should act as a fallback. Should represent the latest available * release of the game that Geyser supports. */ - public static final BedrockCodec DEFAULT_BEDROCK_CODEC = CodecProcessor.processCodec(Bedrock_v671.CODEC.toBuilder() - .minecraftVersion("1.20.81") + public static final BedrockCodec DEFAULT_BEDROCK_CODEC = CodecProcessor.processCodec(Bedrock_v685.CODEC.toBuilder() + .minecraftVersion("1.21.0") .build()); /** @@ -66,20 +63,11 @@ public final class GameProtocol { private static final PacketCodec DEFAULT_JAVA_CODEC = MinecraftCodec.CODEC; static { - SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v622.CODEC.toBuilder() - .minecraftVersion("1.20.40/1.20.41") - .build())); - SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v630.CODEC.toBuilder() - .minecraftVersion("1.20.50/1.20.51") - .build())); - SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v649.CODEC.toBuilder() - .minecraftVersion("1.20.60/1.20.62") - .build())); - SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v662.CODEC.toBuilder() - .minecraftVersion("1.20.70/1.20.73") + SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v671.CODEC.toBuilder() + .minecraftVersion("1.20.80/1.20.81") .build())); SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(DEFAULT_BEDROCK_CODEC.toBuilder() - .minecraftVersion("1.20.80/1.20.81") + .minecraftVersion("1.21.0") .build())); } @@ -99,16 +87,8 @@ public final class GameProtocol { /* Bedrock convenience methods to gatekeep features and easily remove the check on version removal */ - public static boolean isPre1_20_50(GeyserSession session) { - return session.getUpstream().getProtocolVersion() < Bedrock_v630.CODEC.getProtocolVersion(); - } - - public static boolean isPre1_20_70(GeyserSession session) { - return session.getUpstream().getProtocolVersion() < Bedrock_v662.CODEC.getProtocolVersion(); - } - - public static boolean is1_20_60orHigher(int protocolVersion) { - return protocolVersion >= Bedrock_v649.CODEC.getProtocolVersion(); + public static boolean isPre1_21_0(GeyserSession session) { + return session.getUpstream().getProtocolVersion() < Bedrock_v685.CODEC.getProtocolVersion(); } /** diff --git a/core/src/main/java/org/geysermc/geyser/network/InvalidPacketHandler.java b/core/src/main/java/org/geysermc/geyser/network/InvalidPacketHandler.java index 3e836711b..1b653891e 100644 --- a/core/src/main/java/org/geysermc/geyser/network/InvalidPacketHandler.java +++ b/core/src/main/java/org/geysermc/geyser/network/InvalidPacketHandler.java @@ -47,7 +47,9 @@ public class InvalidPacketHandler extends ChannelInboundHandlerAdapter { if (!(rootCause instanceof IllegalArgumentException)) { - super.exceptionCaught(ctx, cause); + // Kick users that cause exceptions + session.getGeyser().getLogger().warning("Exception caught in session of" + session.bedrockUsername() + ": " + rootCause.getMessage()); + session.disconnect("An internal error occurred!"); return; } diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java index 6eadbd0e5..936935306 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java @@ -38,11 +38,8 @@ import it.unimi.dsi.fastutil.objects.*; import org.cloudburstmc.blockstateupdater.BlockStateUpdater; import org.cloudburstmc.blockstateupdater.util.tagupdater.CompoundTagUpdaterContext; import org.cloudburstmc.nbt.*; -import org.cloudburstmc.protocol.bedrock.codec.v622.Bedrock_v622; -import org.cloudburstmc.protocol.bedrock.codec.v630.Bedrock_v630; -import org.cloudburstmc.protocol.bedrock.codec.v649.Bedrock_v649; -import org.cloudburstmc.protocol.bedrock.codec.v662.Bedrock_v662; import org.cloudburstmc.protocol.bedrock.codec.v671.Bedrock_v671; +import org.cloudburstmc.protocol.bedrock.codec.v685.Bedrock_v685; import org.cloudburstmc.protocol.bedrock.data.BlockPropertyData; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.geysermc.geyser.GeyserImpl; @@ -125,12 +122,8 @@ public final class BlockRegistryPopulator { private static void registerBedrockBlocks() { var blockMappers = ImmutableMap., Remapper>builder() - .put(ObjectIntPair.of("1_20_40", Bedrock_v622.CODEC.getProtocolVersion()), Conversion630_622::remapBlock) - .put(ObjectIntPair.of("1_20_50", Bedrock_v630.CODEC.getProtocolVersion()), Conversion649_630::remapBlock) - // Only changes in 1.20.60 are hard_stained_glass (an EDU only block) - .put(ObjectIntPair.of("1_20_60", Bedrock_v649.CODEC.getProtocolVersion()), Conversion662_649::remapBlock) - .put(ObjectIntPair.of("1_20_70", Bedrock_v662.CODEC.getProtocolVersion()), Conversion671_662::remapBlock) - .put(ObjectIntPair.of("1_20_80", Bedrock_v671.CODEC.getProtocolVersion()), tag -> tag) + .put(ObjectIntPair.of("1_20_80", Bedrock_v671.CODEC.getProtocolVersion()), Conversion685_671::remapBlock) + .put(ObjectIntPair.of("1_21_0", Bedrock_v685.CODEC.getProtocolVersion()), tag -> tag) .build(); // We can keep this strong as nothing should be garbage collected diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion630_622.java b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion630_622.java deleted file mode 100644 index 398eabc3c..000000000 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion630_622.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (c) 2019-2023 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.geyser.registry.populator; - -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; -import org.cloudburstmc.nbt.NbtMap; -import org.cloudburstmc.nbt.NbtMapBuilder; -import org.geysermc.geyser.item.type.Item; -import org.geysermc.geyser.registry.type.GeyserMappingItem; - -import java.util.List; -import java.util.Map; - -/** - * Backwards-maps the blocks and items of 1.20.50 (630) to 1.20.40 (622) - */ -class Conversion630_622 { - - private static final List NEW_STONES = List.of("minecraft:stone", "minecraft:granite", "minecraft:polished_granite", "minecraft:diorite", "minecraft:polished_diorite", "minecraft:andesite", "minecraft:polished_andesite"); - private static final List NEW_WOODS = List.of("minecraft:oak_planks", "minecraft:spruce_planks", "minecraft:birch_planks", "minecraft:jungle_planks", "minecraft:acacia_planks", "minecraft:dark_oak_planks"); - - private static final Map ITEMS = new Object2ObjectOpenHashMap<>(); - - static { - ITEMS.put("minecraft:acacia_planks", "minecraft:planks"); - ITEMS.put("minecraft:birch_planks", "minecraft:planks"); - ITEMS.put("minecraft:dark_oak_planks", "minecraft:planks"); - ITEMS.put("minecraft:jungle_planks", "minecraft:planks"); - ITEMS.put("minecraft:oak_planks", "minecraft:planks"); - ITEMS.put("minecraft:spruce_planks", "minecraft:planks"); - - ITEMS.put("minecraft:diorite", "minecraft:stone"); - ITEMS.put("minecraft:andesite", "minecraft:stone"); - ITEMS.put("minecraft:granite", "minecraft:stone"); - ITEMS.put("minecraft:polished_andesite", "minecraft:stone"); - ITEMS.put("minecraft:polished_diorite", "minecraft:stone"); - ITEMS.put("minecraft:polished_granite", "minecraft:stone"); - - ITEMS.put("minecraft:chiseled_tuff", "minecraft:chiseled_deepslate"); - ITEMS.put("minecraft:chiseled_tuff_bricks", "minecraft:chiseled_deepslate"); - ITEMS.put("minecraft:polished_tuff", "minecraft:polished_deepslate"); - ITEMS.put("minecraft:polished_tuff_double_slab", "minecraft:polished_deepslate_double_slab"); - ITEMS.put("minecraft:polished_tuff_slab", "minecraft:polished_deepslate_slab"); - ITEMS.put("minecraft:polished_tuff_stairs", "minecraft:polished_deepslate_stairs"); - ITEMS.put("minecraft:polished_tuff_wall", "minecraft:polished_deepslate_wall"); - ITEMS.put("minecraft:tuff_brick_double_slab", "minecraft:deepslate_brick_double_slab"); - ITEMS.put("minecraft:tuff_brick_slab", "minecraft:deepslate_brick_slab"); - ITEMS.put("minecraft:tuff_brick_stairs", "minecraft:deepslate_brick_stairs"); - ITEMS.put("minecraft:tuff_brick_wall", "minecraft:deepslate_brick_wall"); - ITEMS.put("minecraft:tuff_bricks", "minecraft:deepslate_bricks"); - ITEMS.put("minecraft:tuff_double_slab", "minecraft:cobbled_deepslate_double_slab"); - ITEMS.put("minecraft:tuff_slab", "minecraft:cobbled_deepslate_slab"); - ITEMS.put("minecraft:tuff_stairs", "minecraft:cobbled_deepslate_stairs"); - ITEMS.put("minecraft:tuff_wall", "minecraft:cobbled_deepslate_wall"); - - ITEMS.put("minecraft:chiseled_copper", "minecraft:copper_block"); - ITEMS.put("minecraft:copper_bulb", "minecraft:copper_block"); - ITEMS.put("minecraft:copper_door", "minecraft:iron_door"); - ITEMS.put("minecraft:copper_grate", "minecraft:raw_iron_block"); - ITEMS.put("minecraft:copper_trapdoor", "minecraft:iron_trapdoor"); - ITEMS.put("minecraft:exposed_chiseled_copper", "minecraft:exposed_copper"); - ITEMS.put("minecraft:exposed_copper_bulb", "minecraft:exposed_copper"); - ITEMS.put("minecraft:exposed_copper_door", "minecraft:iron_door"); - ITEMS.put("minecraft:exposed_copper_grate", "minecraft:raw_iron_block"); - ITEMS.put("minecraft:exposed_copper_trapdoor", "minecraft:iron_trapdoor"); - ITEMS.put("minecraft:oxidized_chiseled_copper", "minecraft:oxidized_copper"); - ITEMS.put("minecraft:oxidized_copper_bulb", "minecraft:oxidized_copper"); - ITEMS.put("minecraft:oxidized_copper_door", "minecraft:iron_door"); - ITEMS.put("minecraft:oxidized_copper_grate", "minecraft:raw_iron_block"); - ITEMS.put("minecraft:oxidized_copper_trapdoor", "minecraft:iron_trapdoor"); - ITEMS.put("minecraft:waxed_chiseled_copper", "minecraft:waxed_copper"); - ITEMS.put("minecraft:waxed_copper_bulb", "minecraft:waxed_copper"); - ITEMS.put("minecraft:waxed_copper_door", "minecraft:iron_door"); - ITEMS.put("minecraft:waxed_copper_grate", "minecraft:raw_iron_block"); - ITEMS.put("minecraft:waxed_copper_trapdoor", "minecraft:iron_trapdoor"); - ITEMS.put("minecraft:waxed_exposed_chiseled_copper", "minecraft:waxed_exposed_copper"); - ITEMS.put("minecraft:waxed_exposed_copper_bulb", "minecraft:waxed_exposed_copper"); - ITEMS.put("minecraft:waxed_exposed_copper_door", "minecraft:iron_door"); - ITEMS.put("minecraft:waxed_exposed_copper_grate", "minecraft:raw_iron_block"); - ITEMS.put("minecraft:waxed_exposed_copper_trapdoor", "minecraft:iron_trapdoor"); - ITEMS.put("minecraft:waxed_oxidized_chiseled_copper", "minecraft:waxed_oxidized_copper"); - ITEMS.put("minecraft:waxed_oxidized_copper_bulb", "minecraft:waxed_oxidized_copper"); - ITEMS.put("minecraft:waxed_oxidized_copper_door", "minecraft:iron_door"); - ITEMS.put("minecraft:waxed_oxidized_copper_grate", "minecraft:raw_iron_block"); - ITEMS.put("minecraft:waxed_oxidized_copper_trapdoor", "minecraft:iron_trapdoor"); - ITEMS.put("minecraft:waxed_weathered_chiseled_copper", "minecraft:waxed_weathered_copper"); - ITEMS.put("minecraft:waxed_weathered_copper_bulb", "minecraft:waxed_weathered_copper"); - ITEMS.put("minecraft:waxed_weathered_copper_door", "minecraft:iron_door"); - ITEMS.put("minecraft:waxed_weathered_copper_grate", "minecraft:raw_iron_block"); - ITEMS.put("minecraft:waxed_weathered_copper_trapdoor", "minecraft:iron_trapdoor"); - ITEMS.put("minecraft:weathered_chiseled_copper", "minecraft:weathered_copper"); - ITEMS.put("minecraft:weathered_copper_bulb", "minecraft:weathered_copper"); - ITEMS.put("minecraft:weathered_copper_door", "minecraft:iron_door"); - ITEMS.put("minecraft:weathered_copper_grate", "minecraft:raw_iron_block"); - ITEMS.put("minecraft:weathered_copper_trapdoor", "minecraft:iron_trapdoor"); - - ITEMS.put("minecraft:crafter", "minecraft:crafting_table"); - } - - static GeyserMappingItem remapItem(@SuppressWarnings("unused") Item item, GeyserMappingItem mapping) { - mapping = Conversion649_630.remapItem(item, mapping); - - String replacement = ITEMS.get(mapping.getBedrockIdentifier()); - if (replacement == null) { - return mapping; - } else { - return mapping.withBedrockIdentifier(replacement); - } - } - - static NbtMap remapBlock(NbtMap tag) { - tag = Conversion649_630.remapBlock(tag); - - final String name = tag.getString("name"); - - String replacement; - if (NEW_STONES.contains(name) || NEW_WOODS.contains(name)) { - - String typeKey; - String type = name.substring(10); - if (NEW_STONES.contains(name)) { - replacement = "minecraft:stone"; - typeKey = "stone_type"; - if (type.startsWith("polished_")) { - type = type.substring(9) + "_smooth"; - } - } else { - replacement = "minecraft:planks"; - typeKey = "wood_type"; - type = type.substring(0, type.indexOf("_planks")); - } - - return tag.toBuilder() - .putString("name", replacement) - .putCompound("states", NbtMap.builder().putString(typeKey, type).build()) - .build(); - } else if (name.contains("tuff") && !name.equals("minecraft:tuff")) { - - if (name.contains("brick") || name.contains("polished") || name.contains("chiseled")) { - replacement = name.replace("tuff", "deepslate"); - - if (name.contains("chiseled")) { - // chiseled deepslate bricks don't exist. just use chiseled deepslate instead - replacement = replacement.replace("_bricks", ""); - } - } else { - replacement = name.replace("tuff", "cobbled_deepslate"); - } - - return tag.toBuilder() - .putString("name", replacement) - .build(); - } else if (name.contains("copper")) { - - boolean removeStates = false; - if (name.contains("chiseled")) { - replacement = name.replace("_chiseled", ""); // special chiseled - replacement = replacement.replace("chiseled_", ""); // plain chiseled - } else if (name.endsWith("bulb")) { - replacement = name.replace("_bulb", ""); - removeStates = true; - } else if (name.endsWith("grate")) { - replacement = "minecraft:raw_iron_block"; - } else if (name.endsWith("door")) { - if (name.contains("trap")) { - replacement = "minecraft:iron_trapdoor"; - } else { - replacement = "minecraft:iron_door"; - } - } else { - return tag; - } - - if (replacement.endsWith(":copper")) { - // case for plain chiseled copper and plain bulb - replacement = replacement + "_block"; - } - - NbtMapBuilder builder = tag.toBuilder(); - builder.putString("name", replacement); - if (removeStates) { - builder.putCompound("states", NbtMap.EMPTY); - } - return builder.build(); - } else if (name.equals("minecraft:crafter")) { - NbtMapBuilder builder = tag.toBuilder(); - builder.put("name", "minecraft:crafting_table"); - builder.put("states", NbtMap.EMPTY); - return builder.build(); - } - - return tag; - } -} diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion649_630.java b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion649_630.java deleted file mode 100644 index 70a5e1ad9..000000000 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion649_630.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ -package org.geysermc.geyser.registry.populator; - -import org.cloudburstmc.nbt.NbtMap; -import org.cloudburstmc.nbt.NbtMapBuilder; -import org.geysermc.geyser.item.type.Item; -import org.geysermc.geyser.registry.type.GeyserMappingItem; - -public class Conversion649_630 { - - static GeyserMappingItem remapItem(@SuppressWarnings("unused") Item item, GeyserMappingItem mapping) { - mapping = Conversion662_649.remapItem(item, mapping); - - String identifer = mapping.getBedrockIdentifier(); - - switch (identifer) { - case "minecraft:armadillo_scute", "minecraft:turtle_scute" -> { return mapping.withBedrockIdentifier("minecraft:scute"); } - case "minecraft:armadillo_spawn_egg" -> { return mapping.withBedrockIdentifier("minecraft:rabbit_spawn_egg"); } - case "minecraft:trial_spawner" -> { return mapping.withBedrockIdentifier("minecraft:mob_spawner"); } - case "minecraft:trial_key" -> { return mapping.withBedrockIdentifier("minecraft:echo_shard"); } - case "minecraft:wolf_armor" -> { return mapping.withBedrockIdentifier("minecraft:leather_horse_armor"); } - default -> { return mapping; } - } - } - - static NbtMap remapBlock(NbtMap tag) { - tag = Conversion662_649.remapBlock(tag); - - final String name = tag.getString("name"); - - if (name.equals("minecraft:trial_spawner")) { - NbtMapBuilder builder = tag.toBuilder() - .putString("name", "minecraft:mob_spawner") - .putCompound("states", NbtMap.EMPTY); - - return builder.build(); - } - - return tag; - } -} diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java deleted file mode 100644 index 041afdbc8..000000000 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion662_649.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.geyser.registry.populator; - -import org.cloudburstmc.nbt.NbtMap; -import org.cloudburstmc.nbt.NbtMapBuilder; -import org.geysermc.geyser.item.type.Item; -import org.geysermc.geyser.registry.type.GeyserMappingItem; - -import java.util.List; -import java.util.stream.Stream; - -public class Conversion662_649 { - - private static final List NEW_MISC = List.of("minecraft:grass_block", "minecraft:vault"); - private static final List NEW_WOODS = List.of("minecraft:oak_wood", "minecraft:spruce_wood", "minecraft:birch_wood", "minecraft:jungle_wood", "minecraft:acacia_wood", "minecraft:dark_oak_wood", "minecraft:stripped_oak_wood", "minecraft:stripped_spruce_wood", "minecraft:stripped_birch_wood", "minecraft:stripped_jungle_wood", "minecraft:stripped_acacia_wood", "minecraft:stripped_dark_oak_wood"); - private static final List NEW_LEAVES = List.of("minecraft:oak_leaves", "minecraft:spruce_leaves", "minecraft:birch_leaves", "minecraft:jungle_leaves"); - private static final List NEW_LEAVES2 = List.of("minecraft:acacia_leaves", "minecraft:dark_oak_leaves"); - private static final List NEW_SLABS = List.of("minecraft:oak_slab", "minecraft:spruce_slab", "minecraft:birch_slab", "minecraft:jungle_slab", "minecraft:acacia_slab", "minecraft:dark_oak_slab", "minecraft:oak_double_slab", "minecraft:spruce_double_slab", "minecraft:birch_double_slab", "minecraft:jungle_double_slab", "minecraft:acacia_double_slab", "minecraft:dark_oak_double_slab"); - private static final List NEW_BLOCKS = Stream.of(NEW_WOODS, NEW_LEAVES, NEW_LEAVES2, NEW_SLABS, NEW_MISC).flatMap(List::stream).toList(); - - - static GeyserMappingItem remapItem(@SuppressWarnings("unused") Item item, GeyserMappingItem mapping) { - mapping = Conversion671_662.remapItem(item, mapping); - - String identifer = mapping.getBedrockIdentifier(); - - switch (identifer) { - case "minecraft:bogged_spawn_egg" -> { return mapping.withBedrockIdentifier("minecraft:creeper_spawn_egg"); } - case "minecraft:grass_block" -> { return mapping.withBedrockIdentifier("minecraft:grass"); } - case "minecraft:vault" -> { return mapping.withBedrockIdentifier("minecraft:trial_spawner"); } - case "minecraft:wind_charge" -> { return mapping.withBedrockIdentifier("minecraft:snowball"); } - }; - - if (NEW_WOODS.contains(identifer)) { - switch (identifer) { - case "minecraft:oak_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(0); } - case "minecraft:spruce_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(1); } - case "minecraft:birch_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(2); } - case "minecraft:jungle_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(3); } - case "minecraft:acacia_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(4); } - case "minecraft:dark_oak_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(5); } - case "minecraft:stripped_oak_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(8); } - case "minecraft:stripped_spruce_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(9); } - case "minecraft:stripped_birch_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(10); } - case "minecraft:stripped_jungle_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(11); } - case "minecraft:stripped_acacia_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(12); } - case "minecraft:stripped_dark_oak_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(13); } - } - } - - if (NEW_SLABS.contains(identifer)) { - switch (identifer) { - case "minecraft:oak_slab" -> { return mapping.withBedrockIdentifier("minecraft:wooden_slab").withBedrockData(0); } - case "minecraft:spruce_slab" -> { return mapping.withBedrockIdentifier("minecraft:wooden_slab").withBedrockData(1); } - case "minecraft:birch_slab" -> { return mapping.withBedrockIdentifier("minecraft:wooden_slab").withBedrockData(2); } - case "minecraft:jungle_slab" -> { return mapping.withBedrockIdentifier("minecraft:wooden_slab").withBedrockData(3); } - case "minecraft:acacia_slab" -> { return mapping.withBedrockIdentifier("minecraft:wooden_slab").withBedrockData(4); } - case "minecraft:dark_oak_slab" -> { return mapping.withBedrockIdentifier("minecraft:wooden_slab").withBedrockData(5); } - } - } - - if (NEW_LEAVES.contains(identifer) || NEW_LEAVES2.contains(identifer)) { - switch (identifer) { - case "minecraft:oak_leaves" -> { return mapping.withBedrockIdentifier("minecraft:leaves").withBedrockData(0); } - case "minecraft:spruce_leaves" -> { return mapping.withBedrockIdentifier("minecraft:leaves").withBedrockData(1); } - case "minecraft:birch_leaves" -> { return mapping.withBedrockIdentifier("minecraft:leaves").withBedrockData(2); } - case "minecraft:jungle_leaves" -> { return mapping.withBedrockIdentifier("minecraft:leaves").withBedrockData(3); } - case "minecraft:acacia_leaves" -> { return mapping.withBedrockIdentifier("minecraft:leaves2").withBedrockData(0); } - case "minecraft:dark_oak_leaves" -> { return mapping.withBedrockIdentifier("minecraft:leaves2").withBedrockData(1); } - } - } - - return mapping; - } - - static NbtMap remapBlock(NbtMap tag) { - tag = Conversion671_662.remapBlock(tag); - - final String name = tag.getString("name"); - - if (!NEW_BLOCKS.contains(name)) { - return tag; - } - - String replacement; - - if (name.equals("minecraft:grass_block")) { - replacement = "minecraft:grass"; - - NbtMapBuilder builder = tag.toBuilder(); - builder.putString("name", replacement); - - return builder.build(); - } - - if (name.equals("minecraft:vault")) { - replacement = "minecraft:trial_spawner"; - - NbtMapBuilder statesBuilder = NbtMap.builder() - .putInt("trial_spawner_state", 0); - - NbtMapBuilder builder = tag.toBuilder(); - builder.putString("name", replacement); - builder.putCompound("states", statesBuilder.build()); - - return builder.build(); - } - - if (NEW_WOODS.contains(name)) { - replacement = "minecraft:wood"; - - NbtMap states = tag.getCompound("states"); - boolean stripped = name.startsWith("minecraft:stripped_"); - String woodType = name.replaceAll("minecraft:|_wood|stripped_", ""); - - NbtMapBuilder statesBuilder = states.toBuilder() - .putString("wood_type", woodType) - .putBoolean("stripped_bit", stripped); - - NbtMapBuilder builder = tag.toBuilder() - .putString("name", replacement) - .putCompound("states", statesBuilder.build()); - - return builder.build(); - } - - if (NEW_LEAVES.contains(name) || NEW_LEAVES2.contains(name)) { - boolean leaves2 = NEW_LEAVES2.contains(name); - replacement = leaves2 ? "minecraft:leaves2" : "minecraft:leaves"; - - NbtMap states = tag.getCompound("states"); - String leafType = name.replaceAll("minecraft:|_leaves", ""); - - NbtMapBuilder statesBuilder = states.toBuilder() - .putString(leaves2 ? "new_leaf_type" : "old_leaf_type", leafType); - - NbtMapBuilder builder = tag.toBuilder() - .putString("name", replacement) - .putCompound("states", statesBuilder.build()); - - return builder.build(); - } - - - if (NEW_SLABS.contains(name)) { - replacement = name.contains("double") ? "minecraft:double_wooden_slab" : "minecraft:wooden_slab"; - - NbtMap states = tag.getCompound("states"); - String woodType = name.replaceAll("minecraft:|_double|_slab", ""); - - NbtMapBuilder statesBuilder = states.toBuilder() - .putString("wood_type", woodType); - - NbtMapBuilder builder = tag.toBuilder() - .putString("name", replacement) - .putCompound("states", statesBuilder.build()); - - return builder.build(); - } - - return tag; - } -} diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion671_662.java b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion671_662.java deleted file mode 100644 index 29ab3f2e5..000000000 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion671_662.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.geyser.registry.populator; - -import org.cloudburstmc.nbt.NbtMap; -import org.cloudburstmc.nbt.NbtMapBuilder; -import org.geysermc.geyser.item.type.Item; -import org.geysermc.geyser.registry.type.GeyserMappingItem; - -import java.util.List; -import java.util.stream.Stream; - -public class Conversion671_662 { - private static final List NEW_MISC = List.of("minecraft:heavy_core", "minecraft:mace", "minecraft:flow_banner_pattern", "minecraft:guster_banner_pattern", "minecraft:flow_armor_trim_smithing_template", "minecraft:bolt_armor_trim_smithing_template", "minecraft:flow_pottery_sherd", "minecraft:guster_pottery_sherd", "minecraft:scrape_pottery_sherd", "minecraft:breeze_rod"); - private static final List NEW_CORAL_FANS = List.of("minecraft:tube_coral_fan", "minecraft:brain_coral_fan", "minecraft:bubble_coral_fan", "minecraft:fire_coral_fan", "minecraft:horn_coral_fan"); - private static final List NEW_DEAD_CORAL_FANS = List.of("minecraft:dead_tube_coral_fan", "minecraft:dead_brain_coral_fan", "minecraft:dead_bubble_coral_fan", "minecraft:dead_fire_coral_fan", "minecraft:dead_horn_coral_fan"); - private static final List NEW_FLOWERS = List.of("minecraft:poppy", "minecraft:blue_orchid", "minecraft:allium", "minecraft:azure_bluet", "minecraft:red_tulip", "minecraft:orange_tulip", "minecraft:white_tulip", "minecraft:pink_tulip", "minecraft:oxeye_daisy", "minecraft:cornflower", "minecraft:lily_of_the_valley"); - private static final List NEW_SAPLINGS = List.of("minecraft:oak_sapling", "minecraft:spruce_sapling", "minecraft:birch_sapling", "minecraft:jungle_sapling", "minecraft:acacia_sapling", "minecraft:dark_oak_sapling", "minecraft:bamboo_sapling"); - private static final List NEW_BLOCKS = Stream.of(NEW_MISC, NEW_CORAL_FANS, NEW_DEAD_CORAL_FANS, NEW_FLOWERS, NEW_SAPLINGS).flatMap(List::stream).toList(); - - static GeyserMappingItem remapItem(@SuppressWarnings("unused") Item item, GeyserMappingItem mapping) { - String identifer = mapping.getBedrockIdentifier(); - - if (!NEW_BLOCKS.contains(identifer)) { - return mapping; - } - - switch (identifer) { - case "minecraft:bolt_armor_trim_smithing_template" -> { return mapping.withBedrockIdentifier("minecraft:wayfinder_armor_trim_smithing_template"); } - case "minecraft:breeze_rod" -> { return mapping.withBedrockIdentifier("minecraft:blaze_rod"); } - case "minecraft:flow_armor_trim_smithing_template" -> { return mapping.withBedrockIdentifier("minecraft:spire_armor_trim_smithing_template"); } - case "minecraft:flow_banner_pattern", "minecraft:guster_banner_pattern" -> { return mapping.withBedrockIdentifier("minecraft:globe_banner_pattern"); } - case "minecraft:flow_pottery_sherd" -> { return mapping.withBedrockIdentifier("minecraft:skull_pottery_sherd"); } - case "minecraft:guster_pottery_sherd" -> { return mapping.withBedrockIdentifier("minecraft:shelter_pottery_sherd"); } - case "minecraft:scrape_pottery_sherd" -> { return mapping.withBedrockIdentifier("minecraft:heartbreak_pottery_sherd"); } - case "minecraft:heavy_core" -> { return mapping.withBedrockIdentifier("minecraft:conduit"); } - case "minecraft:mace" -> { return mapping.withBedrockIdentifier("minecraft:netherite_axe"); } - } - - if (NEW_FLOWERS.contains(identifer)) { - switch (identifer) { - case "minecraft:poppy" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(0); } - case "minecraft:blue_orchid" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(1); } - case "minecraft:allium" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(2); } - case "minecraft:azure_bluet" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(3); } - case "minecraft:red_tulip" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(4); } - case "minecraft:orange_tulip" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(5); } - case "minecraft:white_tulip" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(6); } - case "minecraft:pink_tulip" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(7); } - case "minecraft:oxeye_daisy" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(8); } - case "minecraft:cornflower" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(9); } - case "minecraft:lily_of_the_valley" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(10); } - } - } - - if (NEW_SAPLINGS.contains(identifer)) { - switch (identifer) { - case "minecraft:oak_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(0); } - case "minecraft:spruce_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(1); } - case "minecraft:birch_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(2); } - case "minecraft:jungle_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(3); } - case "minecraft:acacia_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(4); } - case "minecraft:dark_oak_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(5); } - } - } - - if (NEW_CORAL_FANS.contains(identifer)) { - switch (identifer) { - case "minecraft:tube_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan").withBedrockData(0); } - case "minecraft:brain_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan").withBedrockData(1); } - case "minecraft:bubble_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan").withBedrockData(2); } - case "minecraft:fire_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan").withBedrockData(3); } - case "minecraft:horn_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan").withBedrockData(4); } - } - } - - if (NEW_DEAD_CORAL_FANS.contains(identifer)) { - switch (identifer) { - case "minecraft:dead_tube_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan_dead").withBedrockData(0); } - case "minecraft:dead_brain_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan_dead").withBedrockData(1); } - case "minecraft:dead_bubble_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan_dead").withBedrockData(2); } - case "minecraft:dead_fire_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan_dead").withBedrockData(3); } - case "minecraft:dead_horn_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan_dead").withBedrockData(4); } - } - } - - return mapping; - } - - static NbtMap remapBlock(NbtMap tag) { - final String name = tag.getString("name"); - - if (!NEW_BLOCKS.contains(name)) { - return tag; - } - - if (name.equals("minecraft:bamboo_sapling")) { - NbtMap states = tag.getCompound("states") - .toBuilder() - .putString("sapling_type", "oak") - .build(); - - return tag.toBuilder().putCompound("states", states).build(); - } - - String replacement; - - if (name.equals("minecraft:heavy_core")) { - replacement = "minecraft:conduit"; - - NbtMapBuilder builder = tag.toBuilder(); - builder.putString("name", replacement); - - return builder.build(); - } - - if (NEW_SAPLINGS.contains(name)) { - replacement = "minecraft:sapling"; - String saplingType = name.replaceAll("minecraft:|_sapling", "");; - - NbtMap states = tag.getCompound("states") - .toBuilder() - .putString("sapling_type", saplingType) - .build(); - - return tag.toBuilder().putString("name", replacement).putCompound("states", states).build(); - } - - if (NEW_FLOWERS.contains(name)) { - replacement = "minecraft:red_flower"; - String flowerType; - - switch (name) { - case "minecraft:poppy" -> flowerType = "poppy"; - case "minecraft:blue_orchid" -> flowerType = "orchid"; - case "minecraft:allium" -> flowerType = "allium"; - case "minecraft:azure_bluet" -> flowerType = "houstonia"; - case "minecraft:red_tulip" -> flowerType = "tulip_red"; - case "minecraft:orange_tulip" -> flowerType = "tulip_orange"; - case "minecraft:white_tulip" -> flowerType = "tulip_white"; - case "minecraft:pink_tulip" -> flowerType = "tulip_pink"; - case "minecraft:oxeye_daisy" -> flowerType = "oxeye"; - case "minecraft:cornflower" -> flowerType = "cornflower"; - case "minecraft:lily_of_the_valley" -> flowerType = "lily_of_the_valley"; - default -> throw new IllegalStateException("Unexpected value: " + name); - } - - NbtMap states = tag.getCompound("states") - .toBuilder() - .putString("flower_type", flowerType) - .build(); - - return tag.toBuilder().putString("name", replacement).putCompound("states", states).build(); - } - - boolean isLiveCoralFan = NEW_CORAL_FANS.contains(name); - boolean isDeadCoralFan = NEW_DEAD_CORAL_FANS.contains(name); - - if (isLiveCoralFan || isDeadCoralFan) { - replacement = isLiveCoralFan ? "minecraft:coral_fan" : "minecraft:coral_fan_dead"; - String coralColor; - - switch (name) { - case "minecraft:tube_coral_fan", "minecraft:dead_tube_coral_fan" -> coralColor = "blue"; - case "minecraft:brain_coral_fan", "minecraft:dead_brain_coral_fan" -> coralColor = "pink"; - case "minecraft:bubble_coral_fan", "minecraft:dead_bubble_coral_fan" -> coralColor = "purple"; - case "minecraft:fire_coral_fan", "minecraft:dead_fire_coral_fan" -> coralColor = "yellow"; - case "minecraft:horn_coral_fan", "minecraft:dead_horn_coral_fan" -> coralColor = "red"; - default -> throw new IllegalStateException("Unexpected value: " + name); - } - - NbtMap states = tag.getCompound("states") - .toBuilder() - .putString("coral_color", coralColor) - .build(); - - return tag.toBuilder().putString("name", replacement).putCompound("states", states).build(); - } - - return tag; - } -} \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion685_671.java b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion685_671.java new file mode 100644 index 000000000..250fd9d9f --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion685_671.java @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.registry.populator; + +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; +import org.geysermc.geyser.item.type.Item; +import org.geysermc.geyser.registry.type.GeyserMappingItem; + +import java.util.List; +import java.util.stream.Stream; + +public class Conversion685_671 { + private static final List NEW_CORAL_BLOCKS = List.of("minecraft:tube_coral_block", "minecraft:brain_coral_block", "minecraft:bubble_coral_block", "minecraft:fire_coral_block", "minecraft:horn_coral_block", "minecraft:dead_tube_coral_block", "minecraft:dead_brain_coral_block", "minecraft:dead_bubble_coral_block", "minecraft:dead_fire_coral_block", "minecraft:dead_horn_coral_block"); + private static final List NEW_DOUBLE_PLANTS = List.of("minecraft:sunflower", "minecraft:lilac", "minecraft:tall_grass", "minecraft:large_fern", "minecraft:rose_bush", "minecraft:peony"); + private static final List NEW_STONE_BLOCK_SLABS = List.of("minecraft:smooth_stone_slab", "minecraft:sandstone_slab", "minecraft:petrified_oak_slab", "minecraft:cobblestone_slab", "minecraft:brick_slab", "minecraft:stone_brick_slab", "minecraft:quartz_slab", "minecraft:nether_brick_slab"); + private static final List NEW_TALLGRASSES = List.of("minecraft:fern", "minecraft:short_grass"); + private static final List OMINOUS_BLOCKS = List.of("minecraft:trial_spawner", "minecraft:vault"); + private static final List NEW_BLOCKS = Stream.of(NEW_CORAL_BLOCKS, NEW_DOUBLE_PLANTS, NEW_STONE_BLOCK_SLABS, NEW_TALLGRASSES).flatMap(List::stream).toList(); + private static final List MODIFIED_BLOCKS = Stream.of(NEW_BLOCKS, OMINOUS_BLOCKS).flatMap(List::stream).toList(); + + static GeyserMappingItem remapItem(@SuppressWarnings("unused") Item item, GeyserMappingItem mapping) { + String identifer = mapping.getBedrockIdentifier(); + + if (!NEW_BLOCKS.contains(identifer)) { + return mapping; + } + + if (NEW_CORAL_BLOCKS.contains(identifer)) { + switch (identifer) { + case "minecraft:tube_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(0); } + case "minecraft:brain_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(1); } + case "minecraft:bubble_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(2); } + case "minecraft:fire_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(3); } + case "minecraft:horn_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(4); } + case "minecraft:dead_tube_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(8); } + case "minecraft:dead_brain_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(9); } + case "minecraft:dead_bubble_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(10); } + case "minecraft:dead_fire_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(11); } + case "minecraft:dead_horn_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(12); } + } + } + + if (NEW_DOUBLE_PLANTS.contains(identifer)) { + switch (identifer) { + case "minecraft:sunflower" -> { return mapping.withBedrockIdentifier("minecraft:double_plant").withBedrockData(0); } + case "minecraft:lilac" -> { return mapping.withBedrockIdentifier("minecraft:double_plant").withBedrockData(1); } + case "minecraft:tall_grass" -> { return mapping.withBedrockIdentifier("minecraft:double_plant").withBedrockData(2); } + case "minecraft:large_fern" -> { return mapping.withBedrockIdentifier("minecraft:double_plant").withBedrockData(3); } + case "minecraft:rose_bush" -> { return mapping.withBedrockIdentifier("minecraft:double_plant").withBedrockData(4); } + case "minecraft:peony" -> { return mapping.withBedrockIdentifier("minecraft:double_plant").withBedrockData(5); } + } + } + + if (NEW_STONE_BLOCK_SLABS.contains(identifer)) { + switch (identifer) { + case "minecraft:smooth_stone_slab" -> { return mapping.withBedrockIdentifier("minecraft:stone_block_slab").withBedrockData(0); } + case "minecraft:sandstone_slab" -> { return mapping.withBedrockIdentifier("minecraft:stone_block_slab").withBedrockData(1); } + case "minecraft:petrified_oak_slab" -> { return mapping.withBedrockIdentifier("minecraft:stone_block_slab").withBedrockData(2); } + case "minecraft:cobblestone_slab" -> { return mapping.withBedrockIdentifier("minecraft:stone_block_slab").withBedrockData(3); } + case "minecraft:brick_slab" -> { return mapping.withBedrockIdentifier("minecraft:stone_block_slab").withBedrockData(4); } + case "minecraft:stone_brick_slab" -> { return mapping.withBedrockIdentifier("minecraft:stone_block_slab").withBedrockData(5); } + case "minecraft:quartz_slab" -> { return mapping.withBedrockIdentifier("minecraft:stone_block_slab").withBedrockData(6); } + case "minecraft:nether_brick_slab" -> { return mapping.withBedrockIdentifier("minecraft:stone_block_slab").withBedrockData(7); } + } + } + + if (NEW_TALLGRASSES.contains(identifer)) { + switch (identifer) { + case "minecraft:short_grass" -> { return mapping.withBedrockIdentifier("minecraft:tallgrass").withBedrockData(1); } + case "minecraft:fern" -> { return mapping.withBedrockIdentifier("minecraft:tallgrass").withBedrockData(2); } + } + } + + return mapping; + } + + static NbtMap remapBlock(NbtMap tag) { + final String name = tag.getString("name"); + + if (!MODIFIED_BLOCKS.contains(name)) { + return tag; + } + + if (OMINOUS_BLOCKS.contains(name)) { + NbtMapBuilder builder = tag.getCompound("states").toBuilder(); + builder.remove("ominous"); + return tag.toBuilder().putCompound("states", builder.build()).build(); + } + + String replacement; + + if (NEW_CORAL_BLOCKS.contains(name)) { + replacement = "minecraft:coral_block"; + String coralColor; + boolean deadBit = name.startsWith("minecraft:dead_"); + + switch(name) { + case "minecraft:tube_coral_block", "minecraft:dead_tube_coral_block" -> coralColor = "blue"; + case "minecraft:brain_coral_block", "minecraft:dead_brain_coral_block" -> coralColor = "pink"; + case "minecraft:bubble_coral_block", "minecraft:dead_bubble_coral_block" -> coralColor = "purple"; + case "minecraft:fire_coral_block", "minecraft:dead_fire_coral_block" -> coralColor = "yellow"; + case "minecraft:horn_coral_block", "minecraft:dead_horn_coral_block" -> coralColor = "red"; + default -> throw new IllegalStateException("Unexpected value: " + name); + } + + NbtMap states = tag.getCompound("states") + .toBuilder() + .putString("coral_color", coralColor) + .putBoolean("dead_bit", deadBit) + .build(); + + return tag.toBuilder().putString("name", replacement).putCompound("states", states).build(); + } + + if (NEW_DOUBLE_PLANTS.contains(name)) { + replacement = "minecraft:double_plant"; + String doublePlantType; + + switch(name) { + case "minecraft:sunflower" -> doublePlantType = "sunflower"; + case "minecraft:lilac" -> doublePlantType = "syringa"; + case "minecraft:tall_grass" -> doublePlantType = "grass"; + case "minecraft:large_fern" -> doublePlantType = "fern"; + case "minecraft:rose_bush" -> doublePlantType = "rose"; + case "minecraft:peony" -> doublePlantType = "paeonia"; + default -> throw new IllegalStateException("Unexpected value: " + name); + } + + NbtMap states = tag.getCompound("states") + .toBuilder() + .putString("double_plant_type", doublePlantType) + .build(); + + return tag.toBuilder().putString("name", replacement).putCompound("states", states).build(); + } + + if (NEW_STONE_BLOCK_SLABS.contains(name)) { + replacement = "minecraft:stone_block_slab"; + String stoneSlabType; + + switch(name) { + case "minecraft:smooth_stone_slab" -> stoneSlabType = "smooth_stone"; + case "minecraft:sandstone_slab" -> stoneSlabType = "sandstone"; + case "minecraft:petrified_oak_slab" -> stoneSlabType = "wood"; + case "minecraft:cobblestone_slab" -> stoneSlabType = "cobblestone"; + case "minecraft:brick_slab" -> stoneSlabType = "brick"; + case "minecraft:stone_brick_slab" -> stoneSlabType = "stone_brick"; + case "minecraft:quartz_slab" -> stoneSlabType = "quartz"; + case "minecraft:nether_brick_slab" -> stoneSlabType = "nether_brick"; + default -> throw new IllegalStateException("Unexpected value: " + name); + } + + NbtMap states = tag.getCompound("states") + .toBuilder() + .putString("stone_slab_type", stoneSlabType) + .build(); + + return tag.toBuilder().putString("name", replacement).putCompound("states", states).build(); + } + + if (NEW_TALLGRASSES.contains(name)) { + replacement = "minecraft:tallgrass"; + String tallGrassType; + + switch(name) { + case "minecraft:short_grass" -> tallGrassType = "tall"; + case "minecraft:fern" -> tallGrassType = "fern"; + default -> throw new IllegalStateException("Unexpected value: " + name); + } + + NbtMap states = tag.getCompound("states") + .toBuilder() + .putString("tall_grass_type", tallGrassType) + .build(); + + return tag.toBuilder().putString("name", replacement).putCompound("states", states).build(); + } + + return tag; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java index b2d238ddb..a43df3f52 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java @@ -53,7 +53,6 @@ import org.geysermc.geyser.level.block.GeyserCustomBlockData; import org.geysermc.geyser.level.block.GeyserCustomBlockState; import org.geysermc.geyser.level.block.GeyserGeometryComponent; import org.geysermc.geyser.level.block.GeyserMaterialInstance; -import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.mappings.MappingsConfigReader; import org.geysermc.geyser.registry.type.CustomSkull; @@ -325,13 +324,11 @@ public class CustomBlockRegistryPopulator { // meaning of this version is unknown, but it's required for tags to work and should probably be checked periodically .putInt("molangVersion", 1) .putList("permutations", NbtType.COMPOUND, permutations) - .putList("properties", NbtType.COMPOUND, properties); - - if (GameProtocol.is1_20_60orHigher(protocolVersion)) { - propertyTag.putCompound("vanilla_block_data", NbtMap.builder() + .putList("properties", NbtType.COMPOUND, properties) + .putCompound("vanilla_block_data", NbtMap.builder() .putInt("block_id", BLOCK_ID.getAndIncrement()) .build()); - } + return new BlockPropertyData(customBlock.identifier(), propertyTag.build()); } diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java index 10d87a8a9..a6fa164c1 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java @@ -44,7 +44,6 @@ import org.geysermc.geyser.item.GeyserCustomMappingData; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.components.WearableSlot; import org.geysermc.geyser.item.type.Item; -import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.registry.mappings.MappingsConfigReader; import org.geysermc.geyser.registry.type.GeyserMappingItem; import org.geysermc.geyser.registry.type.ItemMapping; @@ -260,18 +259,11 @@ public class CustomItemRegistryPopulator { } private static void setupBasicItemInfo(int maxDamage, int stackSize, boolean displayHandheld, CustomItemData customItemData, NbtMapBuilder itemProperties, NbtMapBuilder componentBuilder, int protocolVersion) { - NbtMap iconMap; - if (GameProtocol.is1_20_60orHigher(protocolVersion)) { - iconMap = NbtMap.builder() - .putCompound("textures", NbtMap.builder() - .putString("default", customItemData.icon()) - .build()) - .build(); - } else { - iconMap = NbtMap.builder() - .putString("texture", customItemData.icon()) - .build(); - } + NbtMap iconMap = NbtMap.builder() + .putCompound("textures", NbtMap.builder() + .putString("default", customItemData.icon()) + .build()) + .build(); itemProperties.putCompound("minecraft:icon", iconMap); if (customItemData.creativeCategory().isPresent()) { @@ -427,64 +419,56 @@ public class CustomItemRegistryPopulator { // Make bows, tridents, and crossbows enchantable itemProperties.putInt("enchantable_value", 1); - if (GameProtocol.is1_20_60orHigher(protocolVersion)) { - componentBuilder.putCompound("minecraft:use_modifiers", NbtMap.builder() - .putFloat("use_duration", 100F) - .putFloat("movement_modifier", 0.35F) - .build()); + componentBuilder.putCompound("minecraft:use_modifiers", NbtMap.builder() + .putFloat("use_duration", 100F) + .putFloat("movement_modifier", 0.35F) + .build()); - switch (mapping) { - case "minecraft:bow" -> { - itemProperties.putString("enchantable_slot", "bow"); - itemProperties.putInt("frame_count", 3); + switch (mapping) { + case "minecraft:bow" -> { + itemProperties.putString("enchantable_slot", "bow"); + itemProperties.putInt("frame_count", 3); - componentBuilder.putCompound("minecraft:shooter", NbtMap.builder() - .putList("ammunition", NbtType.COMPOUND, List.of( - NbtMap.builder() - .putCompound("item", NbtMap.builder() - .putString("name", "minecraft:arrow") - .build()) - .putBoolean("use_offhand", true) - .putBoolean("search_inventory", true) - .build() - )) - .putFloat("max_draw_duration", 0f) - .putBoolean("charge_on_draw", true) - .putBoolean("scale_power_by_draw_duration", true) - .build()); - componentBuilder.putInt("minecraft:use_duration", 999); - } - case "minecraft:trident" -> { - itemProperties.putString("enchantable_slot", "trident"); - componentBuilder.putInt("minecraft:use_duration", 999); - } - case "minecraft:crossbow" -> { - itemProperties.putString("enchantable_slot", "crossbow"); - itemProperties.putInt("frame_count", 10); - - componentBuilder.putCompound("minecraft:shooter", NbtMap.builder() - .putList("ammunition", NbtType.COMPOUND, List.of( - NbtMap.builder() - .putCompound("item", NbtMap.builder() - .putString("name", "minecraft:arrow") - .build()) - .putBoolean("use_offhand", true) - .putBoolean("search_inventory", true) - .build() - )) - .putFloat("max_draw_duration", 1f) - .putBoolean("charge_on_draw", true) - .putBoolean("scale_power_by_draw_duration", true) - .build()); - componentBuilder.putInt("minecraft:use_duration", 999); - } + componentBuilder.putCompound("minecraft:shooter", NbtMap.builder() + .putList("ammunition", NbtType.COMPOUND, List.of( + NbtMap.builder() + .putCompound("item", NbtMap.builder() + .putString("name", "minecraft:arrow") + .build()) + .putBoolean("use_offhand", true) + .putBoolean("search_inventory", true) + .build() + )) + .putFloat("max_draw_duration", 0f) + .putBoolean("charge_on_draw", true) + .putBoolean("scale_power_by_draw_duration", true) + .build()); + componentBuilder.putInt("minecraft:use_duration", 999); } - } else { - // ensure client moves at slow speed while charging (note: this was calculated by hand as the movement modifer value does not seem to scale linearly) - componentBuilder.putCompound("minecraft:chargeable", NbtMap.builder().putFloat("movement_modifier", 0.35F).build()); + case "minecraft:trident" -> { + itemProperties.putString("enchantable_slot", "trident"); + componentBuilder.putInt("minecraft:use_duration", 999); + } + case "minecraft:crossbow" -> { + itemProperties.putString("enchantable_slot", "crossbow"); + itemProperties.putInt("frame_count", 10); - // keep item enchantable; also works on 1.20.50 - itemProperties.putString("enchantable_slot", mapping.replace("minecraft:", "")); + componentBuilder.putCompound("minecraft:shooter", NbtMap.builder() + .putList("ammunition", NbtType.COMPOUND, List.of( + NbtMap.builder() + .putCompound("item", NbtMap.builder() + .putString("name", "minecraft:arrow") + .build()) + .putBoolean("use_offhand", true) + .putBoolean("search_inventory", true) + .build() + )) + .putFloat("max_draw_duration", 1f) + .putBoolean("charge_on_draw", true) + .putBoolean("scale_power_by_draw_duration", true) + .build()); + componentBuilder.putInt("minecraft:use_duration", 999); + } } } diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java index d3a4bed84..5fcea504f 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java @@ -38,11 +38,8 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; -import org.cloudburstmc.protocol.bedrock.codec.v622.Bedrock_v622; -import org.cloudburstmc.protocol.bedrock.codec.v630.Bedrock_v630; -import org.cloudburstmc.protocol.bedrock.codec.v649.Bedrock_v649; -import org.cloudburstmc.protocol.bedrock.codec.v662.Bedrock_v662; import org.cloudburstmc.protocol.bedrock.codec.v671.Bedrock_v671; +import org.cloudburstmc.protocol.bedrock.codec.v685.Bedrock_v685; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; @@ -62,7 +59,6 @@ import org.geysermc.geyser.inventory.item.StoredItemMappings; import org.geysermc.geyser.item.GeyserCustomMappingData; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; -import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.*; @@ -91,11 +87,8 @@ public class ItemRegistryPopulator { public static void populate() { List paletteVersions = new ArrayList<>(3); - paletteVersions.add(new PaletteVersion("1_20_40", Bedrock_v622.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion630_622::remapItem)); - paletteVersions.add(new PaletteVersion("1_20_50", Bedrock_v630.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion649_630::remapItem)); - paletteVersions.add(new PaletteVersion("1_20_60", Bedrock_v649.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion662_649::remapItem)); - paletteVersions.add(new PaletteVersion("1_20_70", Bedrock_v662.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion671_662::remapItem)); - paletteVersions.add(new PaletteVersion("1_20_80", Bedrock_v671.CODEC.getProtocolVersion())); + paletteVersions.add(new PaletteVersion("1_20_80", Bedrock_v671.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion685_671::remapItem)); + paletteVersions.add(new PaletteVersion("1_21_0", Bedrock_v685.CODEC.getProtocolVersion())); GeyserBootstrap bootstrap = GeyserImpl.getInstance().getBootstrap(); @@ -602,18 +595,11 @@ public class ItemRegistryPopulator { NbtMapBuilder componentBuilder = NbtMap.builder(); // Conveniently, as of 1.16.200, the furnace minecart has a texture AND translation string already. // Not so conveniently, the way to set an icon changed in 1.20.60 - NbtMap iconMap; - if (GameProtocol.is1_20_60orHigher(protocolVersion)) { - iconMap = NbtMap.builder() - .putCompound("textures", NbtMap.builder() - .putString("default", "minecart_furnace") - .build()) - .build(); - } else { - iconMap = NbtMap.builder() - .putString("texture", "minecart_furnace") - .build(); - } + NbtMap iconMap = NbtMap.builder() + .putCompound("textures", NbtMap.builder() + .putString("default", "minecart_furnace") + .build()) + .build(); itemProperties.putCompound("minecraft:icon", iconMap); componentBuilder.putCompound("minecraft:display_name", NbtMap.builder().putString("value", "item.minecartFurnace.name").build()); diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java index 928ab8df9..4c6d53518 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java @@ -35,6 +35,7 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtUtils; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; +import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.RecipeUnlockingRequirement; import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.MultiRecipeData; import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.RecipeData; import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapedRecipeData; @@ -173,7 +174,7 @@ public class RecipeRegistryPopulator { /* Convert end */ return ShapedRecipeData.shaped(uuid.toString(), shape.get(0).length(), shape.size(), - inputs.stream().map(ItemDescriptorWithCount::fromItem).toList(), Collections.singletonList(output), uuid, "crafting_table", 0, netId, false); + inputs.stream().map(ItemDescriptorWithCount::fromItem).toList(), Collections.singletonList(output), uuid, "crafting_table", 0, netId, false, RecipeUnlockingRequirement.INVALID); } List inputs = new ObjectArrayList<>(); for (JsonNode entry : node.get("inputs")) { @@ -196,7 +197,7 @@ public class RecipeRegistryPopulator { inputs.stream().map(ItemDescriptorWithCount::fromItem).toList(), Collections.singletonList(output), uuid, "crafting_table", 0, netId); } return ShapelessRecipeData.shapeless(uuid.toString(), - inputs.stream().map(ItemDescriptorWithCount::fromItem).toList(), Collections.singletonList(output), uuid, "crafting_table", 0, netId); + inputs.stream().map(ItemDescriptorWithCount::fromItem).toList(), Collections.singletonList(output), uuid, "crafting_table", 0, netId, RecipeUnlockingRequirement.INVALID); } private static ItemData getBedrockItemFromIdentifierJson(ItemMapping mapping, JsonNode itemNode) { diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 69f61b181..9d2a3ef06 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -1546,6 +1546,10 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { startGamePacket.setRewindHistorySize(0); startGamePacket.setServerAuthoritativeBlockBreaking(false); + startGamePacket.setServerId(""); + startGamePacket.setWorldId(""); + startGamePacket.setScenarioId(""); + upstream.sendPacket(startGamePacket); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java index c6c3c7dd6..8fe1e96c0 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java @@ -35,7 +35,6 @@ import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater; import org.geysermc.geyser.level.block.Blocks; -import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.BlockEntityUtils; import org.geysermc.geyser.util.InventoryUtils; @@ -44,7 +43,6 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponen import org.geysermc.mcprotocollib.protocol.data.game.item.component.WritableBookContent; import org.geysermc.mcprotocollib.protocol.data.game.item.component.WrittenBookContent; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; -import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; import java.util.Collections; @@ -152,13 +150,6 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator } else if (lecternContainer.getBlockEntityTag() == null) { Vector3i position = lecternContainer.isUsingRealBlock() ? session.getLastInteractionBlockPosition() : inventory.getHolderPosition(); - // If shouldExpectLecternHandled returns true, this is already handled for us - // shouldRefresh means that we should boot out the client on our side because their lectern GUI isn't updated yet - // TODO: yeet after 1.20.60 is minimum supported version - boolean shouldRefresh = !session.getGeyser().getWorldManager().shouldExpectLecternHandled(session) - && !session.getLecternCache().contains(position) - && !GameProtocol.is1_20_60orHigher(session.getUpstream().getProtocolVersion()); - NbtMap blockEntityTag; if (book.getComponents() != null) { int pages = 0; @@ -205,16 +196,6 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator lecternContainer.setPosition(position); BlockEntityUtils.updateBlockEntity(session, blockEntityTag, position); - - if (shouldRefresh) { - // the lectern cache doesn't always exist; only when we must refresh - session.getLecternCache().add(position); - - // Close the window - we will reopen it once the client has this data synced - ServerboundContainerClosePacket closeWindowPacket = new ServerboundContainerClosePacket(lecternContainer.getJavaId()); - session.sendDownstreamGamePacket(closeWindowPacket); - InventoryUtils.closeInventory(session, inventory.getJavaId(), false); - } } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java index 36752e582..18d6a22eb 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java @@ -550,6 +550,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator { ContainerClosePacket packet = new ContainerClosePacket(); packet.setServerInitiated(true); packet.setId((byte) ContainerId.INVENTORY); + packet.setType(org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.INVENTORY); session.sendUpstreamPacket(packet); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java index 4bc727397..06531eff2 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java @@ -152,6 +152,7 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator { ContainerClosePacket packet = new ContainerClosePacket(); packet.setId((byte) inventory.getBedrockId()); packet.setServerInitiated(true); + packet.setType(ContainerType.MINECART_CHEST); session.sendUpstreamPacket(packet); return; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java index 1ea686536..959797d41 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java @@ -42,7 +42,6 @@ import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.level.block.type.BlockState; -import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; @@ -331,10 +330,6 @@ public class BedrockActionTranslator extends PacketTranslator1zWLFM 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

g-=;VUl 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⁡z#A(DebW+` zMVFDJn673(e$rwiG>C}p^W+Mb&qb)_BM;4~Ll9sU+WDy`ylsgqOlCCgE{W^w=Q9ftG=rf1?lNG43HgybgpKepyV?O~! zYf=@JAho$r?9YsY1r~cJM+j*1UIfp4Eia%Py!pjenTm2WUtYAn_h9GPB| zbH-Zq&CObLR^O+=MK2tSO_Xciy04tYRuqp((?G_wqYzHVkx%5;+Q72cgztwKp}hh0 zrX$+rKSX{K`hKl`M{PuYEt_?ggiFv2r9Vv|RUA#X28QTB$ylWu8lqRpiS$1j+P4PD zvkY{zL^`%6Ep*RH+_-rfW@fNdF8pPA8~7~Lx=!1W^95qi2PZDyV6L@KM45NV~jhuvk!xd>p{jkS0U z&liTf?u;Gg&ZUO{>u|qCn<`YVsUY5kJ>QJX)>TS5i`b_XFP3xXIj}{Y-sy5*yiaL> z4N@!Vp>5$e1lEJ?U1kDZx z=_eHw)q|`UVy`#;0hD{t`t+Q+(vkysW2cG9D-$t38P=u!z^lb&z+AXq!4KTqu2`(G zCPD{5YuD;)R9dW@n2vobw%{?yw#TrMa33Cn>M4cxtO1Yil~!II!FE?!KVTSbF6wyE# z&8hc^ZiHs><0+!pC)=Z>ir|(7z*z`+!R5KMX~M?fvEvA+c4^=&B%Tvqk*f>OLdHB1 zIDPOe)NQZrXU@aw@_t;3ZZTD?ernQzeqbX_1uzzv%{%bTvb-T<0jp&EEC4bVb~+8Q z$lkKu{u$R9CIdYo$77)4d13D{H z?^c5T!f!k3wdcZ+M)&r(e*O|X5cT{N;EziFar4ic!i|DV7#H$2?4LdYE3bprKe1+( z93PSvf~?#n@R9RVmCFlT9#lx^{w~ku?=3J5)+$-n5*6qP#8*t)e1on!LL5UYJ`XEbdHBY-JQQ45-txDcx)*DuM!1HmDSH>^A43saB4(I?E+ zQH9wBoT(W{juSGjLx#&SOMwBx{LeQPo2N%`xQVlJS11kXQCmjI^|}XEhyOR>{o8ikdm-bcB2(wWt?7GBqePtrzE^NUzfv}o^ZujIiRED6SkpiX-D;Az zYIXdIe#^kTdKfa45E>?(hd zJoVsXTGp>!M;LSio;Cj%baOB3><$nH-Oxsog1(hGo8U)owm{oA1!kBYR11|;vzn4_ z0Fa{;=@yx_Bn`I1yx!on-AYRU06D*&q|>H72*}}xjkAAaun0M>OMKxw`&4QjO=%(E&Yw; za?4l#0MoOJwR=8feX{|ahxnC!2T1|fZjh+M($%2soBASGJcI1S3o7Wj%yKOisX`i^ z9?wCGrDKWJFDskur^h@!(Ev9CzG}A|V6J`m5RtLpm;fO;Ek4gjeary4YgAfxstCve zz+D7;jbGE&!!%Ity@D)>Fblz(Nd4=s<~c6`~yqlC7>YUOdgJ@n1nGP?L5<2`KzDZ@|#z^%>KSyofu?lFiZVaKol9-kjT`b^4I3nZ^W zW5mMd^X}ejyst^MXT4LTpnUrR9k(0^0^R=coOOF8*Q7Ya+JpZ1Q)l{=$yY&Qf-(gU zk6M@T$Q-EzOc4C(*{eCzp`*kUn%DT~*JdXJVmbA%+~NWQ`W}#?}8TUBnl_UOn?De7=VdnB3y7#ELqQ z$zAxC@(6I=0Bi2^i=#AzHP;|3XX^)9b6FAC?d~uk8x^BW2muxYh%1-`L2RIUNjt}DmB$bAz}E%VsNzqNB_f}AY5U#{NV8nR)*TRW2EeU|8p~=B z1a8eg_Ae(OOJsOduBkkyJD+31(Jll~xI+?!06oC}FaYu4IAn-sU1K3BE` zxpVk4Hm;Ry3G|Tl-O$j$X9>u9ofi7LE?g0BfW3>~A#V&3r$sD~ogRD4Y6S`c+;ZY< z2q7{NMTzwQ$BRo~B3pW>^kaccvBP;yGPLo;2Kp@X7IAcE2y~nI(Z12e24O*U&+9Bx z0;4rp%>VsA2Hi7b53NuThBhI%hMg3tLki>tCUN<5hA>_zq2?Dcn zUo@wjI4UKsqW@uKQ6aJNtAg4Xmkb4>4U70M%U7UEkxCzTvMmU z9-eomfr3i!+mdLi{UG&@iRp*js27|RS?6?^&G)O+So;=>*qHB9S;xNCotVCavhX5O z1@h;Z$oNX^sYexw!i+qW8dXkE(*c9-?pb>Kn~&quljZ3g#@}CU;Wjjsi7;)45@Kv< zJrThsbXo>##rbeeeWqNtLhBu7+&1HP*P*P)J5Mp^(rB4{vF7Fj1ymSB&c99gD&&jL z7|?tu7v<4GVUkX_!FCQJJlUsuFilvu;m~acvMTuv#Nh zR>q^qC_JE3aZorO2^3Hd9yjc)vmr|p;ivobRv;U&=kx}%1_&X0Zf;+JCRaE^6wniF zN@hDU>nggc2UQLERL);h0rnhYjDbVQL}gcsOw~m&ZGTEH&=oy$Oq%Oj0o*yI_@H2f zpWqvQ{!9t-6Nb(*rk+7nQBsbr@jvF=ZdB}qQu>$p%Mrut`0|XXIZ#;C-qj-L1)+Y8 zbes$f$on@FXBQ3e2B7Z3J^xx9V+(Zc%R6gpZ*uQaLNBDm!FZiP2h6#;+VV@4cbCAU zEbUmvs(+na`GQZR(8=}AZBo7q1JW3x%=VX{T0|uJ=wZ0cmmHIrq|0ib)F7FqGi2+e z@d#a%X%ThQi}mLf0g3D*RYYK9%kz}zCuGWfoGJWZ_UC&pV7P@O91t3I1_2&{S&s3m z(v7Ur`-He*OLIK|Inn}vEB9Dv{nNwbOzJkEGFr0KFGxqocOxjOUzUOJC`W`qCa`?- zCj($JP`+J$if;+{3XRw?VS{fp01-k`qoZhT7clA$%h%?LZUOa}=si9K=5(66GC-z? zuG+$eE2LaO+KQ>rI`2cOee)`MF(9&pvnS$@>EcbMN1}+YP)0Yh2-gF-k+h&gx`?Dq z9grX~&v84pk^?f_CAzfNO#;r=JG(MrFZ@?sz5ppJSrmHT3zUs9t{FpFmI<1gGTZ4( zwP}g>;CjKt(>)gbX5DlB%>QihcR8p3Kf)X}#@IMb`#hb$m;T7Y%yb4|%YBhGZzi-p zz`a3Pyt(g(s9Tv!P#X$%B3@Fz^FuwM?lN{UD92Oaf3gc0cV;%K55<1CqZhwqvvuI1 zkb~mZSqJ9d3T~g#`LWE_wJr-_()&v;Boa2Y@~@IBJ$&e8agzp-w$`15q&D^_LmSfD zkaxljIo!F$dW{q?v7PaN-s)~?9IR9T>ee3msmb672clbT@vJH> zmN(f6BGKC|n>j1meG_tWG{02c>qs04Cm>UdG9g;hi{DNH*4Z1Bd;e-|95cJ0yMf}AwD+jd`@0<=z$x9^uo_OI0tC1^tso&52|#pXh>tQ@l;uSWGJ3Dc zxR)u6xg{M8M5<4_M;1Pr0c+9Vd@+2O{E#1AEh6r4r$U7XOD?^f8+){SnKa!mH zDEDUr*Ax!GsB5VB5Z?`sPw$<_BUibofd!$)t`k+M01+Zvde_l%^E;#9Bt&$gkx2#l zawT?V=H!6%WDqu-yvWObV`7q4bC~S~m5|;23b#CIk#}X8!B9~YWMOk97^~&lz0zM5 ze{^nwg_WFK5KRnNQu#M77-RlX z6tn~;FY5(EVw-|)A-nzPLddt;X`}uEF(hS{F~PO%T~iHIsKxo=GLwI$t=J@H9h_O< z8Q!4+ng!D5AQiWjY8JHmt*g5L?122#s)O>QTlY$6hHLKWWDgr@XV@4x` zV+EpY&DU|PmYD*)JO^3&(ZJitzOqI);crYt4%kn-lWL(xgMeH6v8k4pFbB}I#ncy) z{&D1*^3w*G0gId6AY6``HP<@tCB8{b*>i*;*H?JsA49Hy(O$GY;yRGSvkVY74*{-} zl#p+zbyE-3jSa0wJq3S=SrPJ6g;X;gWXMTv{E2J|7eyFy%0KzrULXuPhjFn}%P=5p z6$?fG*cCUfqcol%W+LomAMdhtKWFC`$&nygkI8Zm3S`L5>EU;@mhKYzwB>wx(p0~- zd`9TgxpR}<0l80MbIR6e<(UaHqkRS;MSsGij*b})i&S<8U~U@}a)`@5{w@ZDt=sHv z^-QBm??c(y zpl16#J#wf9xE}s>{QEj60m2_JbXmhDI{uxKxC!J>0=nAc$yOQ!sI7*ElSJiJ^Bn z;qD#y4(Ql#e@Y+w5&$lp^fv1A3gj+@`rSbGA;K6)m(%GxPtYt++dB`(2FpX{m)V2s$Xy#B z<0Z6V;!U>P+ifdiNTD1mbm+4H%j3z-WbVQ%kU&{%N8aiRj0scqfdNHX4H+cH3AI=U zP0IKB9T;{B6SZSGDAvn9Qs|JdhaUQoHE>#s!ZezcIyEQS<4sC3)ejZER>lgG2LwZLQ@62r9Sh46}_J2~n9)3v4;sfH8f zrm56U-BI?*62M$|H#cSSL9%UK2-o-BH#VX$?v7(Ngq=`A_l65$Cm4klGcQ=1veC-# z$glNL%$S(aJC#iEW&6}V$~C_qDh*|=L%jufL!%1OezkGz>)dAElt4jb?$~Y0cq6qR zkQ0jKh=e71WwK^XzEHOsN`?fyhFtA{AAR@DF3~`)c7*oxaH3H!5L^6EZ_FVW5^xv5 zZQh1I`IZ3RDfw>Q%-P3HkQn&wxN-zJ3WINN;qv>gaL1xfuSHUe=Pe6INHo_wM9fCf>y3(<>DZOq|hbA zH=qkoRUB_MFou4}fr}R~d^=`IH1Q|^Q=5TNh{mWbgC-Nxeg1uTXA%O(v7B{+Yl{2gtG<~{xxM?Gt!09o33+zfa_0yhElMlZOqyzC2Bna(}! zbuIwj?(mCSQBi3hkOJM&565?*L~qrnEYL3HWhy5}-<^GJO#57kl(ed_qN8D`mg4i$ zL}^%yGs&ZpnV}%OOf1q;O7Ik%@roZds)G4y<+?C!&4(mJZiwp4p8ggufaB<|79L%hg3LJEwNuR%9vDW>Ytp#$ zj~hoZ)Hd@RVYJNE5*mg;0%pYe(685Df_5;x3d4mkF#+fwA0lUm%jhkxNn>eNOmDqLKunfx#t1~M@o{@U8v|1rX*|f7K8S)nJfFz7 zwOFb{VR_4pjTt4Wwf(0^>(t;EgIna+T^=)DWRRe-U zpLOaoW-DWqNNpl901D&n68u_{0an>b&BiA zB;4o-dqjte|86b1l^t=(u=G`Em9*ezyO6~l|qhvm5@<=>zVu^}|2n`@G z(;7(mDHWhB3(V!M3oZyCca9w@DF*%9Taq|G2!B7e5C@oCkuS#kOgUhOGRMN}`5`8E zla1N>3&iA@hN?uU5lrsm#m8CYN0!u>9!cg|G&QI6m>zXAJDW?TnnalG1|8ouS?%^% zFg+U2{uGuDTM+q5N-t^6UJ|tA1`muUFo;RK!fZ(D=+4!2lgSJKpVzzG1UFd<4>D%0 zp67PnXkSfov1xO&>9$nh8ODwP2$tbGxv4nDb_GV8qx55c5JU8Kh+*y4&|54(Md_SP z`(DLW7_=iUEr}Bq2wvdYzyiLPHh2H|q&b!G|u?(?7wB>utiO>oW4p80xPtST;z}I~RVsg5&RTl=} z5XHcF!YMw2*q|igCXPAgq`sQPDCP=4IZlHiq2X@UVFd)X6=&>t==9tjvLLB`PIM7B zdjog0xR;rD5g;vG+P6f+0uHwB0Hmc``a(#v<~F!_rE!&0y7xMCTP)6%Y*R0xFNB{& z{=yhiCxP0=q5eVw5Jj}LODQ8U#(-YVXL|ulGaqoS&|`{cDSw)E)8RW+B>JA@rG@<_eqy?_w~;k2Tl56?x{hZyPMWRSf zebIm!{acpCrXS|9pP2G}v-2X`QCoDTOlwsnib|Ou!KKDFHg&*Nc2dSbPD0~PC9f-``o<^_jOW@L;I>$0ac?;kYn=kz4-tNxJ0Y87w z=iC_m1B4^YxbL!XLg8I7)CX-kG}UFcr7jOh^6x7-s>IxRmgj#bK^;XFnQ)d>)QSItSwhBlEPrz2E1k4WU+AKS_Tal#kyY{cZ% zary&FS(6+zI!2JQ(W=p`ZVJ3-Zod0`>MC;2+#HSai#NzUbCr5yfA5)l|KU}4H04wJ z6mUigNPV68_7igL4+TpUCDrBBjvpFZCDJP>M=iJ9t#`c3tlry5!ixk;yDqe3ku%X= z)*dcQ#Y6&t`F2++jnDH%QHG?b#D>3TmY5 zIWYj&{%AK#xETBsv6}Cg-x*4|{kzPTpaxHP1t48+3Aua;X;sY?0umxuFe7c6{wU+{VP0bVZD&*2XR$vIgI^CA_Re z31lZIi01mrSY3(o#x}1?lZxV)&R?RzDz6{G<+d{j9N+smqk}(3XJwLS0iPgBV2;WP zvmnIfX6|5b3J18NC+z6dNi#Ct<-Cb^qfzfjfTPZRDvYbhxiX1T${Mn1I~Tt(3EN%* z)LHtX%5k(S@I>uL#Okjq3vqwSx4x{J?C5a4kaMgHkci&D~TKz$RNVoWc zWG@3V&+?F_A5%JC(OPX@^$P_96>Hd1(o+^h#hN$~9F3@02ennZd7+9`gvsXCP@E)G zv8Lj1nE0{a3%Sk^Mm$c0D%Reg>b>%g9N<>0qyEh_2+m22_kE1FfZ&`Xjhy9x&a95j z`sn=wf$TtlrZcu%#9sq0$+Qyp*YezN(3+HDL`lht!J|;?(RHs%cqPaEiS*kWwIC60 zjH8lR17WtidE5cDoFMRQtA15T>JZ_#B>J&%K88+EqOrU~7|;a7&6xHd6T`q#iPK{n z_e)gTYFHMNe3CGdsNLj2L-+@HIdPldl5`Nn$s0@7PL;EeS~z%Rtw8K0z0Pecwju%q ztR2mG$LP8>sDxucLNoy`i}b1`~SqN zmM6kufR|0nhM$oXq!BCw?wV_q5$TRDf0M|Z3GQ=Le}8y48vM?YtP)C{%%16s@;KG7 z$pqmiyx(K5ibnQ>)nbQ-&{@g(#E{Mk*a@wn*6*i%Ak-33EZ^?|_lH7?vN}tZ@R!s9 zwHp#xP>9&SQ6^4ufb2=@6}cP1Fe*fk#vJls)mhg#L7{T7S2(@==|JzDLXT?!DQVoH#VZ2jM5b4_bOnxW%=FPlqz zcRg1uI}TLrV!D?-m8uCOvW%E@sur@(K?PAkvUHKu;JQ2Cj&iIf{YiV)4xRpJ%SPwt zfnZ-z;4IU#LiUy3=NZpIfJodQm!j|0f_7nX zdql7OhsI^JmKdw35Eu(0_F&5I4diY3-JPxXVB0FX6l8{m=DC0Df#_ThtJy~<n;Ofd)a8y@1j0pjvTf2t^j0t_Ia1<#FdIv6D z_}s%<%={0X(veYxl4WTLO3t7D|0L=1y_M42(>LDV512KVc$ zqa3HzRA;JA&0TFxL$xhqU3Ik!8;RlM+Xu_@b7Lc38aD|ANk|N;@7+5UaGyHDcc4Ea z*gmbYx>UPkjA#B-r+SC(d|VX+eUtd@!na50hxP}Iv>ycUce+t&tN&gM9=j0RP*z;J zzqxmM9)EuRlC#tX{H2IC+oy|Ij)wP5EzB=6_(ExYa{^ZvxCKvt-CJ?`w0z)kYzuDn z`gD;OV?=qA)Bfbh)>>OdVxhuI>V7T(n)tlaxwLljdUQnvan;4~((KgfMdlBsh=i*> z18h!@wB}iN5=YQ%{uti%Q*`|5N#nlDbLz$Bc#%3TIY#uNVoZZ;B+fO~((8y%gUh}p zNHg2XrtstK+fq_g4}_AzUB{G3m(ybV8-BKJ$8u--EhksJC>l6VmO?)r>UndzlRrK_ zPX8=sI=Y;%&0O9t}Y9RuA$Bi8N3-&}k? znd5u%us@KiFg%Zh1$9porl%(ae(nb`ncM$4n^68XEakfsHSOwTPSMQ6zDFWkqOqxP zSZSWLtFUww*&=<~RI+rm)Nh={zebg;R*A)PL2!<8uOOCaBmHLV={oF?R(6H;GSaxl z-O0R#1(w7$PHl;K`i8%a>+9Q`pFZ$V0WGyxlV>KM(SygM3dU!={yq-wj49Yd9%pjc zFRVq)cH7`gcIwa`?v3$Gt;3+-_7GcHMLij!Fo8~HVdB5i+(z4YTE8l zI9J&{_-IpdA&+tZu0i+A$sc2(iTB#4z0_ThMMp1rms89|PpdYO-07NR1!|5`j_zp|+rfIuulHGlv@!St zW&|WHIFSt-o??R~+1_)WSbsJ=(fh^m@3i13g5-p+!s~ZaWxu~W)d^*U)LF?%Z=l_x zG3s(C^7(D;=8hvb&S{^6q^u?M@JEdAEGx&U)vZJys7N1Xb^e+bTv{iVIm}|1QQi7A zY9EhXNyD6R_&Yp}9S5cc&({)&&?ayQWDQIUTCTXkx=8|B=iHGR2TJc1h=aDHoa*w5 zX#Li*evE^XN|P3i(n!fq?6&=v{-&lF9v4nL>@9m$>-i!pb18Wf_M)zw`q~o*Ir2%> z9Buz952Vg2%(2Cv$gd|^Sw?@$t#zXi%Obt4n9|RE>>#J}erskFf1TPv?!C?-s%;@p zVcBOpkZZb(j;}|9{QkM#hx>0yx4Dn%C%0ZzfY&KrIjxUHUXjgWYZU{$*v%uk^78)a z9^@UPp6Ga0AiY?)vBRB!^n!^y%AP*?*@Im*q*`Z)<@!=Qw!lY#nc=;EbHaIO(P%?bv$l9{+78Hdn>= z2a-2W%uVqI83ERomfK(~e$A?G9s054jNu^j$wZve&5P7C(AzQbx5ngKOZWd}>mQNEGsVW8oZ)YU7sJ8%av$d9Uf$L2Vyml}1&P~A zQ)l;J`C`qQcF<<)Dca*{xi;^Flk;agG(WyJIEBw(2B}^a7)>Z#p@p4e+v&IFWjMl- z{v&HtBy9ek0Tv@9X+FY+)eNR@qIO&BBGv3}v{-t;hAUaB2z9foTS4;E_8~=!0xjmB zx!;N;+Hl-hAFG4m4TBZZ+&*Om4sF%l+hsFG?vRT1cP{4fNQ5( zx|`|-@_Sl<6|H^_+nuWW3z^6`$u_CnM*6+}^No)S@&eXYtS!&qV*Uv=<{7K+q+z=w z^d99J1DsJlNpH%`POKfz-OWF|oMM6dXvn+g_>5{Hzt3eTX1KvRxOvpCE@53`f^#F} zep3~BE3a5i(@UV|Sq~N-*T8yXY3*}R;oF|IINWs-eXMM`;Y!v_bmgl{aJb0ID4 z5w=y1*E56MV*YI5ZWWhs_+FHi`=W4`Y;=2{b$^jYO0o-N1#t5s13)9`d+-_dCadU2 z01q;XJN{HBYH)TryJ6>D^)fLLAX^q`_tgbHtmiRZqnekSEb#B2s8uN0_ zbM@;s6<+@Lk=IkqA!sCayP=K@Aa(5gQ!?^;I0RW-s~I9CoXa#Q zcnX>4_rxVdOvwJgV7|Z&XTEs1J$DZu?s!}52g=9>Nw_9n+}cTFF!@c{(-E|uvvZe1jCK1U1Q>bJfYYW4wqeB`vNQ2JpA+>$SyeDRn*X>qRP6tG>Koh zfpRKY@^=34flsXU1?b4A?~C-%z+E%P^4kv%Bw?rCC;%S3E_K@b1f%36>^E54a@->a zcVYSR6ifM8BBV0R{_Gs28|j9+BS<&)?TU%zRe7gy_Ba0+jz#;IjXf?0`*DrL&>FIz zb+G%1Bd=wt9eSV%-+*ddnbjF~h$KPhPGcuccMVo{_*niUq-#HQDjy*m`p+xqS;*#X zZ>~so@cgw67$Uuc^+$OPuzu67TeT64yYMp>vwKe63_nIH?^atcSnv7b*&HFPZFSG_ zCS%oS_%c%Rc=JuLl=iCm?eO2CQ#hELe})gN&5_SO?+T~C?;^5=qCcq*tbC4q3=4LF z;THUU@Jn^Lup#a)qC{qU=~goyupz#if8x|}Y2(u!Y4~bO0U9DgyU03iqY?7| zuLomx9{+k!e!?g5Uk_sTSYm)pY$y8qpzlQo(t)nfN6}CIz*dbcZ5fvgXhExk#nY*H z|8;;TeBQskUL9@|*tu!?|h3dd;kPi}>L7c$fJ-_pnFz_wa#rqMCb4@|A|-Li`Jm*Msj z6}EK~F(x$?ctPzCz{|h9dm>pb!omHwn`|cEKhoh|pMFkuObe{frIX*i?z@6u_j;_p z_uGC3*{dsPO2iRcC21XJb`7x?<_C)>h*@^@ZG4{Y|AOW65qHsW?xKMihSAWfCUKWjjC{0<))&O7j3Y{qEZFMB}FV`<+@GZK0&MmYv$fQ;6hhtgXDkneyQALJ-ZBhv&Feq7llkOagj15aTl^`{MwX5 z|F!K-k%hhVl>{#C!xo>=1Y-$gig&z@J|f;nyY}->%%Gyd;-5P&kXE9m`sn_(Vp=zp zoxtRVJYg)#^WScR`F>^YDqJ*Nxo=bLkj5J_wEShok;cnpONIV@(GC?MF8S&Npz(}u z3t67-G&s1wf(eBdFyT@xScz~9e&5EHjS zjkb#7k4v$!Opp}PWB^KN&^+8`oHKnZBp?3!n2pq(qW*o%#qYcv{`;6)d?lzdMH}EJ z+HM>>NCanXF#h$a7SjADf$IVPn&+Ni^_?sF!gl9Cb?s#-7UE$P8{)Dr8L@)Clbh~q zs%MhE%>I6~RB)~r?Bx9VDbY^CS~xTlN@jQ<^_~Bu0HW zm^T<*CtM?asfKgxx3d4|smHvxnRp+#zA-*FZVgVG-(Rs4i5V06f&HLAKP&u=?=0VG z*SuBb@ExCmn}UQtdoPv=8!he;e8-K{sMq*8cx~kpuU>(%EE?7ymH0lwtC!^WF?Gkuw>rdft>yOR?Q0w;cg&c=DzdjMZ zSe|%AKFTXDUzz4!5n^)v*~cc6PfZxd;J0SOwS}Zz>pS--6t_*qFH&n#`W}B2%v8Di z@KW;vqsFU9r}~@P4OP1nMyTKC7P2*+suOPaU(*vWx@+(Jpn(Om?$Y59!)o94Tm7xS zUrXts?=J_?*W6<0bsEc9o!hu&n0Hy|eBrD~rBcw3pU74*Ue@E@Q-4|`=~Rgew^miU z+pJ@>f{7|m<#Z&j>RlErc}=rCoVJE?KZvzT^7QuAtxEJ%o{9x+8ua7FlNh)2K^5y* zh0Y?E-q^|SoAsY7=@QNvLi1SZ7DsrO{YLHfTu>bCy(2qRpAMvWi-s?;QCIN(P;gou z%p6{3M@b9Ki0oytKd`vnk1taxD&H-=wD7*|+P$ALOO6FLtXEz%mPlHr`MXYX-MqdgI5SHE^ZM4{3w!Es%XxDJr0a|AtoUrFU%eF}Jcv)E5c+xx#AujbAhE z-lA_^creCmbpCS_Bt6XAV}5tC7Bg_JFZqr(3QrL#h1C{4r>}>36E9Tp@$Cht2wAwo ziketRT{|8-xT5Fn8|FQBudHz!8c(ZZgNc$%#`0%;6O+GBcVF$$VK};?o3FSJh=H~g zNm`#vp0gn>SabF_M#mYOs9}bglRCqMuLNyyHEihM@Xk;O%#l3MGDCN-RBLcO%GhJo zbmnvene9Cnt5`@o)13p__{XSt^Tvtxk7mwbZ+6z)=?b60x7xenDF~XhCu!Y!`+#0^ z5xhxk`I7S}EqDQ?FwS;51$WrQCuUZe8rbLpL5ztD%*ooLuQhY84Dh{fo_94q;K9#$ zI5NgX4P$DslDSN=Pe^TE0*#^!uqAms<;Yf8#RjcOwO5>R!a_~dR-0=deDj^IH)H{k zjY!wJe+7o$2i?`OWsQ6fUw~adJ?JUSnP+>z&S>TNo0Z6hA@)HL(-+u}^*)-weB%#- zdB2~j;s*%Z-Bx!8$EBNgq)2ulTMo&N(%AvJ%-cXb+WZ5WvA7 z)t^!5&UvgQPD8Zw*^pSI;WUgl(|JeOjV7>CQBAPm_p@x3EuURtT&4^h-=j8f{Kg-e zXcH#WHRTQ)lPs|Bd1l8(-6c<38)d5_s>u|(*#%oWWvdHrDzkT&D76mCvds%vdjz(J zYoHeWex{u@au+`bjBPttn4j`+t}lEA`u;~xmlO!K9B7F0a?Gi^pG&k}l4F~H5zQTx zMXVuM4BiamRI*gi4}ThsO_g;V4gZ^vh^%^Bdu$L01jWX=nVc;QufSrqrIt%E3`c|}t%WRfMvQRDQqgDTx;9N* za!6{GVy=cQEQ|!0+@%Di*_n5RNWxBUvCUh`RR#2usm+65A2e~7(ZkW;DiP4_KIUkJ zzo#tZ*&)5tUX|Y^;hXq1S3^{3`WCpP;728Est4|{BP!1{t0|GJZzO5~NH=zj3d3&) zRb6fvUDT@$N3!0Uu|(D(-@deW$~E}g=_i%7zr~+3*`of2eSEt5ERy-)9(<=Et*>2p zu)8HDhqT=sJhCy zsGhHH0n#cZostsL9n!7RNJ+!e-JnQIcS|=&H%Lh5(k(5GAYISBm*4-z^NRDCJ2U6Z z$yx6A>~g{X>N&MIjUqx1ufHt6`gFwgI{`KSt@KVL%P~OSpp#@*3jq7t45&HbyecW{ z0JXobHg>`Xn1{%Ir-)5@3iu=kOqJx~bw&U;x@g&rLj#DBoo^-nkfMnhFbfgEP5ke`h@MTb;5gGvy+=nFC14i1-UhRj>9@QXBi7#o`K6;1#zR(P{y zv(`5Msq~T)65%#FUAj9HT2)H{MK~xe%p8;4vlj4`2Te#c7G$0Qzd*rnO@u2o0R{LR z{D?P@-m!xOk3XG?9P$J#{9y9Q;-WlncVHqQYD(U!Cm7*?8I9A2O{6vlpvlaR8Y_@x zQoIy}DL`jP`Tjn-v>I{{>%vvBhTI@=OeUa_{3^J$o&VB<5z+Tk(mkzZRh~|c1U1ogUTG#b$qpO45~$)kQwt^0O-*e zrH;)=paG8a`(8<($w0^B+II>CBl{NdcS}t~B^cSDYdHEpg?~c;g!$=~o%Ve5{lH`t z;AgC&X^VmvVG;OHc>eTdyfub&S90XgGcOBNd63iPPv)%qIrgh1 zUshgT`g33!hc_!RLlu0oLk1fvPQGqs!+>+wu_zL05++v4gQYIn#Z$Kf94kw|!qsRM zf$H~?n6`}pm|*t=CmH&|r$ylln!_N$TrlxC(Onu`nwp+E-2;vdW6-DiW>`-j>D|8B z>_r5N*F|T}bF5s|JDuq13?%vGYOt0%=01@sN?Z;r-Lk@M*7AO$jF7}9YgV@@&@ z6=|DGB}O23_gSKbPLM&XT?{!JE?6e*Q@wcTp;=j6Q;FRpT)VC;wTJFu#Rl169q#wg zq};Ki1514l5=l=I#Eida?9rMt92#v->?(%t9EVlYGiaWa#F!hekpnV`2_=lIWCn;X9|Mwj20k-Oe$cn=ZOo&0 zAda42&VXAIz;R;TaTvm-C`#p%Nrj8##K|D#w$Z(4)Baj z9~gJYq19qJ2tBV+L2*3ZbX55RjuP9i?$E^w-W7nTxl#3-0`Cf725J39-y8@Qbt}SE zHmJILoxawDocD}y=I;a1C7ac@l+r+SGjtqKR+7b698$0eAiN*Im_-YLpKJn*Q>ikn zlLT%;qP|*93S}`fDYPTPL7?gn`Oa|L^Oy~CLLoOkbt45^1;cU)sntssij6W}VA7*J;3ixx)$O4b7}%zPWSxSbzb38L+DkwZ9o&^as` z!`L4qL0)l|bql93VgyTz3_ z8b~78E?p}=BxL(MpAu9$nfc2$9|MvlXrw-iB84iQ=x5qBXW5)}Ko1NuBz#Z7!HYjB zT;Y(23oLbRf>1_B(y7V5YJ~EoiC1*&XHX3-T8+dc?A+eJT6C8~QI#hKkMhR4d zu6blcfoms}?OR57Ho(P834BceI0&rmnO^K>L!cM@c9W6C-%2BZ)XYv=AeN*N3ND&& zR7M2v!(fS=DSDo5Uk_Ca=NbX(l4i*71xKB;n4uz(ceT_FT}B8cz3QQBkJj2-;(Pz* z-l${4lb#BL&Yl;x-+9z1tCgUwh?$BE9D{pU_sC5JQqj=_zlIl5TM*K5CLBu|mJih| z^u)f1|H4|)gG9Qa78_Dgo6w;2*`Yq@YRu=OFkVQC#z}ik&?9v=k=3MuTQK0(-NT&a z+0}mm$$f^~^39?l%Mx~JL>oIoi%nckjNX9y^;jrM=7OH;ax;zko zUa&*Xp3#6*5I%buWgG*gnj*XES2wwg;Ec-6ZfY#h&$}~6%cQ5+LH1MBTG-hz;6H#s zncXpH=Y!%UT#)`)8alD#sjl=f3Up2wlREtVvKQHp`@fu)zmO#j1^4fS{!^E?Ni@Eo zVLYl+qu70kK|Q!Ce$L6(ID_`zd-PTXx^l!$w!Zo=s|h;ip#7KC(z;*kG(uiXDv9@M z5X@W;v|z9*W6*+8JnpQOt(t`Tmx|Sbh+~A&T2k(=UdPCS&i$yStJdFSNzA^7r88cf z3%XebO5kE!JRN~mi);jx0Y7*bBIii4fr_!Tz~_t~5-=R?;Ub=(MX6-Ufzk}mkJ+js zZ;@#h&fZ+dn;cA&#|hlM+~w%bl)7CSZUg@bQXTxhV5%QSQ;8DUAx@W6qgl4i_))4a zf-Ftm4~lv0cY@S4AMjC+dPv%ZZ(XEHWN_CkAFLZ3a}}D2EaJWs+&An;1o}fCtTR7x zHZ>MmB?ZCbm#0R6*5($?kuTrMhF8FIW4wTw76$X1331C!Z+6^oeD^x+=<; ze>sow7ei$EM5J|52ToPAX7Ob%RX46{R^UwU;Lc|_&cJlPD6jlWnyk7i!Wf4yCe;=z z@O|2?fnGSG-~6y*(J2SI(vx7ejlKC~lYnqxTTKs4XEt%kF;Wj@^Vl~7+nWaPn^y1m zM4fEx&pjrbIoDxde~!|+!dxz}w)jfk_Rjt6pQ@TWM|@?C%Dm*FyJ|)2%I9(s$*Dq^ zxwf~w?g^`H4vbPnVqS6z++&RKaC5o95K<+kt~-c)Y%Fu3XzMzJHGfvT-o5^DHu`sq z2_xz4co}Y+=dh;WO>6=F(|z~JqX1H&R4JRK$~fkEvo`fFS83JPhIf{~koVoQJuui@ z>o@K?o@8m|a3!#f+Yy%c%$_9F9`1+Se9{rxCMjmi_lRX(%0_-c8aqmrNG?_YzcT+z zJ)QmC16^JyoCsm9unEJRCzuG~LXa6@-LowmtLJ^h!P$p*i0rcy8c%*D8R#M>Hx{7t zph)Q=do}0cgTyG82Hb}TVMfg^iP7{=tW2ofr$-+cxozBj9td0={h#-Um)>IZn|=f6|DGW!f37-iqA#$vf48 z+e}xl@nih%Aw?`xE0jrM7I#{=Cr_>z2E#H~2|D@3lTK@zGP+-zQ}V^L@8w@Nb83uB zH2Aac{fU0a$7oJz`8MekK0VnFOxXOEV^)T?MP&4zkjLz`yt|kBLLzQ;WMvn;3J=GE zzzi6+d@aw%WbBzKZn@S}&c25_ORNga!0Luqg`a7hk7sh)ZKx+XSq#Nm1N-HL<(QEU z2yEp7v*&@?30ajS>f;g$B(h_Rt{#W@A+tR*24=JF=vmBwObVnXY~IP}sz^!xpCsye z2lUvdO7=L+n~h^9OqNmRgD=(x{Pj<%H7%bVX~>r;xxd}<^8WL?DV3p0P|$pR_)WEN zw)V$~Vr@|vs@V0g`D?tvgpvj%(-UcNHn)0Bn?KQfF=uQ;>5SYCcZ)NKn*3E7ZNdp3 zN+$iU)gmdmZ{@F4t?A{TwIIz;*KY*=T20oCOFt2`YgVAEJ9P|J*R8wcp^~!MWi2fI zCCw!J;p~KM6m^GayNZ8=-r(Q|dV9`54xw5yCYSe(oH5!MUCFMaW-12H&)l)bR`?0B z40Eb#+0%Cy6*x^Q9dys>Xw`~T+C(f6ni0A9Lti+cjUdu2Ak*`F9MqU$Xcaam@SUJf z9dKZ;NviE0cL{(yT;!NFyy3W&sj0YRP>LY#xrn!r^6BeQua-b`M2#sNV^&F(!Rk@1 z8o2Ech&;>XRL1W*ry?v}iotY^qK==qzC^9bT-a|kd!I>S9?L72dlHTRIHsZ{H(4df zfwEGDO*BFkh87VtxHdi$`?qGbfp5zXE2956DZW`YHO@%*UyI}D9-4^>{xboyotCf5 zRE&=^H+3sZscG8j60%>Jd*r=$_gAVx3nWl3orp?#T0uGyls}%Z{DkRoCc&A^6gkb? zQ_4!$pNnk--qjznadU=RdPSLcFp=}rk7sIUB{Y80X*B9NH2|bY9HCQ-xv|+8SZHk zQ@3QlUW+N#KI}Dt!uUF<9`M2DjqR&ADzo>VLC9vC2ZCTICt!mQxn|b%toyQ z=bJkQZn`fUyf@#pI27y$K?q(`pJJ!oiQbwes^AVb}v#q+Hr#Z?m^bTzb~-M0Jz#3&qr(6F=2EU zb}_k60*lKqZ=bV@F`5ChrH07GP~W#tmwwX=F$bjsFLPr8XWm|5^nd&0Rh~>kyJVF3 zW`M-y@3VD2MmGPPn{?d_k6NRyABXcDl`#i(11~2#Jwx(5rhuV}o~yZ-gQkI(oH$ON zk{A2^-^d%%Z|wV=^^DQ@I*z8_wV<*YOuJDZ1oV_Zxoq;4<#|QLFb{vd`JD z@=Ky#sC9z$+_PuJ80^jQm!_f!?cJ@Hu?dZvVTa_l*=vtN4*cq)UpZ)2_Z_myOE9WE zx&4cxbO29EMAB^)Vs6@^S;IGc-$AKCNh_BjSNN1g$j0+##rGf-rwbKhe)Z(y11@Gt z+wQM56XYMie}qd|eAuK-led{}iLas@T$F(K-^2>xl@k@SUVjuTR_(iylgBD$C*Iy{ zJ&||g>OVTTgI#9uzB5L9NB4*$S4Ypttb~kuIQQBMa3D@B5B;M$8UGbXkvl6A=(B0`> z*uyxNV&zwb{Ga*;B%tNbKe;;VQ|9)BHdX$MQTc}ai&;O;uv4(juKCUN z@XF#PDayAnI2AUIPmPmKYzplGP{E$Q!;djve$93|M5P%R{dgEpM1=eL5-*3DTReRD zX6QTZ?nJJ^iuGuwgp0O06Uy?Ew3&_nH$Or3$kV55xo|$gqSpT6nN=@Cgg(-}RP~4J7vID%#t`|sE~)ROW?=Fl4pD1+H}mh(_(^OfV}CJ! z_LDs&u5oBGI!*Km%ST?^0xR2Kx`28yIMZz_o-sSU+S*o4s@*3od#pQY4n~v&@xlxG zSYA)~esEpm>>{w4>=XHg#++#+`Gu1{#6j+!IP={MVLxmW*9s+PC;qh`-3p~3GE zw}g4K*`iV={xMdlFSVDMzfQj10vFS&hGtT17slIArphqQwSf~a*kL?a&a&*a=#%{A zk4#(1C(HFXhi4jaj#~~c3(NKI6LcJRw=?50((BPey05%$aSZB2Yz?-*|1MS{U~=2M zO{3*bj`81_tI$S68RE=YcB__J`dm7!(b2K~H*ia4YLokCEDwt}mUjB;gR_;2Gp7c@ z?uS-tMbevz7eop=kCC+&zJ?qmToA$P@IugvAcEctwF7txtGn(yRT%IHV@W2b~x_V+4|Z-*{Wlo>dP=14#v-bk&7!v|#EvxCa4()u@g#4)m0IIU!@r{~=4z4(CUiPi zk}+Qf47KeK-U4-AgVAAj$un*6#XXzbrkggyK2Ni#YN3XOmkgz$(Gzd;ZYIy#S^7Lp zjhCr%R};HX3$s@uminJ0dyZVbCXKyI_;F}D)c7=nAtr6(@eBFiq^L!M0bjYcE%|Pu zf5hcWB)f!2a(;Yqd*E^Rz`A7(R#`EWNQkQDPAw*1>*7+m{atrS^q-Qs9OLTUM|bum zhitv&&fCB3%|TZ>ydh0&+(qoIA5gr~Q~mV{wp7a#dKez5#SuTOr4MR)Ze#Sf*)^-F z2latkT!tEKH}4NK_cCSY>*WIyeA-J?wEmG7iooBe{ZSoQNbmmPJ&QBv(31IdiU<4C z0^8AZ#;$DjsoYKXT7PQn{m>-neDaWV;P%nbizIK|r{dlZw;BVEYqu0fb%oWv{)P8Q zfkacKTrkK+N%0On{Haa!R}!!kH3N`2G%-yToPlX1x=+dSmLb*D4*2 zTs}w1BaSgz8ku|`Ivk0p02X8!lX3&I_StpRcKX>quIujkaJ5{t2{ZIuZ)(Y&r2g8M z@AWp5%^h`6osrjPBKappkn3Ne7OZts1Bu&8{6%o{vc63U+agzkry?Zq=qxx?_xQQ5q!eF}u+nZ6z@QQHHw#2nxjEL0PTtQK3!z!r}qlud3U78t~V zbpjt!XX3e-UjY364Ct@i$_Hacz^&NYEQB(VZGX^Zj+9jrbeEz9(%rZHz6t5OZCFJ3EwU$Vw%?|i1fsrqiYb-yfCxaFqAPkVGJBIkFxXDG z$vya9w0e#mLYlje*YLK3*hW$pyCz%^-Ivnu`VNG*K34Rwvn(HkV4_2g$+HlIQ#M4v zv>yU^CV3s8L0Hm46<=;}bM@95H5deoE#?t)pa!3LtoE!rf*aUgI7HV%8`z^-s6eRy z%Bjl~NCM)Wz2Tt|hTY#mChPT@X%J*pt#2?9Bu-~kPaz0%aVbmgD{xExs-qN42u!^ zNs$T|kaW9onr#pfo`J6miD`|tbO4EIZ^1SUbx7Fv_HP1c&@G-~-+#`G5XhAa1|ReV zx$N7LFByV5m~IpFf)KX+`-7#V_hJ_8VFF@4<}X(o33mY}aeL;Hq2G?i$9+1&n zuWCZ7I90)=TwaMLko`THj6y8{5Cg6^poB;Epp%LJe;0P#AUyvGZH_k~=P!W_bMKo&?wvse(2SGR0Mu3?f26a}?= za1iKI;eJ;3x{@&pz?s_Re{q<{0zj|a&%8;}LjPOptT4R~I0^SNXI`C@{|+mu_1Y0a zIPY_KOr!YgEO#vnlv%{zKoSq5H%i@0Y}?b)v<2x{17;oZpTsU22ma8!pJ|Z+fO+`% z|DO3DTS5nGKdX$I#D)%58MdbiL1uN6oybceFs4akwa=LwAj{#i)(nhD{%V>(p+ZA zcVS_pR;;2c~9!SK`6OzkB=mvKqZ-r$0ee_W`k6bstq8#tVYoeD~2(UbRJ z<1;>E@ypYD5cQJhh6e=g3mG*EfSLm0Oa8r~fe@4aW@+}oaTx<(9tU!$(5w{LCN98ac$9;C8$kzV8NIitPuea<-5*!jl) zIG0foxr3bs;`1fFqTc>GktBeo|1o7>pKHT4_(8?LJ%y}YHLL} z=}jmIr6$6%9%emWdYCp{bd&3SAE-I&K=1+*=pA=o2}Nxn10Z&vi}EQmcr^rE*S|vG zg`4YuCs}#FM4=Czq%mN(7#)eSRBS3SnUJn2RX1VStt%B-0Va{yh5l z7HB{q2#$q7x?TqhJFKAXY`+%ro5_PX_i4AqL&aDKhFfdwNLB*k;2#{XhL}h@-y^5_ zlwC4_m>)XqoG9XD1P=8ec}|N+QBx@p!iN_+Y+OP%B`+1pt}chPIm5Gobw9D69J&sqz@dJsT4_2{Lt+C+;)MWA(`<NVEAy~UDxdc(&-(z zYG_GE11~{lotO4lij9fuH{TGv0S|3CTt2shK9?wclkGe`InDgc@k zK(jbS`H2to8`I-+WO&kBNbPh8xTjECSn2!8*eXt_kH6@hUiRMZSS&CBQ zW%QSZ)UR-lQD81B_N085P!?H4zcPkWN6}tV@@KGeI5EzV)=!Ep1L?$w!z5Dh-aCZ^ zFAo9C{q#?)sgH@$P`y>#CkmW@1x=*c|0lV>o&)x)kdUm-LS^bbj&U=zGXo+CImq^- z%gX1nJuS#(L!H^0@7qb_ZT6ui4qfi6OcXHGi$et^E@J?U{evs&$qE?_ppgcMZ+Jo4 zFq8_lW?IOVu@@mUSsENh4aoKSQI*la(|1^~1b@vWLWL|H8y(u4=T*!_Ypx%_O za8($@{zNIBa`O)zSUj{Z>HmlH*5P(~`d?EHAN!HmerM(( z3Q4CQ(1``Q*iZAO<8V=G_^bzUGfi%&Mb*8Bi=Ya4649WA27U}GwCP>4Limj5l$Vy<-OXBR? zQpfe@1Oqu`JH>2G#75%@a72SWx|0xZ35_1FI z3Y3@!vRL~!oLrzd<&xpvQdn;x58jlEkGwx->l{8C)V4C6knw8EjRcaT|FBdX+6C{d z==2FxBTO4p?`=!F;^TI@1w8%PGI^bE1-!&Z`B7$xM)D7;($jMs#*d)GJM{8oYeayh zRQC(*$PP64x3UyVDhPDZmZ>V?H((#+?htHZ8|>$qwy^NE5{2p>gM}Os8dOlbmsz)z zz&49u7pZ{N`zBlgB8=!EY^V!MmwPeI;XcXN4fYdd*WZ^rugRQY;L_t$a#WMl1~z!w zcE1nM@RIF$o>phlPoB+iFIMN`d8$J!9<=)m#laWI#wUm#^-x<*N`gDnf4tA-M5`IW zL;a<3`~>g2Z(-9niHrU(oRJobdLcHoVR>)CLesR;?#~S>W=1`JF1r&7m`(e58Yq$< zTup8yS7)niLBq9I%0!sZS({AC{K3+QGsaZ?zdZH^qq_UP%5IfM-gn1Ybh%gH+&8CT z|4nv4wTB#rZ_%t40Z?bLmHl8GKDdoz^4UQ&Xk#BwUAJ}tIF1w;n05Q;`_E-7n}Dc zkYf)lY26=NO25`nzgm@$N_gJ0 zcI)meF$?vedA?&K0+~+SS1XCHGv&_@nW;lo_7T)FMS+*aF>?U*F* zyIqpvF}f30(rVS`=f`F0WAb4-CHW!~da2W}`vvmQIy}^E0I^q)rh#_m85#8{>LBd#SnYJ;|H)NoI=W5$& zXzbOUvfp<_Lz8epY~K(NOVk2M&May4!(hW%s^PlVLBuY!RcB6(Zfq+SQS`^+Kcs5u zj}P2jH@@AbaY&#Ro%_!mus(L2V(|1il-*2 zaLxLzm4(VVrH805k9e8w;Fn(=8UMEF65NhTGxR3{W3Ec z#<8+p>a#6tZHbJl=KNS$m&Z-f+t$%J#_fIOx;W4gHOfx)l=EhYmg}av3~1%ydTGd8 zZ^JQiWvAFp?pU~w%W_?Lqk$Vz^x1gl+pW1}4=I3^?)o=uU+o?g*8VDyN!Npsgh%lx z(mR#+@3mHT{Qn3myynFQPe?$u%JemXTV?;3v z;Ah4dLef0@v}v!2DKI(EIbt$+OWOV^ivM_@J93+nDn;P;2mMhnx^@?0`tG}p+Vy7v z9>yFN`)$0weQI>a6aLppMwQil&!85g_D3Hu3?1^4iyI5ZA>eN)hQUg}9r z{=Q)_v146R|4cs9xKoA{7@?7;C3MA3Vav^fAMSPPF|N%B5tr#-Th>E%S~eO=@X{T2v`a?bf7-LXt7fgt3y_RZHDW>B zQCZGCjX^T=<&Y?!3y^r@9?9s1ixXLk5UO8VCm;fl3#k%sbX~rUW>QoTj?n^Nu{k%K zNpTb!EK&YvD@2r$o%hJi*wh@xO z#|pK0`Gdh0#)8j($Ni&h>V8=OuW~*S6^pg$+bfU3ZQ3FrFZ`-xAD+WrW;XXcQ>N!C zRM|{?b0qZ+4B}kD2+w^ccq0`LtELCbPHJx z5)|l^`p_k!W469ysPf!i>Y7%$8Tg!g11)(pcQoEp$nS4;yJ!1OHoZR)U=fHHxlpCJ z#pfxp=6+U^Y{>trbk_85o76bZ${Kiy!8XW#<)_B6I@VqBF@;a8ai`QVsbhbBEMZWR)W$7=T7e{U zy~tm%zU#+S9$gk@q&Thu>L$kMKK()2X#yrs`LRrhgf7MRts!=s?Pn#o>%ZdO4k!qO z&Ul=JJe;kv*?+djr0aOW(8!dYE9bSGZ7UB4nO`pF_3iNIG2VJBW&0bGn$_BV(ByUw zbn>3^I>atL#w{pVW*E=6VUthc7wadjZaz)e92Yk?ce$d$qR;lT4=_E$ltkiM<8_Wq zB4~j(pkR%4_KH?rk44MB9GcGIs0?>w30+Rn*0jGmc3d=B=k<M4Y*R zH0d8^AD=-^ShX&cL$Zc%PY&1cP0Dg@k)fvV0bDrn2Rw!n@z|3=7j;E>(>?I(6@ z7zLyS2KP@L)*2!E>_2yiKKK^;>r0kyEqb`IkWk^1B|5@BP@%+1wQ;L_){(&kw@P(| zx=GxwfpNoEe|iJPt3L(mcAW7OYcNBKLTXM8uV-qr?0(kjAKoxYU@t=NrwDk7HK$dC zP_-rg%GAHeilBIS*NkYDr&99Vk#Y?zP{>bFB0t9C^r} zm~p+eBKw@c!9NS=jd?-Q0j3wUXLz+rQyb)7=%mU`T~&~#7B}GG%>@=`0QdANlV}4- zP%fPTx7Zyqi9+*B8Dp)2qb`EzFz>VzKL_7Q^b&46~Ira^UNML=w> zD4sW7!H6&DoWpZVAay?{C>klT)w}+o{V`c<3BXBk>eZ`_meCkN_rRL)GCO~5#1EQm z*X^$U6{sRIFfY<6k)5apPVB!hm$M`U-g}D*He!}1kLWA;_LMF6>)M%c#Ui^NJ!4F7 z+qcu(o>lHFTOQt^ivg7{^+>g?g|(E80C33KasC)ONT1HU%F6MxH8_7^m-t1cdoqM3 zn5-duZ)*f&_g(|1yqF--g}nJXdPwn$i-IxW_PSYRAIKnU29$Z!a>wp5txO&AQJ1=; z0ggv?W>vkjJzm`gm_0tB>dq4iP15GgPk=9U{MnpX9^KW6@8`?;tQ25+f--luqcn3$ zVKrE)t2Z4Dxjm&x6>nUF6P_*XH2JZGzq_h<6Y%GT{Ygj28wPV4-tbYqBg+YbSagTmwa<{Q|i6k0PfjD!5 zX17RyHrA337%VCMR+Ip+Ui;`fTQ`16N3AoM#!anee)RyaOqKM{TG%a((u^vF6}r&7Mpql)*b#=`f(P-kYdpo~2^P!O zi%%gZ@>4Vepz&w#jeO=Yw)V`W$wy<+! zjE#-Wh0vW`YdK4Ie?Z~6Tk@@d{{mswiPpTBUBL*5)Y8{2SACy8hQ99# ze3%L&w;J>^$WE7p@{IQ_g_jHc923AsRy)O$8uFmg6E^L8I5r8Bin4 zyl|ZXUfg}9RdLfT8Boi)`vr^rCnTKx+DRihn)0(w&NZizdnDzIFva@5Ruw8w6eHD# ziJ)><@rYuj@5~d$PUTN|UYP0@+TR(Q*-?$OjO$%@1g}Z;v=|!qqLk>A#$EJsP}_!j zyFTn4`2MwhxY!C=%ITCK@|voq+V1YeUBtP(=IHvQR$B6UJyrTP9& zlG*VdzsQp8#{4&aQR%*U`r}|Ul_tb@CR>gac9Jb^P0#X2u;yU8q6^qTOi3Z|s!99^ z$M*rDin9!_Ez4ZYmcbiR)cuS{zWWA}!JOul7r~#|jSy3Hj&LZEiVpF9%su)seKzKv z^V4O3HNjJ(wU~~Dq!MkzE^8|Z`(?NWA|KpgwE&_R7U<`GKvdC-3o;6XE`zu>ohP(K zx!_XurRQwSc@WjYEUpGo)3O&6mC$z7jqZD%DBrqY`<5K285%+qKK2`2#9*@3H~o4z z{u6tNk01)kMcoDeAwIx(tZ1?H3t_mCJmRqmfqcODwh?dbu%Mb_TdRD zwW%$oH3!<4Z>@2Azq##jT0W0q^28z@|I{CJ(Yrw^mEX! zE=_98DfAxB?p($bwjWhc937#BFur`Iy|t7>)uD-sD0bFyHEyJC-sbbiDW#Br=lM}V zmroDpW;-bwDlji6L?bo~1eWrcan(g(iJSso1jff2iM6Z@{1^f7y#l>b@`$Az1nV1A zdvI6FOE+G@55lY!y4^>(H%#5u-D*7?E#^5}q@N#&T5@@REjP~GC=k}0TbSLzTT*3Y z^(GUi`FA|++q(7pU%{QwmPf2istE7_VIZG1^zFdWYnt&g<8!2&gMP zlF^2L-Z{ab@7mUFCvi>IX`<1KG|*%lvl_{R{?4 zH!b@S(%*A)UfWW8H3>fOGw3JX+!$@(puNO^w@|G(gueWjka-}y98)%3`dobJbGun| zxw>m`%VR%#TmQn>#!KZJBeCnRc9c7J`S@*Cj>j=OKmud)RvEGK;P7YS^XB!3z`E@| zRJIm;u~FymHmb^rfflbLfh`PRwTLsZ;+GgN^1jbV@VQ2Wt1_U%3D)TSfYiKe;P#2D zS?Vf5)Y0Oc(rV$z0pn4ALuHD=pbqiCaS7LE2leg8f9`PYU4{4 zfu9cD?r|y{&*6acN00)UK);g(T?k(Fv~KRvKuy@KmgRXCl4CFnk+zbtOpNe;oJAKK zVsj$#NH<~`m((7dC)yi3SGlN~JP@x?feYz?_D#(%^X2V>Rknw?gg*z1VP;k28%TS* zt~HW*&8}Z%3$lXK3Z)$0)k}=X^2O^eWsSw+^Z6-WszzHUYSVXTliqA6Z?S87MraMn zm|g^tE8Q^xKT&M<%M?MkzW4q0<8Kvr%)+Qtu#=Ciz3OGr!gj(_tUCk!@p8O(`$)1@0HtU|DuLY70BWmk?cuYfa&ZIo}*1;CDJM2s>o83^`y= zIZAGAT=jnl-r^=$%D!06PDkyeL44ic@E!K`@RLiGjyK!ifn0+p$!XWpt-n5wMud%U zIaliuJy}!I;Qg|A7>^qOnJSjjH$Az(IGNk+Y`gmB#O1>l+Gh)SfbcD=A z{7Gtv)4=vw1g8Dg)5n)C=p7=$f>Sw^0|UHqegJ^znrg`-*5BgXbQF)Dn;;leP{<*1k%0i6&viyyi4{ ztz+G3fZ&zPh8u3G+(Zo$LXAt-L|)01jFAf0=bef-f9F!l&s&@pgU&67)aQE*R(P&C zC4-X%-dz8)TgJ+QMej1t4Od&y5IHKE8mCPiPi;%U7%*es<5OL^ij6&1IkVP~qONS6 zKrju}95wRNud+p8+Nkz1PJL?{&RI%o`EZchZ=?mm;;h2QIQgw_ zwERiQZ$16MIeaG9lm1(5*gPll-zGDSy<}fq8xFs7G8H#w7-IAEuMnN%8{g*}Goj_H zDpVN`Gr2@F3Ye799tz%Kiy@vZT~+N*6cnAwP_a$9h=hi|(jYm=rDyDpn5*!qra(iL zH06TOkS1rpS_Hr>$oTYy#mJT~j!dE^L!ka20@mz-l*41~CmycbhB9GA8HsZgBMl20 zX}%u*i3+lUr^hzgxJTNH7MMq^9P!d@$ll{xPQ(=ow>K`t44*R%!uv1>uo-ba^Qzb1 zee~7iJul-G#`~{(r0ctsNU?ddO#ypnx=M(i$AlunN7>a%Sxq}1Vf!PJ2{8f!g|1NS z_JT_tgzV?DA&A9NpZElfs{%TU0-isl^gGlj3X(DVx^?-a|3u;$tX}&rKpFOi__c6B zK%*D_5?WK>N87X)lX%{CziE*@eze59?$#E*`2ADPdNc=C-wjqe-DgB~)74EuxR_e)yFbliKN!Sp#d>~`uZ@$-i(`m+ zs99|dcfIqXUZ595wlP&PO16p2`xQHji%?00daK5GH8vncBD_Z%xyLt>xYY( zwi6C~+PZOD$PL$du6{o6`dMtGfa~gMnm^04!G_Zz8pnXxnXaK$u}S1-xR!))z5Ser z?ec9i3nWom=EupaQ-~kzgZ7y|J2zQbJ7G!vd+oS%v>|qUQ}Bf>N2t{B%wYTQFr@n< zGW)i5f=-x-y-c=C>S(`;x%Z+QYhzioX&+_9P}G!Z5Ce$ zo;S|vX!tH|a(C?YTB;DY4%_;}+}veluLZmDnM`Fu0vtTUI(%DKfnN*$b4i56J(tyh z01Q2zFB~9696RB`u$fF0Wcmbvy5+f@_uHExIC)u3vIGmrCoG7Q6M~#4a#U_YBV*27 zF>K(YfP-DL;ek!{4uQ*tZ7Sec?KiLbnaJeu$nfOw&id*u7k0~MoS&Xg?&rrf#eCM5 z6D!N(;j$zCfT{6Ltn6%7P?s~C#7?9*Vy5a)SAPM`+k+!h?IKB(6=6M{dSvlDN9Odd zD#x46AANk%$nhvrl-!+!FrR}Vm^WIK+*fj1SiF{QM+C#~8^x!`>!g!bwNJ6P&J3o7 z>4w;s-eMrk=egln{RksMsZ(@3P%}W_!LCrmQSe83-xnR{C8r#$mnD~RbFp@gIuS>y z(b%PUOFj=9`{VXVG)rF$c+Yjq;IHs2aJyqCdJ10?hq7?ket5~?kIJ`vMB}EhFBuwd zGEvT2;ei<+-(+q#(v$*ikHE4+epSB=-9*M(!Y@%Tiak&0Q#I+%uI$SjroycK$sO6` zu~lp3E4UIuHwNfmVcRvA$xxodE1N|KEzrmk7$an+JXGfNqqZV$DZ3;~#MqtHXnr|~-}))muC%#y=vSX? zb~|}l%FL)&94R(bm${nq->d3cxkaNOY|2_0(lW?QHH-OuIi|B> zjd|5kn3nOj?Sg^}zb|dYvpD~qjo^U1e}%z2VG10SA?KamcLdl(BN9ZvlBS5qxt+vJ z=&?_o--WV?py$7vUJ`L^|C0PZ<43D6{prs8AQZnFV&&=|71TH=M;NSgJ9KIZUNm=} zWqH@OoTMrPH(QUw1{wG-rDi*1zT-6Ms*1r$R3DXuTMNoZRRx^fjm=3kYn@#^@>L|i zLf9ld;isPubf9{qL3e2)9c82X;EN>Rs;D>iaJsDdA-{Ivw*Gs5PP(7=0>|;6X-Vd= zf7d%)p;SB?etRb(D3pCzO!#A)*68lxa_^||@Vma-$L-NKI}NKbH%MP4IXv1qQf>_f zi-c+ugPNA^v~>J7UDIV^us^;6!jyMVw@ooADODJRVrYj5urb12#Dh zKX{i-s`*EVj6X7(k3!a+@gFIbBI2>9Ct|(kGqgRn!kw;7$2{~G`*z2{Csd?DQ9ElY zhC&j8PE=Egx>h!dN48lrl2zWGI=>`|i^V*S2WfQ9)@S05&ivRW@f4|Af9YE=D-}gK zmEShjDl=lj6B*7oW<0YuI{MmEi}oj{LOv?9$ResStb4}#AAMO>M z{)|3WF$zbdm!FOKwTH?PSxMK~8T!AL_u6o6(lOyW>DrsjI%}%NW6`zCY-^@J)tXs) zU>xTA*ctVi4+`l9B-pJE1-t7dad0GqJ@ET6BeUfRvEbeg2*ODWXwdWizh| z2RjKg!>HRC;9yaZV3I=;4doeMwQM+)RyF8g8U_|-( z+KNJIs|W=nD)DymEg;<`(%sz>hweJ>-uwRkU*7v^?uwabW}Y>(Jm+loD03g? zTVyu4U;A*izH-PX%~_h}Jp{y!TOp4GafDR;w0+zc*A+XcRuy!tOOL2=7d))5J|~Nu z3B^er?c`PjZ3?|~p^!#7(z|C`dh0i%qtEr}N+kh&YEYKJY$Q0P_|{oX+pfvOJV@le z)hUP zTboNNC^?nBXYtA-6ZtTDPvE&L2qWs-zwgd^qY*riH9_>{H0YsbDSH0oIX#Q^GuYkd z#^n5v>nLNs@!>dw=491#SOXymQ_-v2x23y`jaQQdD$#FvvJco*yV#u;x)mJ84-9#l7kI%B*&o+h$Z3$vAs6`I+_Ikj^JJciw9~KfO(fhKGNhJn(5EW8`s}eLd~CdT4F(lt==p_TGCC{mL_y zw-X=cfm?4(MvWGUGGz0ufa+n%WXO&@s>--v&oK@WkJ@fh_pC`AygOKP#%YOyLcKXj zZPuP6=?aJO>not`rm3Lg*4fpLMu8Uvo>mX!=x1UtdF`m}*usrHq00ltR7(LQjD(YS zL&En^#6?I*Aj35Up2wQ93m1m<0=EYul;G&L2z7@VA)m~3%**_qwAw50NcIK)z}%D7 zOWq+nEN)#J@R>D%D_b#ZPcaaX&OgqVG2pGHn9mTnT>($84NZ3*qX0J<>yD5fYzpW` zV7+^5Mgv}MOsk7LUV;L*)x}I9^vK#BmCGr3$KV-$y@?B5HoE?$h6DI;hxTRgKDbka zRxkR!D(2c`)V<2G%ilSLZFrLs6;Gq)>gLI4s^4>C9o8<|Bc>zaN@9Ec(o+A;fAc$_ z$wDi~>~1aX9}17rlUgxFJ=jyH0kX=BTUIt#--A8O$Byb5x6=PaKGPSww3*hB-0Wx= z7z8XURebLvF{tb!OIc}ikr5V@vAT$!`ozRjEc%6sKkA}RygNWUG2e7Hp|R7rrV-dg zuCS;R2dnY%NHDF&PW;?ho|&<^nXBxiHG_DNTN}$d0{e_s7bP@RCrapsU`OHYbLGc! zjNneODVZ1#-$d3xB++EnIz71k@LB#(aB(0LHlskS^Cu6ylS8T^zx2i)SN9#JJG)7X zMg6`og_v1%296+|MdqtcqcXEN1h(%utz>4tj=SuTF z$My5Am|culqkKNn9wqRcBEx9?CKZ%0Quu1KgR^%Z1z$6JVcoNnl~O7D+&1a@=^fH5 zd`+**F`4A+7h1o4Pd-syW#PaW@bEPc?DOdR9oj}COXlT{*eJ@(Tyd9mjkYYUMhSEe zzuu8zHHyDy_$`OF@49};S!Nbx!n+Wp_vXjDs)q~~oI3|fe9dVGh3~F(jot4WrU~4= zIIr^FG5q!_FQ*9Bqxs$kOuyFT|)}2+mDq6Ed=i2XBmRmOseb1%5P0={f_^!QPK7FC`z)7bt$u+)u zgX6)3J7wD4|2j;dxG+GM2649JOiT#XJl35C@lkNi`>C!GiBoAL522>Dr_lv$zAxw1 zqxRywADcgl@xvzjPO10Id>mL>nvnN?Dr)QxuvC-VSIW3g2nCsAOpx0FHH<4u4R=IT z4soM{+4@~MbyjiS+uxl#?-%?$YUZ@C3vld_EtK|sC(@num3!y@?7hqW*i>g}Pj_&@ z5^g;H+WP%CHFe?YLH8o~Ut)K*$Z_}LX3a0xROECclarS5jobCPTESu4w}Y*K9Iup6l4fZyqx`^Yy$EDUAyt*u(HK+n5LwQMV97G0OB2{xk~F8-Q&$p5$Np^YibL}hXq6! zwEZ|?ckc#~-PVz;?C6TQalWUZybK$e-ix6iMODJ)<39nFjFBh3 zA(N`?6I_d;B%k`yarhEH|Fjk{4#9zuyqVz2a@eUACtw4FlPUKI21xk&d%YM~FX!c< zAF4`W^Zij_b@W&SQg+H(Y!#sfhcwbina&S$m&huC8LKzcwepf7Eh)>+EA!*V*CR*E z&StnPvrZe?re}4-3P)mB#Py^zc}&*1v_p%TqqlZK79^4-e-lU-#D4k=oba z>4Ya%++60&rTqD$Vj<$>QS8f#QkK})OFQ7m`&!1kxi!w1ijdI3yY$epAak;n@SX6@ zA>aAp?lOk|o`};K_)bcxHEz=DjE7nPJuOC8sJ}_px^4o>+Iv zwu5}aO-z(dO;R{UeanptFUJy~BAa4c!o|n@{7`(OFZwUOZ_pR#uTNy0Ii!P_)S0=Z zRQJD-f4i;pF7GjavbYjt$ggq76Gy8^{dNQ1-Um1T>*Nrz!T9OlwMzzNwY2yL>pK}m zitu-@(HQ=~E%nWs#P0Cl;Sy-PW_lmPL0h7kh*b+O++ zp%EvVOKbSdawa?<_1@}Bg`g$3qCC8cCJpuqvvjjL;t;VYVr%57NsaJUP2*?p>g=q+ zr0gs7kJfZn<)kLT>U!36X6c7%(oa5Gb4Yf-sd6@-h<{+>F#s0IxzApciBxC*6100U zF?VC}Ui3D1jZ)3eBA54NXfkY=TU4Q>oa_1Tu=9BVw4YqhYa|&ZoqxB?nI#0KlGc*Z zP18-p9GlMcX~}&ZI#|-#ZM^wa{JPWbGSk=OidS&6Bwwq(hsBf5u^aP4Kc7M0)(N8; zmAMA3?5wE9)DIcWDPrZC35xpDRG3x@jn97Nduc2on;KhtBV%)lNRIhho=WF_FCmK> zTXXD`si2UZcPcSV%!A^>lj)yWD?fBi_{^4rvl1-zWqx$el%<+|eM<_MZ!qc2-i%wb2hI03&bsxk|+OR)IMTFs% zciQa?)$c0dayfQW*8jRy0`F; zh%JddF^-c@{mw%~Wb=)+gu*k63gh&ssZCW0x%<@e)l6_UNhq#lAYFT+ShxSp^Eq zFw^A<_Gf#&(-TPWMcG)C-s6Gdo*x#DDh-vtgR-AyF=~jeweWCoXAuIz9nBkzEM!0! zDN^PWS*{59(UTYwjW4!gKPgw{<3QLT@h#&9D6CjCG!$a_E&K_IY-(TJTFFyOAOp$*9{a|S{mIa zBYT>3S$crrHclp(WvJ0T_IkX)$}hthUncyQ8Zm-SKSRQ6G;(+3n*?g$_(da<$grs<7__Z4G^eBKlMuF+pNN7dBW+&Xo- z1qA2e&na}TDZ{!n%0E5s2qpSnMtqDGrdl*PCnZWPo*`t}uU5p7Y=1`D;4z(ZEsdX$ zd+_6--%SQT;m6-W;FY&|=;7I|`zo2WpLV#i?s$B6FV{sdw-<8`&fu@omjtvn4Bp2U zptePST%hyKY#j~2c=Vvg>v3#n%<{Y;ou7%0_BOq&JLp|)eaIu@Wxv7hx{v=Z;J>m+ zPv&(JFoNpDLrIK1S}wfMu-cbJV?8;x`F)=}V88IK5n8VJbmTgcgfw|AzZcLNn2_;p zzby#K7mc|u*Sa_8T~nZ}5XHUMx9FBC;(q5Ranl0zVjWd?)$k{Hd#vijhH-rUU+S{PrjpLXPH?)j@k6-g~ku<(g*mBPq=4C zX_tm)!>%)KWUgD9iSra0)hbU|kG(s;JKK{U4FUN*g{3Xr^$$Gid3Rpx{Q;!afkCki z{k1}%pnU7mnFtDwEerA5an_{S6wXcgjB zj(CA3N+I3RUcrH)>}5wI%xUYSRa!53>}_n!76Kj90{yG@$G6Rf?6FaY!b!GW93max z*q!8S%_M-#Db>)|%{4WX~PgdvhKdqX}GY>Ca%2@88AHPb^Pw`@qq33?F=});e z9mKV^2N~Q5aclV%=?`>oQSTdQ4)Sb!KiiAjKx~ zNF4WwN*E+=&p z$x?g#l3e@uBCbgJQ;~&*^GspH=649k)68+|7Ulu?P`i$jk0M2W*jY zyG~l{<_9`qaNAI|wefRMDB~8se*rEct+CuhfE4BI_jEw}^7IF$64ZlMp$ahN5nzhX?c>c z8c=s#euyO(G@^BW0OdsJ)^2FoPj{7GKi{smX$V~8cD&J=3x)Ew3Rw>d+}NSo*&{Fm zyzFtB=%C&8rRl#wn(2?iQr(Fj5Wu-h8K=WX;9NN8sShS7V5pHlgQDD%z@mo@;`U`) zQNGC3o3sRtUDRT(Wk|eXP+x%J$oYT(RPOApzuFiAhV4!mQ z{^s(0(1SIyWt>}xsEfQda>!?2Cy@T&pX!uDPTk`#d7BZ~fT^vpZq@6?)p*;)Y1uiWFX_ zoBpVz*oN*D7&Ocn(Dnyjxhbx_2|W7*08sB*baKA42RF19Xk>Ty0*Z&YX~_1l2|y4A z<>@N$c5u+;@K?HXIg&AGBMSM^%V`5%45G$C?SY2v;J2WaKNZjUp#)?}ANCpfxIm3W&(LjUgx2{Hu;LtnA#wM;u0>XtBrPsuI9CtC5NTXE=LbKhRkRhtQ}6{=O%Jf z%?iQLT^^=^{8D~CK=cI6zG>5o!j9f@5zm08(~vt820wK!wLdAk9{_k4EY0uBpqw!h z_Q|hqfY{Ac6FD(rK;PW#RtHNwZ3f(f_=S!a+G+mJXu7erhFS^$TK^fhyqX0%n1JJ4 z#YDuB(xI&Vjj>|1w7%Tq%jHzz(`BrkL!;FP`dlK z8_OX*j@>Q619uAk3Tb?oy0)N}csb%zGANxs1PkUY5MiV;ib^!T$AOt)Cc*Lg0@6Fn5H327hX1jg& z9MUL=tXYx4DhCnJK1x{{IztsQ1fnJn7%vZCsTXem&*p0L(YsRshX9zt)`0>tQV122 zjIB>W1L^9;Ta_8bBA^ECu5pzp5Z;}+L9I3DgdV;TV_4W=r0S-cK8+1W`gr2i0M%27 z`aPtYDpUgr2PZtCcA~rXF{*Apq7$sJ#Ke*UpTBl8rX7WCGv6>i z28*TM1n(4ZOc1+@9_@rOp7AsR^Q73db0u#HxLgkCG))8-7&CV@|UC4f?cTy0V zoeE|Tl%2C4OGJg?pxwDHC<3lvmDk~v*89sug@};1_taQYIQ4kJ*b4G zQ0dPsl)#3XH?r*|?U0+J8&LA^Q{R|^MRmdJTy5AqCgb|Rr@5C%uw?VQm~sI5Ith63hQJPI0{2P@G^3xNIXp~NHnI*bxGAv=4I?4dT@6#%-ypm3@W3j69F}y`bq6I%U`wR97Q|LJ5`1on(EN%<=y;j1tfGwm$3VG= z*7{cnJtvgo1X?qQjIRSh39XdIHLD zmDPE{rDW#>Q_W3~-|h{IX(&*|&xA|JT5W+*zb+nD2QDau$6UmdDQsf%vH z#85?|>Hbj;m7HP=;XvLsPwK7&}2i3X(N!F(dNtFQb@T>Eb=tih9EGJqG-RPu1t!??NO&A(W(L8wP?2Tz9k@ zSkOT|C4+dy>Y47~Y*mFJ)(gl7;k#V*9vg^j7(K(E7oq;(qInw0MFQQurgN%_d5MNjRZP_zxgGr{yW~OuHm6l;UHy6 zk9*{&sw+U1>t7p!Y{8Bxc$#k=12K}Y-!+(XJPynew~$Jlvm7PpOrujH(ch{sC{J+? zo&ElgKH-&YrI5u&X0sM32R!=!CTt;3Qi^ocFGawMpf}l`njJlqwv4Go^~)3JfGiVl z^rQ&LgDfX)G}Pe$=PPnV*r(2)47N2#J=d5Z01k%k>FzBU6Vp@#BwGpmzVLz zA||AMH)$4bCz~1H9jjF?H!KNi;}wlcSm<{%)(%q0Qy$kZLJG)1$dvK?3YYo^N=CO-OE?VlYJ&U&FDoHp5oq z6IW@2GUB97%AN@dOv_eoe-*iF0$G*kb4t5wLFCymN z*y~@f=WuZ7Z|OdqCb!%bs{~Vw$62`R{~NyCL1<=p5Kf5^BjCb>Z4<`JymP2h-kl=w z{9_bAl|Ab35b=(gzUi;<)>&y{$8qFYZX2;RZES}l{Ms})6LqzO%MkeL>_PJF7wXdO z&>UCmK-3$=CB06)0zvKK5wSNam{C&_Z16Y8OP9bb_$$*K%Poa zPlJ9B2?1+byOGkT0vsG!x9lnDY+)1T`hQ1l#xa(~XUXy@#AYB9FbN$^oYj7%ePS4m|=FW@REj~QIMwDWlBgmBb@S@)hVXT6zL10 zVbNwX>S1j;j@Z=`#22B0!XC~GuXZo&7dCcw`HJ9@T1V4vDp26we7~T7lj8XNcExvH zFO$dUrg;mcGeS7&E6>awD8dwKt(d$Ap9J$)U3xv&8+_t+u1>aQxQi06YFMC*iOtQwg20-58$L{uc5)_O7;ejZoWD^))$gQCj2q|pdML_9yf3=ZmDA1W5VaG zzz4kKR$3U3$JG7T*uol(eEb-jajvhLzm3c>zt7FGN+?DIkIGlo0m7R`^uZI#YHf<; zo@00}8}*!i+@mjy)CQ75SZU9nZPPuwz4e^njm439jn^a0_)3cWr<0vxl17bH`a@u# zd4k4-D>|*uM5X+_;=O7)Q&Fm(gcVuap7kM`2I`x}q!~Ux3DNi$ng_nX@0Ux*TlxNN zV)ox`C44vKWE->#l*j)$7EEH)?&1DLsj{g)L~WBXnSXPbHM;yFC#|u!IpMVk#lw2z zPx*4JDMl=~Ph+K9{!bN5?2LQYG4`i|gABnfi@&d#-tZW}u^Y9vM#tD!?y$YL=(aWV z?K&RFifnb3BQp@UUFlRf_fsFCn(i-)CbGJ|_ds1cT(N8*dS4#i>Ziy$eb4u6SJC&9 z8@3ctNR2|=8Zn+q%nE<&l*sZ*vhDg~C(qEpV+{`Z5PRQya}!yn7pCHa%#H)!0>syU zH>;Tvn!@zsPHKcNCf7^IFw^K216A#&uu&r$Vr58%=GxnKeiTWj_1=5)kvGS!3p8Jj zO+>y-J7vEp&n+YqF=RR6G8+-f|!fCZxg7)SRZ-C z$en&GHTn>9rP)SH&u#-V07Qc}TH++b@(y6}B(V5>S>7P?2V6buD{6i+z4;+v_}ouH zDHi7No94qB22!TcWoPY;24LmY(FasA!50>Qj+i#uSvg--TR=={qumiYx_>PbW3Err z{MCEe{KFWU>R5JHAWZ`Gc!xBfo_ot&j1ixD?>C?1hf3;Xa@Da*gQ5NeYW6m14?P!Q z{SR-cN{r?Z3!}7R22dE2552AnfXPm2f?ehN2$~OiF+VNVrnbw z(`{h#J)xE?E+izEZCiIyi0S?&H2Iu$wFkc!9{u^lDcCo>Y$P>wP;6|I8B(HKraQ$(^B&HK+`qnrKN}&|{?&uIcOQ-fF880o+lBxwGc9t7n6~{P%cBs&93lQ?-{`8VM+OR# zKlnZfki~QoYe(B_Ww5Rz{=@uN$Dh*=c^2G>_ZC!SvqX@q3SloR$SVhtl0<;!@IW=n}^W>oB1#cQQsGI0ZkSq0pd}Cx`Nv8_9fv3|Lt(-qAC8 z1PYPWH>hBoY^DSR388?k-*Sf|@&yvUwHXQuI)HLFvCnG=_(E1|`==DLUU#Of0Omr@ zkz0is6w-z5mGDGNrNRU~m)3u=gMd_RVAEJ&+^Ph9@X$a&vFYU#2%u5-a~o7hvDMcc zON4Yv{I@o=n|{rp>OCJPYX(r`ILF-r^FxaTut

U%|v`u+cnT^Zhry{@&`NZhQ|*31$eF~qfgO2@AE=^z94FP<_OI?lDl3c$|^0_a??3%FXK z;HqvP;XyV?Sq0Rm50$pqvsRX@@8g^=(f~J12kaW2ZAjBvEnE}V?6>!twh^aK!Gl zEE=Icmg;{Nmrr}$ArFw$np@U3fb9p^HoY%`-X()kZP(~;c-EfAUPrYqRM-^8X&eh? z$Mthxdx_@)6cjBK6yOsI_LT(-neqx2o9qG8w&XYI*IB~yKp4v^J2|JUo;eP!_Yms~f-ftj3dB@Bb|CdX!WMFW9! zP7GdxlBOa~V5H+I4}#=>wHfLK1%p^fXAtB{m2~;|I0i7pL!qIz_<8a4J+O}5v!&)e zH3-0_c1>j%a#fyD+k*_kblxXPsk~WXug3el84B^dbC>hfj5I{IuUZ)sK=uHtSm{Ps$sy0FUP2RZc5ZJsvnq zIra<#pbW&u;;~VObpi#f5v7&~Dl=UHT7hTQ^^2iQsZ zmp&VCfJMmVqE144xNQ|UU_Lz_C~9a!DHAoqq4L9h5V$M`+AYNwazq6;+-#Nf z-y}hxbo9yu?1yo{o~G)dWl5LCUiWfcB7{X7>K1{59wAUOybTEJ%6ku5)$({)z=Fzr zt!tMvs1{ZT6JN;bS_KbvAo`*)Gb+e4?VcU>(CA{Q<=6LW8weqTHVB$7Y5()s^rGpq zaTioHZas~!kOsKdb8o+{5nQEZW@c_+KmaOnse8VO1D2C+ zi}QV;t{lurBrpV26G3&C@HWE@irMl~Ge6XjxA}DSy=6aw#iVSM>t!&tJrB@8l_|uD zMNE%G{@m~0#@8JufRRUI`dbd22f(aVMW}Sw;1%ubJoCy4So89fz z`aznbA7s@o|4eBwY+KHb2bu3+k+cHD+i1|iHPwRxF(#OxDy(+_bmx|G1;zw)LjP}# zH@&871~%A002j#?g6qP9K?J#ty#Jtk!SyKTDJWd}S@vs!`uLZ9HE{sI@BZA6?Q>eP zLHqksVvNZ8-zvw(4J zFy^1b2OBtr&xI9mBPgtpG!pWyAV7vf*dRj|N*mz_s^~+G2tzw_07RSZf>aF(JO~oK zOS%IJShyB3$}4SN6ab~Wcg&G-pn)I+JYTi4Q!i}5BHCl8%Xj%4YADue!h1fPP^^e& z9e+t=Loqd}cdg|D%BVaH^-}*oE-$o_l~uG9D}of#y%2a*KlX%#TW;C&|2z&Y8H@x< z@Cxa-C0l|GH5po?1>@YJN}E&Qh_&%R}-pVE_U~S|95sdIY>UefT~vb zCDGK58RSW6>74H$&_-$Et=lueEa}2CECHy>=^eVg2movB-f4}LD2T|Bc|P6^ymC1H zH7`{v=@tQtmsYNC6$?~eqx%Yop`C&9`G)^HLQCmNdstB8+0^k=$EyMkon4C@Det4} zNnDa?_uaE*Xe)2+1hYSA>vniSXdCJZ1^X;>6ad`qm9&oTDDXZ)q~U-6Kck+**{ply zu8<4O<`z}KY(V#4!5p^44$ZUTWzGThHh+3cjjI2ySj9XglThcIS}Gidj5Sib zyfi8j;40JG!Q%(}S>)S+1S(c=V;MX~Mi6qw(^h5>;xW(ot3&iFAgU`92h$_R5bh|C zpZ~`wiOF0-Xl&kN(gJE>w`Yf(Sdfm}i`1Tm=1729+x-gRSp0y4b}e;1-k)`56~Gwo zU3Jl*f~nzV@x=QZYu5DL-Zg0A|LEkeR&EVmpsu-AGn$`5ZVlvT{~w!1b(G#^hy_N> z+in+}0RVWq->BLnKzUY*M3sjijbmx?ZULK4yJPR4^6H*atl-gZJjk$!AP6> zi=0OOFTknHo?mN0ZFR}-GNAUzB_ADr&L#@NO>JpqA%T*bQH!B5Y?KFHd`$n@#lDS2jkWeZX%@Ejax>jPHC$%&G9Do9P`{ zr`ZTkTKlI}8#-u?`o6%EJ}~UysdU6yluDSqVd$hzys)=mKiMft8ygu_632Tl8799@ zuzV+F7}_}uN2O~$*Gwj7I_X+YQt;Vc>ATn1NY~%IO!z7IO?-)1)#uo*{DSF(<=07n z|Bt;sfDDYS3|z%A;!9YnKEUVl76k6D>euFmwKl(B9)`LBZ%}V_!4DTW@)mCC8|!8| zX}i4tckHo4;1r3|CCQ2#3&uVq$J?+YSm(dEJDJ+!Dq+S3(UgnVPYVVkF|K**QRRQ&0I}$8%99B~LWM#6M+nqHQYAVhObE8J zKz<(gUC&j3cE$e~TMoTaXgXx4?Lz~;b_sSv06w64!YTC>{kPu7AMHDLxL=OuwsB2) zq!NcsPZZyg=Y9J7D&D~`REYwfiPRZUDN-tb*`N4C?uzN~piqEX$vWM!poT8~e)^E& z818ll&-wnScoWs!(FI0V?Q~m{jT>>Q@vWVJ^W?R~zm9XhbJkaH)3tLsRCX8hOpGo< zy{hv_M2AYlD}KfeorNeD``+$OY#Y_atC(I0(bqeCJ(;!C`iY){?D!=AYya}!F%G<+ zS;Kz~n3(<;XnN!XqWhHp(_Dy&|Bm8~`=~J}gaP@tB5pn7 zG7cH(zc*U1XtnfwE4p`wquq1@70bVJhq<+e)?#`8W>P9vN&0%`OmWn_cWkPcw@gAS zC;tuO{Qvthu;LSy>T;pTr-%+E@A2YQ^BfDD7>gIN8Oo1HHllIK%12WhvFbPJ(mxJ! zDH~oZ$AsvTz;V=%Ubq||$+b8$6Jw>gwOytsv>5Pahq;b<3+wm#jdXe2Y?c~dpCf%} zvTd>NXNt1_-nG3;i&~|^e=OR=LeAX3_@#6XvD?_1Tl2&Y%0C}Yq9f0mWQ_CB@Y5tAVi0vBOsLuGWs;$J{4mQ}{l;D9=>FJ;=;x%F z5ANS@qkMU?^xQ=2&c9#eg}hIohCczn_+*1e5&d2bgG-I^Mfbt?c=&$Y94q|$jcV92 zr@r<$vUYKmh00_`v@vYhVadg{nVp_iy-^2?@)&MIL6&hUv*7M&#^V+xyd!i;q@72y z4)?tnT`iUnfEl8}P!A8ickx61%~`j6g$<3NVLps>lE1)STDM=fTnw_T6HN9f`{_!v zpR>8*EmV7bmG0MVBV6M%-kQ-U$U)lF6U9~P9&+MtQl{u)y4M*fp->&@5_ox8cF8u_ zHfODn|F9_$VSX`UcST;#MT@4LHy@Sf+q*1n3|V$(*0RClMLULjQqJ-VWX)SeKst*j zBduRK;dYobG`U7sC_}b&f9y2dyxOL;%I{Y(F0iQ#2@brxnlF^E3X&I_kxfj5RqaqT zn(?}2*4BAtr_CfkPTg_JRI8_$l^k#P)VZHxmH21$WzfmP{_vls%c#SV5d3CVU39|> z7;}%Ge}p#ozO&tP;f+y1)yR`4sXHf?jy5*c;R%74^}Y>-zTs)Hzmi#e4_$4O0E7>X zJF6=nqhoR54_v)VtH?Gs1ONGxe1Nv}I6eATJa+31Q)L6>44l5vmc6(a;E|x=Z0l>HFY9p?{j~ zOYhXa%t(bydmA!YLovV1{bsPO%T$JN<6fKPdNn0}+a=#($3^=~-cewT@{0_z0 zeUo*_&UQTsgizqVE%3XPj5nZRfmM9(EtpHyBY|8Zr+nD2Eg=B`= zD=dode*xCjyOs@^!yvZR8#ce0pG&9u**{P6dZPl&xLa!;Hkp{b^hYK{+=)$330rl2 zC`_=ZRKFI>xeDgDBb88+Xh_`xmOKz9E+>CrJMX%mXO!{xKre)=6ErcX2BQ=8M5_QiuyO)h8 zSHy~@w4rHPfWAWkA*tj0pM(F*jMF4 zhLK%((g}EFKD)<%&tl2swyi1$2;zfX)3(RVRbwnUL2VWB!U77VDSy3Lnl)?=2vNnQ z?qn52_5&s3ud_2XWTHAtwTjF0|B=|iK*_HZHvg>pse^Z*3J~)v(z+Z^diM4&){D<3 zcACdu(7kVusRs^k#^h}W=lonV5YBSKKK3c-kn=BT>zWzPyP`N>7g$nd&WrcA-`;r< z7<$alwNqIT|1cCyhDfYOUN4o3O=E^J9F>XM+&SH|nLQXRJ>=3EwKx=aK;t6OA;H&l zneQnH@lLmFJQY?`?JX%ALSo763{-^9%mQW4d2W*VMymWyNBk$2W;j@AhsRXB<;oHU zVe@rV`TZd(Ok&9a2?HSIo+x)%9lWHZ)LAltai#L}NlQgZ$`ZrdYieMjJ4bTfyOTB0 zF*+@%qN7dfCZneQ(doTFuITegY6+|heVhd=7X`D?c_C!|NVWWfk)+M~f-2}F^W}i~ zz^}%ZmY{k2=?Tx}`8g9ZHXWZjyP|j~qUF;ETrd|)MNj80r~1Y+6d3BQku^{}mrt39 zEiFla(d#vV=AQo|73XWwr&5aKx)Zu{7B`FivCLBLAV2WZp5Zn4o~Pj)Zl5n`xyZn2F3_$ zoa9WQIDJ^2PpdA4@fz^m-FZiqxQy5wJ!G72HO~wXY3&H_t?cJl{q3~wE}oUV@2_=je}Qs>p?b;(y#LoX?tct}#?{S9I$ z_a`E+#XlDtp*tsPyo?0Dp(EGm5{sZvTTP)g{G%Dmt*-RG?&ifZ8qCT{I5G*_ck7LJ z20#&^!g^W6I*yn8m1l}AYAZQ@G3}%5)HU-@!6y?ZidLTHnpfQ#!^z7?ij<{N1RdOx zmVF0b>+l!%+A`o^j93_pO3P&_5s<q87in(4~uruo7C^@I@cO&OncUFjXd7 zgAb3k%j8Ahn|*#)z{lri<}4jCi(P~M=kz#;jhaYu^vz-_tW_$&9vAD>dm+P`n#gqY z4gFoQ@!C(~wZYFih>cr?or>%{Z!G)8H@1EflO{DYDp~MYprT1sl$$H|rPzzHu2B8i zGNrdfr7)5Gbo)MzGZ1HdBSnvo;P+-`Te_es?)$uW?8 zwm;fPrOW@`15Z{ZX9$O50Dqdf{sG^4cW_;oG+NvDAoCtC%FxwGimZ(N=X2@gcO=)R z8FnsGc!i&K@HLZv*gcaX$S2Z`N&hl~sQO)2W>%1qKMW74cVKYTeda^jGpQwJP0l{d zu-rO6_jC7AeHYwseC|sQsuYmWWTZsR|D-~`GW9!MJYOK+L*?6C>C(GZ|9p;n_U>~c z$J1WRCvrj2Xymi%H%Q}8dR4iEl_)fZuu~M8s7kCJ0-9>+W0AVW*+Tby#3$F{-2Hp! zeM%md=k2}qNMuZ&&fec+E%(ofo>qAHI?W1e&TGmB{ynf=a;gXs{7q2|-&}Qeo!2%2 z{)k%A{7!Cx&K-g}{!vcDsfAX!-BS$&niJaxGaOjYF8phm_d{ic7+UlqoW3WF(q+V} zWT~|%GSBNFEZh|^(^A@_6zLmNd#`@)>peGF&y{fTvhud-BHY~yZBUZr-g#EK-b_yW z46r_oxAU%Elg)iTY7$Oz?ru)uv*z$pjG%1~o6sChxc3%0OQnrOP#gF02r7H_BRghc zZB$Hy+lm|bFBad>L1VE{CWL91MDCex96uFAs$g=q8D0G^e{szOSiLE4uO9uf(D&x8 z<>yMIpsYl}9Mn{(4yQmUMoO#7XR@}m$9;v7m9U<%bTI;iNzbDtZjj8A@i)RJh1;2h z=$?0sS#HZ^asIHioYw%N)53oG*qd0;sY9RZ(uF@Uv|=vsQMKx~P(+0r)p7@G2;Ngx z-tsr!ZT%Oh+d$Q{+KNx;(TkbFpAyEgQ=%qs!xNUWWwme#6@it9k;(6p8{(S4pk83J zB2;PYk36uO79u5$8iYJ#()O#hA;-ZE5$y`BsM@NkV24kRN)E;5R7P^fn8aLsE3#03 zhp)s|U8^@A#@?)>Xoc4R(cea&w$z96RLz<{nlJxVx&avV820@AIk$HfNEPeUFLHfc zsxDlqKaTmO-WQK#5oC?JEQM9!t?=8$mn8FuG&Kl!wXFPxgu)0Z@Q_TT1w`};OeHHs zfx`s~I}AEqAOXUrsSeK!wuP-q5E@iH>V{c-5K7Shsx(?MXw9S2)S#^Ku`b(Ev?8ct zeS-_t7Dd3m;A$aRzZG^j29&Bk`sp=|)be z0RTkTtL}BB)?t7xxp7r`0|W~~{QC8uP7@v_EVcdqWIku{KwOLyJfj0ji^t`-8P zz>RDzMBSE>*7y$_U7@A;ZDp}Ow6JV|kC_dgHqvO%Ym}v}5Yx!Av%OGWL;gu(kT028 zYUOn$_%*toxk4ba7OzuSxN5Wjys~o-`Ss8#|5#;`+VP53%&HV2jc=&=GsGUQ*}~IT zVz4B@JYHHMGF8kah}F`YG-zvcMibFU(F!*u(a7?C*#NCqf%Joonm4TG$Mfi(+?GHdbkPdc! zDOIPZ`^%9kV?l4v4z;h*XB~_`&P#Kxuy{WPLlcI0;ltD%w8t6dN&?Euixq{D-#2ZF z(7Blcg1he4;|G}N4wkV!2YPq<82j{J)-Cx}58WKNpEy}Y63#yK{-OPtXFQW}6aHIW z{MiEwWfOj7FE2iW1zif;d( z=N}AU(ZVXa^M0mz%!wR)t8D51nM}gaBm3k0g5bOA$*`BDr50f2a?y6u5(s8iNiYWU zV1l#39g$T4!O1e2k00)}$}Y{!uUN{ACuMcMc4bhlw!qTdHPqtC^l|iBn)o8SpAOW3 zhq8?bG4^UgAh!(2vP+|oe+|YvigQ!elo<<4CgVfiP_2%usplK%sul(!=H0=--UHW= zUe3r|dv!G$5ZtLu(?B<{pDQiX`Sb3qEb#&VUKH&uEkO#ccMq&9ign%zH$3zND&p~& z0*TI}8ZnL!wfcfFdpD?5_h1FBp9Bllw&Jfp1WsDmHQ;Ly>0dSqczihVp0x88%8jy! zj#O3SR6qBXha;9OWb?e)y_+^4%c&sO<^J2Pk!HLE%0=5QGZzjdoq1W z14V0@?k`5Rfxq4x1wXG}x3kkORZ*%KZI|uu+%>!*jH5b|IuaIFN!KQPsM#SwsDUXS z{f;6+av6OzOvCzkNW3_VEUi^kw=n!67^aGyaYETuurojASccmE?d$z{Chp+C%IV=2 zl!<~WSA;kihuX2xR*{Tont?^G$z-`P$8q0X2lIhgV#ic0 zAw{Pt8ti~ESPS}FNlWKS#o{UP*9FrB+j-e^9GObC<_rzrY%r|qge+_tZa0ZM>Vyg# zc+Jbgf6S-nY{?Q;e{G%**wMh8TyrrxiVJ=?M4Aali1Epo;@i(zDdZ)8MtG1?Z+rwB z$)X@cM2V){YsB3&_8xJX#;9J8SP4#iAZk#ZEiYbFES95s$%}djHGho@rR$QZaUdOO zs%H}Q>4SgH0@bx}rHj=ngGH6&4NKnXW>v~a<=naembvcSOW6joVI8ECS$fl1+56dv z&c)8r_V*lOC~sSBVG2f zOlR+L;p3P}_kDA9a!qXnPG+e_E2U4-hHZ3tuoE3erS-W6fX!ltOPxDlsLR9FxvTb> zmsYSa=H;1Pig4kiwDR!2JV(}8>o&&Z&SdF6qr#c;_fvtT970cCPQFU+oXzg{zeZm< z)DER9QW_yyWq0je{z6I~TCgdQiC*VP4i`XBoQJCrL&W#-nKjm`HOk!RxKfR>;9SSYEAvF@r_kq% z^89}MdEn=Z!R9D^KQ(w>4EZP+^OV|M)LJsXzYT*LJ^KL^qKADoIQx>G2 zo_Uu{%8}@N`y=NXBgCjPlJey&Au8%Qnx8sYyOBSd}5T%&OtEtC+UgN zs*JBgpF`=iyNyr+r@Vg34@<#tVVvl|3alwAr~0B{D}XH#(P>yMPjvMlPt_vJiTbHw z#Bi?QkSoTJd%oaRjs&ik%#!s z&)UC{YjaX^sOK!!J*?i?zB{0gOU?;8SxKMQ)U)B2YxgxcYVM12rm~8b%Gk+J?irxv zdBIsXJg{rfMkM*0nS=LJ%z#IO$QHF4-GwP^R@_b=}?c?tg^#Z$Ak<=Xubm3A><-yGW{vko@ z@psmO%2_T+>{ZhkiJa|)L8?gQS79$|`%&3QM?5dXrRI?QSt#;_Z(ql9D|Djc z(d(?RfB)c};9C+xKpo-iYG{gnC{0@ND{IfgsPQmx;Db$t9Mf?#9&>Qh9{-z=3#)G$ zd%=#qFpIc?#^q@Ko2Tm@Tm3PVxvEe6Ul;)&1Xt3&D^d6!bM$~iedWyhefxBjMOw5v z`upMH`?tKwT+Qqg#>R_9YP)WBHeGrX0cY`}hNtM6%+wFqk*1=ubR0|;De8gZJ*R(w zi#PLbfU7uelUG^h_;ou?4v8z@YK}gaJSv?bjFF__enoX)J(Bl!ENJL$kT1vH;rnW0 z;P%H~q1!A2=cKi(mvquU;`b#!c9xP$`6lg4B<9awwkY6Xh+@V@Z4e}ctBCC`oa+$*Pm*r9KCnVKtbP|3^GVWx%U5ju5Vh$gedC-egCRzjw;q14wD_f)LFM<9}FUHq!0YUl36D?J}g?rWwtX zSCr0oO@5)D)zOk4Ur7m|8Iyi4@h(t9k~1PDL7m}xN*&X~6&CuLGi-}&q{~BBl|R>fF1Sb&dl+x>D~m2jr>*we z9>T9)h`g=kW?kuTVVBBuYo6G&G$}ET_-)KPsvq1r_oka+E?~7g^r3{|-fEt6efDX) zaH-NH*=vq=cw9L5n+lvQx!m|4pG!Yat!kg63_rajGNl`;f@?yCX?~^|Y%kz{qw$kN z*uvHtznK`$ovspRtE>Ft26hRhxFjWc*a@bYWb@jH1idJh!kwIr`pnfOeabXC=@E+6 zuPy`Qp&w6jFkPKk^<2_srV8VN0za*IeAFt{eJ?Y;)hKVXI~lC}%(eRlu|~J4uZO9* zaoBcu(jq!3GWbH@`Ufq^y&jy1EDNzAtgFiV@9XRYv-`#FW;H)J$gZ~wC)|dZaqjDK zMgRM4%^oKnH`{t=Esl3P8B&ss1N+^`?Jl=DL(JyZudS_;&mDx1C>e)Jt!Dgl%2)-3z0^<@QE;$Ngs#gUeWdp48yugRdQo z)4ESq2-v*g?0<^^7&UAnC%*f7@!9NnDE$uU1sO9J%ox$zP3#;(^SuK>_6HsV&sf+< z@wP6nWEKN>5;Sa6y$M*`1wt)?XmuYYkC%MY|%Ua#tB{3v4l_QXVV@tt8 zGqhuoUqO0cXx!P`RHgkqarU{-n&X}S%9@@y=)6ksk11iM2oYG(N-?y zlSkD1aX~A^R)_Y)rP_$ujg9Bq{=dD`gw^Tq?6+4-^_=~AF3?<3v)c6{rNdKh%~|`4 zRI{~9m8cO###S`KV?UjkeiF_^Z`iuw410-`IQ_ygURqu^MLcoxga1+3uZ=L)!cJ6{ z(u-dW1T0vbj1{G<`P~XEtcS{bj4vN__xiziLnd9W2cqDBx}5JyU$cxqzBkw7VkRIzESIH z6^Fb_M48&apwn#UiWbJI&bgobah`=v?zy#zLC43W!|F?Ubiy8IT9Oz(rx1YAVs0O3 zoMe~BqDMdaIN@dvAeld8enzSNKtE4Yt)pok5uql0=e1@x3;C z{>LbpTjl1-rd4|{g}hB|i|{03huj25NVxF|yXrdUn$cMU;JXTJulwt308zbi^G2KG zOdLQ|z6h^$i%aE=DY|{V23zxB@7ULLp@B8y$;(rAE0M48OioEEYb&=BPZ04s+^tkY z8;Gs9$N=F=4Yt&l8|7F)xZilvd2C&U2@u9jQX#zy5$8k1GfQV3Yb-J%F})NtGxS)r zeIZ0j7cCB4ka~^DIwoXR+e|+elO91N)t;}Pdj2@{**m=a9W_NvR%T%{=OOB1GE>8^ zW0Ysk9j;%+jVVJ{*$|2VRgtVRidgrA#XA#rp=2DUK3RJ)YW+hiW4;$>I0B3>v##Us zkA`WP9$a%tf;Ah$-g-MGGgNbfCImjDgQKoCn zh$whfMt_^_f)z)Sqf7dAz2X7|nas6Vi0U)hpQ+#%$W@t9G*x&p0h$S{FzTB z^xN{;47v>$Zx9KLb>re=-7lVVN?qmqve+(2{2{ZwLAGCzSSGvTS1ImvBYv(gb8eS7 zcg~b~(^(+IaMqbaJpZW%!#kA9v4)I*z|_;JKj7oS^#>r zIKQ{ZJFIR6oRj{C_*{Koxd&6J<<4Fuz@x(dQtHg-r*9A0#+fiXSGFza_K}N!FOOT{vL6FYjNd3H`61K#E>l4L4eXx_gJ1!xg~ZK|53zkRZc0=e1UiPO-x0$R3*Ii zBy8O=c1^YvE1dNt|MM9nO-1s>`}qQ;imL7Rk}=Nh_Jwj29A;(!8Ejt|#;2JVL9Vij z`^gG7X;Rmn6D6OKwno@RQZ0mZNUR0ZTRO4Y=bzQKo(V#0kO1j*RPG%Pe7)7;%gn2JT1RYH8^sY){Xj+J=8 zW-TIjhTX&C`lRQtn~@liC!I%Fl3u=A{hg-q-CRWk9+WO0c}gXbipWSRO0dR)+`ESQ zi5VcLSdjB=bjK5(zYbeZ@KxTpR|QDa#RT8k1r3Ga5OmwdA=-)h)vr6oJ^>=1j5A6$ zoGO`saWO2&4k0rm6MzJXH8a`^oRZ6{I;y~)7KL$!WSh!kai+k{-d`NS595{mbK`i? z21cm^`VtveSluCZ&6WM)j##To!+6mZA}vK9Bwq3377J;-v+odOp)Ar!ol2+mNNQ18iR`7J%5a4r!bJcdDTk2-o=Dju1irls8(biRK_}(l{ z%hKaePSYsk)tM#N77F28Ka&i2`EYT3RFW4fkwinh`&&1kf;~OgK2RAi14|Z3 zW8%(K{2!}jT81mZs7Sa|s!LpOo}^1bVuC3$agf+X`+Z$eDK}Z|7zcbZ!gucMtp_;S zQf5#n`B-BJA4bJrbh=2hvh++v!lysYnNK8MHR&6V;VU}Ni3>5}CiaD1>Wm`Y^9lZ+ zY7!&`njG{5PuznaXHt7vOvC@gl_DwVBSp1BaIblsnOMuJ#s70!hNPf;Y0Lz{eeH2( zkXaNn>2f~>`sAMt`h3_W5!tXx#ex`psZa&g0z*lqpm^oOdg?LlA@Yo#G&&O7#jx$! zoXA>7>)tBtLyoYu2FGo(5;`4fH)=;Qn5C+IGTZ&eNQ=0}@poNL`#&VLdD1>{{@4~n zXts!xUY#8?iX2RAQajd}69}}x{if|^T*_wcK24w2QI#VhIWZsQO0rZ%1LzPQbJ_OS zaXQv%_<%7@PpcEcsozDcJxzZmjnW+6a*l0g+12exFL70(!yRbR5`DkeS)sGs;FwQV zawlcCpPJ_;`bVe15M$btjnpDo^-kgsxtrBf#TpMG zCBJ%abaZ9OqO^>d^YwU1KiTV%NiE@}Db3yRH^zQZVMe|ve#S+lbxCoH@DjE&m-2SK zFe%)~rdmvsRk9Hir?S-$PyW$BAGnW>2sA_fbS0V?s6S^2i#X$goOj-G!hjN&*_2!f z6^^DKW;AT&bc&Xu!S^)PDONGzAi3djvAK?%;ok2%nYuhk{gxjkFSG_# zG_H57f(K}m!4A0_Q*#OQq5R3XQsB5OP8D}EAOE5r1+p!Wup?m){sPu|atv{3He<#L z-%BU-wf@JuU8bWfQjYm>tM%nqUuG^UW45nOUw%EC{TRC1y)@QTV^2ezIA%*1%Iuz0 zBVWkoEuLT;$CPw@FdMo#PC35EYOJ*QuIAITP-fu2h}ky=hiPQ96>?{62XY%%jZ&Lg z`&b*oW}>GDD4BhLkz2sXHVv}|a3sI6lCGwJG!`%t)sTHd1105=S+tqss|u=NkCaS& zfGr2GC2e%8asY*)1G&6b=XpbbLY~N(Xo=w_oisq98gtU|rFeMaD4Ih%NA>}Z^C*F0UL!H@j7uquMNikeZB%4+iKt%z#saAAx#&sJx9gN)_|K28aH zfuYc`pwWjc3~@qu`(ZD+{l+^v;_S&cVKAIkENH(P{Zx}U;g=_dHf!8iirEK`;c)g> zJr49T00}tGDrsC-$6!DLV|jvJeSP(*rq!zYXQhUoEBr0fs=zE*Ijg)^BJktpnB8#6 zv)1Gi;hDfVM9wOKxUc}w$WzX$7M;U!e?SHGGH~;8voldKyRG)m{FM9Sot(aEFMOhB6f@J+X}x3PR4FbhNmXLaIq5y z+xx$nu>NoEsqUtjOIl%CWe;m1zu;v2s@T!`{eC>0R@aF6 z7VH!eZnX(>v7_$${U>fjmRXZS2t`ezXYLHej-K!L6EfmdN6c|yrc#quHeEIMzy6$! zknp26t3rmgxY*+tmo3zJp{`{TU@2dy^H_Z@zR5;Sb3gOvtVpHw^|<*BtVQ@A9hMN) zh8JayOGQdROr2k<5C{^-y;U0?mpOL#Tz8sQNk6i18eC|kEq0`Ozdz;Dzm+{nk5aU7 zpnUeIa@Oc`l?w2KtugbsCsV4#Pz zXkaX+FZ*whiyg(@@7rxH@}*CfJTB5HpRO^foQ?TXg`YAS(PtU zyQc%|GKD%Q>J38o$yBCQg-WIpeUs)IpS80h{4_(FS?nCs)$;5xtR65*Wr2^$stawU zVu@~@gPuqxmM+jnsvvNcR+31bL?ns*SdAGDrhPl+K4%uEj7guK4fd0i`z1i)?KEB*F+sOE#$B`6z zGOKoDnLDnM(@xX*e*9ur&k5cYgwMbj&bW0d++~>4-A1+8>Pm{emU6;KH8@_YyW}e} zFy4A^w^ntAr<&lim3-?wN3ls^{3O1VPvW`rT&!wJkD8nCpRk7%p&^i1WtY<%0EyRl zYNp7WZme4GX8v&F(7%HjxL7_i&r4#02MOj)o`**u;aW0=X-^;Tfkt%L{u`I0)g6t< zWskWB8^I@3DVJ^vK(?-|2ArJiU}}#d!&py+}&Wt?g*)KtS22 z`P^sCNVj4>wDjEP+0!s0CB5ZBzE{rPDT^3cMFZ2R=#9?{=dw3Jo>2ipCCmw*v(}K? zv5p1fl6UtUCeJo@{9)@FpB@f2>ZaQt=Y0w%v!@`@ZexQF3la$T8d4$p2IqXvja?F( zM2}DSUhCG2Ha`AAlJn+WWE(fVSI;7TJ91CXZokJ6ncTy-5=)GFa}X2gslOb}S)?!5 zT0x7NvW7dWX#G{ub^G!I{lV{LqSw=pyK5qU&o^?n-&4lXJtbUa*svOlpl%{l`ZRBS zF@zRNZ^lsP88BVj!C@6nd}k8G##Q?_QjZ6S1|iM}&*XDO;$m| z`;)iGp^6dcUoF24(1bTQnh&+QgbKVh9Op@Mk-L?2?#>^w6L(f04b zt^`s1ju_89cQ%^Q)sHz&;r(xuP3^j3ur0>r?ze zqDJ7)kmS;I`dI2l4Bz%mVy$+tgeGzN3t5m?Ix9de0}}oR*p$*BLABNfKXSol8%Pjd zX>75Taq59WeK&NZB6-~mAG4^(CBXy|j*a8&AN%oE?7dhy` zii}zWY50aazaJ~G@78a+KK^^QvN(BB*;BQb!qG?wyJ6?ct-X35x{R#}D)QX_j0^Z`{^hadyqm zYK1#eHG963xsV@4s~Tk_5YBYRCSp3#9Lgn69X}$ECCJnxqWMp>giBRb-rEaHsm`{leGH;TG8Vs>P0RUEzdZ=w|B&$~ zhQPihU76pjNysYX8$PWUHOudTR~_7OqC49)n zKKkSna`spF+vXF+g$4fo!v3p7sT|qjX*16-S3?}-7zL{~A&)WRMZ5g(MBjakl9i<2 zd{QfLfT#W0ts=o5jr9BBaG{HAe8PBsA$11z1#fH@r&NId&%S zV3(?_G&ouUsou={*k{?_6)w_b$(Nt z#li!px1C})8a_Qm$t>lFDQ=PgS8c~=tAsUkFSex3?`$i2pHnF<1a76G?YOt@m)6}; zAst~}ahEe;9YG--a$Z+>)1wV67(5R;tMW0fIL2g-R}CG3RTUl|$Qkq|9TDq-YIJF8fSzw#K!j<2Y7`cFity#ECkqtWZP}8%XFkS5<$?)e-;!i$CISr-Iexma6f9j9Y~*)>#RkyM?VP=N zdHOZ6s~f+<9mSknp}~Rfj2JIu!T=E-C3jY7ERlc@ZMSEB=za$CVAnck24IQ%0XLvj zG;@Jko97;W(t}!Wot0YZL800kf7fA1gAamlKMbf-zYyOOfMs`bU%fE#FH`lU1LS#| zM_xi2787lI0i^Y1L3g%+o_`_wV>>HifZmt7MIHixq5$Z5oY%*FD9zSNE!jliGY+{% zS7eYdNosO<1UhqmUJ?y)Y*IDdxq)GJ@%n+c9sfeCT|*TI?P%`_rt*WHIyYa)OmPH& z-Za{q4SIsS%U`)J6#z0ga@wU;95w*L3WUG!Lp%os6#Uvd3*;O%7s(4l#1TD_2tGllo2w)S1kgCktTKU#?G>!7yy;^OQ^gTvu#=hf^AHPXGuTwd09S zr4saPuby`XinWFz6b>SOcTA-~Ap($}m_TOG(wtX)BZ^e?`+?NQHB4n=fPT^QUycBf zzd$DUwGI9ywMe1q0TEn`6#hC203;>)FnUD2-$wuH7igXIw265Gkc=ZGw$p^bPdfp; zRGLj%LueWAHuwO)(*;l+4{CnqP=Kh9N4>-5Qw0zrc5{C31hl)RwI);`c-7lCYK*)1 zJ|Ie_v$Xe@qMLgNCVb8_h#11M+*4z-5QnfK@$pkqA#hCMBbTAXc3}`%a<8K1BZRPR zyTj|I-aQ6DUaEKGEh#sIfjF3r?~PwrsJsIaeoNghQS9h&5LUw#bnqU53)}R{VTuD0 zL`g08Oe^_|I(nt5mk40pSp`u*8F)ON9VbyCtk!Yxt3fcO)^|-?q(C+*Q%54GifB$P zL8NorI=UE*!mnToYgP6ww*kb?k!x!KZrpZo8dAAT(f%d)@?*hF6NKlfmsY2U3BZ|_ zh9T4cl~UhZbOh7_rkz2WV`HwxK5xT?zvIjJ|mOpWWSGH4>0rK9ibz1Q15mIqOOZ+F!gM=UjURyihv| zcasek(jbWCz2Ce^4kmvQY$@%vrWU%PlzKSH&wmEzm3N~H<==wRb#{1T5s3?WcH|c+ z{~uxFL*=Ww6-7(EuevYb7ABAn`O+U2Tl`2Xk~tJnfwp4JV~Ij_a7?n z?bsE|e@Y9yu)ZZc5Clxyq{cyL!31s<%>Nb@$1m4x6i81q8hz3B0pO+SL2MKL->|Kk zU*9Fg09dJ}7V1Q31788ptHbV>H?Sf2)K+=>1qctl#7)}?1i}rj-AOqt%JT*hRqK*2 zc)cK>Bbunupb6ry$-?_*w#AEQ{|RW;)+ZNtT|<~4z)c{f3knywm|)RR!wOs>O-NBm zaj&2ANcENel$tlaGpDk>VEPgdtP(m7$6yicf6(T0SNIrCSQr7&uJdZtiwKVZWr8nn zKHDU{2n2zaF@)ok3E-f<>KW|M2NfM7lN10Y3G8Tc{F;PdC2yI-s0FSR;Y6<){8T^+ zmGp(;BdZ^tIbBB|ZgkrB?^A>#QpQZ=u z%Nm{@of*&_P25)zjAAjTM}z+W+f8%uS`#Y$-6OPWP#=juK>97 z=ejFF^2swCn6@=Zh`@8+4_05)q1wnW?pq1fzSV6M4zQ@&-e~bOL&t#Y<5+p%#uJpZ zUz}A7u#hyB-ct#XC>p9O0B*tnT6kn)2lirPGJq9M z5YSKb52a z`ntz|L$)geq5&s1bT*o#ghE$45LMhU{^jBvC61^TRY17HD&^&O=D_eaiUXcXvLi#H z=iu>Sw`lu62P%zBeuO1L0L~9Hf4)}zy2=m53-qKUxFhe)VlbiQ z4gB96a=(GAkF(v^<)5XypzeJQ6C}ugftq$v`;R@@9BF_0%91b?~M2fn5~?XvT)x#^Ub9bEuL09H}Zg`CCoJBm|81|K9$QHsb*cHpdTZ>Gv++K)HC$ zlmj}b#LRG&dO)RnJgzqq1lkV1oT#hkhiaIahZ7al3TOyNggsd{1PPp0cy_s8f%wkj zi50qIP`kECZAkp@LXu{_3-ztP0N}VBSL%OZy^VI4N5L|g*EN7_Br6R7i3|3B<=wA> zE);PV9V9L4Wr7;OAr6Hzh-G~iuBYl50(JPCQLZTl5E5Ly~O&Zb+`505n(8{mjW&&P~koQ z&1OOb4XF3j^#uKN&@Sfq7p13f0|AuSYomq%@XC^1H3D5{6sVkEM%NeJ6>r#YD`+e)aG+-Zy<}g1Ia>RtoxfvER6|(YW3Cg;gt`1DX)$kY2>7Q)> zZLQZRcoopr8ZmApJo}GJQAnU6@%K7`3ZzDtP%u4vdXv3S$JA!17Wi*#%a#su<4c1r z+TBjb2EhF0M89~!80P@p2T)8c*GUCgb`qUW3IvrTd#s5}5%EFkDWn}#hm4rA(B>8V zS5_|c?uP!A71a$6S?F$>`>h*V=;jYku?DqoCQofinr~NM?plIfU9)911oyw1QvLc+ z-NXRen$q+(ULa6>aIMB%pBv;ww`aJ44ij`Qh#gxi6G}p+5&kX;vtH(a|A^v5X z>RHdT=l}~|uyF0iv^)fMez?aRh87s@Y-wbJ(DJ>M3O585GXPJ2zAme()mpGt<}%TgCpZAbC|u-pk} zQvF^RCuu(?)s}i~<5g3f;lv6LJrA--3wd5YoWoiZo{SY>dbyPto{@xVKc`0??QzrS zn>KtELGvj#PvWP-M&j<5pc_|Y&PC&wi3BK8&ULT)T6Uh>PlfSrmU=mI9>){9P>5c2 z&wRSs@8Kcs6JYe)D{O#qjE_OSG68uF=sd8I11?nbPmm*eyw8 zGYu&v-_f<^dXa)ANd;1R>rth7O%pd%}N)%mGu z;qjiSw)wt7m^k^bQB!T5SJU6UpT!!}@oD*LVA8V`REnnv39{05{bJiKY<`rP7%_Z) zE4{w*ZL(g>Td_FCqUfD=D0co|pSnopJJW2O&pEE|s*W8{D<*eybG95Y($)FUB;^wNFT=Imw zsOp3w3C71?GzyCPzX1pikBtxCU;S|zMWMP+$8 z5$oxz_(o0LkIODW9QT7PXU@lPBRaetJS0Rd)TYISpb@RoDbscM1YRktPai|XF$nVr z8<(pd57Mlq&|*XtdFvITTk3dT`bJF z!YQUudwHWZor_c{ZMdiW>%hlAyihOk^g$_kI62efl0Yj$?VAf zQ**IPuf)_i(!-c*qi)1R`eIs+0dxLVwG1YF+1S)ZVUwvu0?+zDe?@Y&+2j#Sil)pY z3wo`wFz2zlW)ClY>Dj09t`>(T_EwTSYmyhHr<7mLbusl`uV$0J*3!*xn*KSqa9CO> z>Q?$C$4$0m!tY#n+}-kuPs`d&zEEcSW+eK`h^NyeB}Nx!)cLwmod(hF1rv_oUEKKf z7)-j(7jB2{vus!rN6G9*6Y*R!5^#daE8mbt@;6gmSYbL6Eb?LYbFCBP0Cqzx(#XzL z;!{=_Yjv1Gi|+7j*pJP7zF!5l}Xg{~v^GxKx{^@ws^H3tjh6lqy`Cf*I#`Ts$St`BRf**#X4rTddhk(e=eTks`plBM9Y~U zgV#J$+f$iHaoqem4mWdAcH*w^_Pe}69j{YgaAuo3R-AFIhthmbn>*@-uHKR=0rsXy zt(Q|ALFV^8{x4ibu~RQ1n@MRtY5EEoDfXV$1Gf_}R`5B<#6*NEdJWJghf=%O`Ymv= z)5IXwO&#wXNa_}GIV3-Pdls}@(}te$o1w#s1~oG5;5F(JIZGOK%WncwmW>r1=K){6 z?hr%6T;68n@Vcv?O=2$-sL=kj8H5RZ%L7H8>pBncG^$M*03sd8;am?J7Yi^R?GXs} zai6D(s)Ss=;S!z1M=S}$dUzw-$DGe~Ke~p;-5fw0EIP#MTWkCiPcsnn9L*Pf1z$T} z)PaksAcqW#XfyD z0uVg4&4Eu&QA~&ihLf`Oi&6UEn$eqvwmKdQE-kk;^8est%2x5Q`KVt~Muxx3<9i&> zz-yfKftIOK&d27D3%nOEg?K^W9~4}o0g>)Erhv0(_Jh{MFrd@I-q#DD_a|3JyNYn2 z_fK;uu;4+LF3!6q9-X47(GM@DG=S0m0irE0vxfcL-0JIcbY9xQi1i#GuiVdkp?F*V z#E0|5@;v>G?_N?d97z4Sd8NzSW#Y@U6=aG+X|VzvdetEB%?NtVTWGn61ai1I^*_i# zv7DY&_5;I)yz5*n@uz0fdC{MR*A0J{>x6tPhouO}D0%G;xQjimJLQD5QU2a}fX;$m z4F>d_Ma)$f_7nw;Xuv_Ow!9gE3Jsy%AZ(%Wa}_&fID$yy&{bau5@kahibRBd-MkxCh`Y&L8!P(G12$ouI>7R< zAsS%dwlM(byW>whS{Ith-ITbC&kG{^P)!$&7A*y$*M8ju%x8~4H(oIDZccTJsJDzN z5s~?IyB|~)Fr?dD{&}D3waUKBE#BAOf!<=K`?9UR+W(jn5cb{g{!x;V$@>n-@O=hC zk;NosI99vCBJ0MZ-9*7YkxuljD>PROG*@8tHuJ`}7{2Y+#E(V@USYyTKIo~BjXyR8 zw20BnmX-A9@M=FRXP7lX0X=aB*nRX#8W$w*h!_D+^woMRKQ~7NA)HLiGZo#iQlY(U zH$au24s$rf*kCen9uUdBZLgOIIZg)#j!WbHIOxpcH3z)1cjcJk3y<~>eRa-(k#_@k z?MIBZ`Gq)B!@~RcCmcC-@d#7L+3;3kMY9rRIAOcN{fOHO zi>^l-t$>x`H&aVKQ7u9;rO^X>NyP^2$+sxHn8HVc ztx+cdq~7j}{f|f2ewb*R!W@K)%j-7FOt@*6MlT@)rKq_5-5NW8;kNCS#lkCD!&g^@YruYHfNA0f1pXK(k_m#Ct_lw>iZ5d;7_eh*)~Qh{{Xf;n4{fP zmtJ70Uf~B!&)mG)WqAu)OJ3{!pjw&*P7l#F9pAreHU{dQD{+nAGayX5f zOej2w<^>~QzXLXhn5OWCp!pTtJ2Cm)$?cZ|>TC4ZO6{u!pmG?OCWt>?Im%zK?V z5ioN18cn(>Hf1Otq8jP)5)~*5p3_b*z>R*3(&2Ky!9y~vbG*^on3bLUZvxn4Jv62< zAQusclZWf+lBH34tz z@dHjAvJT4*cyd9*4~>(7XDPx!Y?re3V^5|+oP~k^ox2vSjE~7B>c?wruy)jR877I8FBZfBpam0YE!%(wGYxQ-!9F4d?Ou zp-r!pf9X()YdpdNmm%)qW*sa@Oj9jI{B@(7_uw+*J=nn9uUE`g6SRR25{O_Qf8(&q z+kyzPtvm`v!ROli-b!dtr?ZtXTJ@xX`lm!1DsV46&=2)(&7c7vH(Rx7r~Dzy=)*cY ziMe#(hFav#ZKnbSlhxaU|5?^Pdk;qp@#@=2J{VUaE`3~S-HR(Hu_ep`EjJo(qhf-C z>Ge*GC9?e|tvD*$-L(lh5lj9&>hGX75 z5Qha16;oB!U^f95iH)-4 zICLJQpkgws%E-uUS}#}YJ9E%Id=aQ7lW6j~)=!h%G_ z27kt5&>6x~+E>Q-Ku+lga<1jH5P#!)^2Sr}CA9yuiClPL1u(Vale`ifphT*fsR#XA z$c=~6^U$eqk4v`qZ?R!u$+q$P&I*-xVil8dsDa4G*ZMig`9XWxGcX0{a&?SLO(Vv* zUdHOI*->2ns}_ef049Klg|!5wLbZw71pYhZcPY&u{8 z?@r!X7X-F0G&Xphx}!c1GQxH8tVR&3OK9XtTisxn@@!ZZ!-iOVQMenOAj`U`f%r&< z-VCTzGt2sJf9u!Ld`>De10dK@9y3FM33c-8u>JomH^q7BFVM(>C3-&7^$D7=NvmK&7pvk&g@1PnRbwA-n%s%sNy==EXD!5mk#Xz;$IGd zgF2{@*XmwlN`?X|j7b}tm0h5h2kE*!|F)4X$5a$s>1VL=4nF`0$t8GTskAS-umx@= z1hTi}6x#R|v?zYEEI7sc5>j-#jRzq61DTv&AkumcWHS8fY(#MCZUOSP!p0E%+XRfE z^$w}*;4B^NP9>F8nG8_qKUTN?>t2gpP!zkP2Bm@Z6JXNdbo80mDG=FyN*f^$iot|>Rh}1DUK4Dro0m=|&?$hAfxiATF!FN0 zc3EcX&Kn9Wi={+=pxAGIgQIQHT;m!l}H3&bZ;GtHtrF(GzEz{DE zDIJM{QotBaxw|k6WX=sC1ZZM>D(L8~S0B-1;YYblwYHxWaX>`Jmfo-ql5-?;M68ln?yI2ax@EuJX-Ggok`->+# zdfMFXXkpt7@0RrHs?I7~(ll%;Pt}b2vWef@Vgy%uWlLGT+wrlnm&q2n;BhM_&Cty; zFu=;6iAZLQkW+a!+!MAQ5_r0|I&{najo?9;j*q^c34sU0oUVz^{Rb^X?0A*E;K3-5 zRiq%zr}aSbmNS!O0<&SaF&=@nTG1@>E|~GIF|hVALAkT!ej&vjokv9mFg-3l~x4=Z^-*=$783 ze&VAVc{XtM#wBy0z4iaS#q(3W(XA7A%GAWF)Fi&>JPb5%dTahNYEt+abxcl8);RSu z>ZtS`$-dbILJ;vsx7w-&J38zI1Ch+ z^0DngH*DBiQLTlzqa<-*>GYaEPRFtygRl0ot2fLj z5G8!%;^xY5^G)k^!X<``N)<=#csR&o4H(90y?Qk6JIRp8eq*gnMY0sg)h{}a1Uy*U z>D>_kP+$-uR4&WDkA7l4YbMBu0UH z9o~D0%(-wlo|K1u!QCY>eZi`5SG~nyo>t`HtrF!%QnadJg~jAgEHTr?v`XMF`Z&6@ zOvFL0C{@F=*-UaptPB^mu^bzSFI2fu9GTA`A1Yp>YDt(Yb`n(n8wUYEVoOV&549Ib}$c1h`USc3iJmTN2I z(q~WNuD*iDVUllk{yBP#F(Ov*tmVPtW4vvWfIyzFZHJ#N^;9()T?i)o zzyZY;09BY=uJ4GoJwMka%DI&IlH0hKRrAGZV&KR4qj((nCgZ-2nCh6D{u<*jWlb^d zBK>ZYfIGZVM!MlCiZ}2xM=zb@6Jd$`#jc<64#31EBZvZo%o6tzImCHopXc`41D+_? zIoE45;Pj>Qi}nEj)Yl$8 zM!LIGx5}g5?vR%5?(UQpc<*z+zxThx?%COPww+y```LyD3pZwIg9`H`v)#s# zmBbIfxsHNJs!@b~eIkqo=dXko&vf#m8crA=Uqo1yy1pzJqJfT>J)G%kbVD2xAWI#B zp^-py3@B$Pp&^@`DpbR5d`13r+ch(BL(Er2VvWVk*+cjpheNCmy5IO%*uzBBg?hiX zkMKJxhgeE`M&e??d2f(qbW~#}p%|@gNPb}Ya4p6Y+VebG*uNyy#Q>>r zWRjy;^F;m-wt2L)F;BaCxM*y=E_}74X#Nl=+YrJ6+O;aUXcRn=l!m`*-e?C^Bwb!u z3YBot(0HUA1zo*_ViL9?&-}c;HE_|PucL>o`?T$?6sS-W50GhdCTu_8XltYSxu?6j z+RW5-+n8e7x2`gmRmQhxn2q1s6v<6$Yc}=Gjw1>AS|vMr+LmDU>p~sk{oA5jRHs6z zhnk*yJw|7ylg2d&qm+S(7C%_e?3aGHcAZ->)L_0mvy%TbX~9Jzc-Z`|W4YphRGeyX7U z*+i>Qro5IK{zWua+oU=~`|yuwC5ouMQZd7fSsm2$Od)HENLJ|9B#+rU;bWs&?PqeS ztHi>gTme1l*L9J=X80loAL*CB?gP$*43iSCn=C4|t~jgQE96_|DC@Ug8oEy1Sah(_ zd;FU!8z>S^DZf3u2pjFmFPCBqKQ|z?^p~Nq(D%EAs(z3k@AN%w+3seueYaoLtK-&n zWApC(LLnpj(+O_i!)zc&sHS~5jPBf7nP9$Fj*$OP!X^Brl24tIw(Zq#XNo@+8Z09p zeVJ{TJ$!q9mheXJ-&D>`*{8xY1FIT>HivML)#K}5u#LVp?~WtoPb(ykbaK#eXg|%M z*8$J;nw|s6_JL=Y3UH^9JtsOjh8;FG7{Df!qoBg=^NL?RC(Vb2zBX_7e;z7${cUG| z;KxAmSck}VXU*@jvvCgQ?i%}s9XXn`4%Sl??df&Rvn2^mRXnp=o0@TRPlJx1s8%- z%rU)}T>eH5p=S&xo=reZNNw((9|Sm?4in0NE9CJ*H1sreQO4;~&qJqRGX#M<>G4DS z|4uQ1*ign}qBof0{l_;%XH47!pa&bTw%R}}a1@nj3>ty}Uo?)1&OiX6dEc6eSriv_ z2tBm(8++4}2qaT(W77^nTB!DVuD$Y~Alwt#?kU69p$Y+r+Szjz@Bmu5mr9@G2%i~Q9Fpj_?QaP{r2wY<&Kk>( zb_FoPl%`7t0?TfnQ0YM<6^!(WfLE5!Lo*^)o8Ll8l57wVdE1D&0hB)Ep2C6vNqanP z@dg=Q-d3bB5YnosAFcrCQ~(2R)obPeIn}IdBy+GG4ukUHps=^5&ICeXkGmsI??C4d z@3x?g)A5~$8n6>}KaAEuAn2`<(qYh_vLlN_i|$}r!B3Psz!v~-O6$f35@zVKyl9F_ z0O6E=*F$#|Y394Pa0zi*f6p~on9&C9Y0QNCc5rTrW+%LIY5hQKZSKBrK3``%t zefjVE-#n5I5Z<-I*5%`WfDP=a$1t9a!uXDNhj4p8yQ}5@Dyc zw{Hhwb5GKoO~E!-Bp8_eFKcA$u>n4$jRxgSyCA~cUb)i)uwv)GsaD5xfS=z)Ac*;$ zewi~bh>KZVxdNB6gHZNPrxS=LUxWY$F@rQ}|LrIiP=bNaCN|DoWjReP#8HZ`?}ouj zCGr73=ZDup(ku+Li9o)1PGY+q^kRxW3IiY%orgZ@`gN{>T-+y?+T^}}yx|6>o_#txRM!eq4wGP(uaO+Q?jDj+WY zSJd5!0K#_)-TQUmC})0Yeg_-nSO3GxyoekWSDvLLoK_Fg@~6^k6iEY7SRwZJ>(4bj(5 zW?#qvI%ARdOneg)%)}udTy<&)K%SkXtE{dTI1q+Sm*&p#1NfA-ji-7S0YtXemh=l4 zAOj>}MK}6CI7e;qY5}a?(Fn~t2qG^(2M-Z~IXjWtx4>s(LvP+drmV4e183=iNquV< zY{s1=a9}pX0h*q4|1niCB(8!WYtk^%9P&R(wyJ-o=>v#H)z}COgCq#bTAT?kh?hL0 zPW%T3RfYtkXzm6<{PnN!7H@XtKXe!lF1`6bCpz~-&0={01V9~5|0A-TY%OEW z$%&9GTqiSPvugiQR5LK5kDy83__JwfaO%p&Rs4Av1+c76QuT&=7Z3u|6ddSTbcdi? zDdBqb245j<@F|bBCk2ZMb6gz)JyX{L4KVUxOp=8Gpsml-LP`s; zKjph(E9+hpFXZXnR<1)2VH@PBZr0BGO)D1=-3|3-?!lS@*VH%S`_7PAf6Tk73G74p z+()H=<=Kb}nd-BpXL7p#L9=xBx+LimRFF4-+cLZ)aF+?uPb4cadj62}$N(r?-Sbd9 z4!$&4FrYgyw_-zVly6=A`gO_($+(uPk?>0jw9)WW`3S_1r+)G-1K2NC2G`a@gASO~ z%}j(1F7i~59B3MHAbyM@-tP{EVv`%UzhETfRCVY8wvFHkIM%;9f&;hiz&_#Vf=c}v zoD~17Y$E)Tq+BkzGKcH1c!J*S3eFe-HXi`%unC;b4w!?=T)!0DH{f7lE5AHM2Xex< zmd?Ps3)GvxHMOx_1oDEQ@8o}j3oK8aRQiH-1}G4}*$%Yj^Fdmwzpa*u4-q0{fxC^s z6h9**X5{}ea=yHABmnvWfQ9v2%>RN}eN1&;=)gV{o!EB>Py_wC-rZ*e zNo!OqV9Nk}gp{G_SN?(dS`mCxnRT3T1%q|_Zub`0(+BixZlDdR&Knnqz~vVb;UN$L zl-WmR|CA@`1?pd0I&PktfT;2CmF@*ZQFEbzl^Gi3s%Is8fnTj?O#}NVNj4?q9t#{ldzs&QN?kyEe(9S%SHfZt&6SORJ-Ipn3I0QI zxkLLv1FWHkzn%f44nF4R7~opsHi9lACxiicZ`xWO#f$|@**sW)(|`RpO!cm(sJ@nb zS0e;MuJ1x4J%QVBYV~15sSv ziacEb7&UR~32XrdA3vmn%Rd>^msK4AzE}W#OmutPOaw#@I>)VXU)G~U7mzlzADLwW z7oJgVrw`04dfJfqAAxG74{j|{T;Xei#AF)6`R1J(+Er<0#!H_ZD+Cm3ek`$WK(9a;@&rQM0hhU&i6F&rr0huJfMRo}CN}+R0 zdE^e^xNEtyJTh(|u;;JkXF@DhCt$+4y`gPA~X3qATXaCIIbErJM5s zD#I6|;i>~}f%02-aiUKhSSK8i{67^FMewO9k{aHozBIV7W9D|j%@Us zt9SoHyYU)uP{2{($6iNiBSHk7;;Xu;hPP&Pk9LK+T>&xKpE%Z@G~7gK~rACvZqqd7Zk= zz6SUJfPzPGzZwL)xMSty8XGdg-kyEG`v09?SMs3-fndLDt8d_eW2f=gaxj?TQQzkO zcY3vEU6O$NgtiQL3BX-f<d$9P}isNCC@NeNN?O5OAY1@D@=u7TgEsHE?4X^QwnH_1G5&HO`aZu%Z)Ls!Dej z1y?-B?1K+r_1g3ph*@8_(QL|1wLuC!HHyajKkiq}hEpV+qUWoJ?RgX#=p5*)oLykV zWS&TmsaIeD`4U7w!1r!e}_HlF_oqLhG$E*g+(!1+rDe zM~#_o5>cmEZ1Grak~z(1b+>|E9)7xZ7$>@|T+lbKv8E?yYH2A4!1RB7`*5iioa z$-L<1h`!EVRr_&V)qFU5i5AZ=Wn{nRE0SL3U$0pEVfQAD$V}_j;!(^5NY2t;+<_!x z?A~-JTt+4YI4x;6)9Q%8A@F4^nhm^y4zL}ONs@wSwK|U8XA$%P(6OVL@W`|Kqzuc50SZiL zg^6b#YqL|Vh(zCRtZsgs^0AiiI}ZEEx$Grro!nn8TZp@-C(Y=KKc~RSHq=lLkm_p`=hKii!1T^yz@L`2QNqO!g3GbV}%YLHuD9;)II5yc;-%w z;95|fZ?^lohZoU?43{oD=4e%tcQwcPR^a;Q^)O$PK2Hs5C6aKfpdxkdiC5JCh^wSN z?H7wQpMFcI5JqCGPFIQgCpIWClPJXXJK7Z#T&QdfDcC#xF?TX#s0o2w7@zc==CC(k z_NkSjS392TzrXon$)XG$#(#LA_)6%wLKc=?=eX%_cnmFP^E{ti?)NC`Tm{EaL8(W>hPvkQ|gEDCjyEhY2XOU<$2R z=yzFy1+U|IoTGNfLaSiyaLZP-Oc(jS`m_~d|G^{d9h;C2;EG|=WN>w3jGXBwieEPU zszhUkSRA!>U-Y5S(b%d{W#S>{_kvyC~QUo z6}R;;WYsE2biMopTVFEBjExne>h7!Ju_pXE6p#0+I0T(^Enao|P}p3F64j$v{3;b%4YyEt(*st+v`6pXQ_^UqB+5U< zq!~rT)ZLGct(o4{cp4iJ>xE6>&(b<-`*tIX5+$Pf4M@!}ai@e#*LTcVaE0sQG5#_L z$GfSl>ho{O$Xq}iQsijx3hexM| zTOR!mZf?EqXRf@o$W$Cmzv&7;%JoQVWpfT;ner&QX(z6thycNt*y^}oW&3-B`9h=; z8ov0vfYP}SatVw|mA^07w1yaQRcLQ>E3S}`I$led*XrXZ_Z35{)zVshjTG-|My2D_ z^g2&?;b?+8wVqCr?|GzyJr&M$M+*JS7)_gl5Wvvyp(0;|qhNEtmZRIamG%TD)ApH` zdo*wf`)d8C9Y=qMh9f3My13ML(UQjcOM!(veXiQDmX8+3zC}2r>b*Oa&rt8tbEp3N zeG@-n$x&#E9l(wNoyg6hX|R6Ho)zzY#M)Ebv2O9f<5`~~2c_!sJnpdcEQjsK-uYR| zh`;1Ew|bn`F?M#FAC;=zm?GyV>Vf06#QrP>te7)YmdWD_$;=Xtn@!3sE%r?0nVx(~ zQ!lLolD&ZBdP@5uAY-FywOhZcTFSyKC5kqMO@mrOnS)LWS9W~q3V)$A4v=x9-1LM| z=diX8$cQ96i?T3HF2#YurG}_J`9%4tZ;B z@_pIx-s0m=g=H$)%~n5RgG7mCh3!Y)m2S5L-!zr7*vN<+2dDP-(`#vJ=Dx0<0|})vHCge z8X)2P(M<}*dnI$DmT>7HHn$nNbmL!L0zslS=NGO>yg@{nQaqt#k{Zk)=`uXhh?%#k z%6XG`vCU7_QRE0|=P64uD6r13f)!MlnR!RCv!)G5@yuExTLev>G5tU4XX&5%7Mk+h*gTSEtmF1SqYgd0K%oC*x~t1MbgPT&GJ38UUw^< zHf8DyX&kTK0#`upaY*qpF^M6E^a6s~z3HD+cB#S9!odZ&pF|@58KGk#@H;mY>I%6X zV^M?h59Z-H5J587v{cMLgCyP=CrKdrSpc)3L7W;6i}$@EB+;g?@n;@H4X)xbF&`q_ z10WZmADV$7M(vJQ>n!l(8>CvUGhl%T5mq%8bKoHY7SRfIZsVK$rSaV6(^ltJfJt-K)^sMHVk_C(zqBW3{%01?P4EBB z**26JRZ2Cw>RsKCCv>j`E#;jwBxy4HH}vP)YjKA6GB=Ea5Lvi#@A27E zrvw=W(l$DfHMV-bofrzhA-mHRk~=;GF92F$r74o>SdUAeW3k7OV6M0=8=?K&kH+Ux z$<}aQYV52M$LH`Z8Z)mkQ6~U_EAlo=^1vp7Rrg8W&&iR!f1`KJ^_i9mkf2ZhUdp8P z&fvo}24s{!gg|QAvZhEmTEp^)UyD#7x4#Mtsn+gTVFoTlh`6^SSNO~P2vo5DfbrnB z4+^gR>_<AZc0m)#|8-khMH^4q17 z+|LV!W#AVngjq#>aFO_(YVt2nCaB29xdhfuLr{No!hT8J22J&omu$@}0@^Hwtjd$- z3Y9FyhQJ@55@&)+x=%fb283qlQrxy(UOP=M z53E}iem_U#UvEjR1isbWg97Zae#q`XJI@+o zXE|^hF@5<0HnbaFDaHqX2dMDz4?EW4h+IQ3!K-VY?!H>kqrbWXPN5e=R8tZ7B?O>d zFpIcUs^xr;Eoqe<^NCXL(Z_XiH(v+u;KNulD?5I>G5rbcf?LFe-Xfy_!-ikPWdsc? zx%F1#+goWnYRHBiie<-kdP>pRA-qEbPPoVNCz1wU-Ku0I#CW_oLI2!Y7P&_g0ow)Q zz=z9MC#YY=tY1?9bW5PZX#^_duyQp@1QpBokTY9_&262g-K$KwS~5?*5j#GiGt6zm z&st)g#dJALryzSdg=De)N!Oc>RK5%MP&AqL?Z>BSJQ|yWipakFm-()|*d|0c4`7qx z(C+UQ#VrD4LUV3e*0zpl^rmvf-iD#_beIgh;MKL+_C-ca`P#E#N)@r$RcK0whCg8! z=~sFU*|Qx2mm8HSrZU4(z*f-FGim?Usvc_h^~==1_e}U)BeG}It>s17vAUWYTam!q zUTW)xk3|yoD-Hjf zX%bK=7z8917Q@U2J2YccO8S8~Hdd#_Hzd0j zUEk#3)1v-xz%$EXV(0pMU3&vIOyxDB1aR+V0r3|gW*N2V+6JJpavBN0IXSo(0hGT? zS<3+2o9bYJBg2~KP3_o`(-G`s;vilr89F&Z1P$W);fekQ8x))K-)ty_HRNQeS3<0G zOo+rrs`GDgp^_cAvY{e=TCx9n^JVw5+$SjDt0b=YD&}4tNIesQ|CO5vyyUr2xR~l3QGjG3uo&x+&^#m;(SDnP=*krsk&WNYG8Vpah zh~YrxZ%l?@Dub<5ye*?OS)}hj+E#9RyYl(w&;4ST+Q}Fz)x6!>VNP{dX2i$CS{k1f z{hho~PviNwd71aDX5QpPRrJ0eet1NEPnqDI7Y-r7zaW;hA4;qYK;z}v6ju1DRACI4 zrRC8HU+tl28;6WGyFBombAE%-JIb zvRVU#T9$A|F(DN%k*z>0^>FNQ+wv?$eWBxx^)d|`Hm3kN!aNQhE)2m4*>}DM#A9;V zmhWN;FHS;~fsLo{*4F;+!uvMz90-(cdF*eq8^Yx2o&SsA{+o>~gy%-M3PF_0w zQ#AjTveSlRg;;mJ9|~)UQDe)G1a%ROi8S7R)=owb{8uVZFLdcfXntuHH>WrLPs4?Y)vc8PN>Y_bY55mV zI4smM9M5vthaMQH(^q;ys06%GGCML4ho;k zn&%*o3^%50Fi)VkavnNkk~PdLp}stJRu{PM)|A@Q~x*)159#SFXjP-zn7arkap~UcGRH5hPrbUo{$d* z>*2kjvH}XSFQNnxf!KP2*?nSt)kHBe~2#04|K7y3@&GK`O|_UZJRIX~oN3@|d;?w2*y*sBVm zC>)jcXw}z(dkFSv2~3_!DJm?PL(+)}$S!xAB~9NBZc*l$*z&yB4Z;raV87Jz?^LGi z$}#hDoqUi?T1F#L*=NIboy>sO9Oaw+`J=2^s#94jKgG~N0q;ZBzrLtwH?+zMk&$cW ztK;zPX!K%F355pE5FrWb>LyP`?_M5DmTB)BX zYR$6YA;qI>ZCmEGK;r0)Zx$cbvgrED7=25b4nr-A&2`7}pp!G{U#Ea&aydsmXG`Ck zDRwF=Skgzt2P#Q*PtCJC)d6IgI`#6ZW|eY@w1qeq_0k=Kzvi)WInNmj1y4^I??;3w z19Xk5ts0b*_MVjTbId`m$e)ON$eRDj3;=^(P#Lf0L;6P!m}+F6U)EW8^Lf^PsE)85 zor*KVndv&eEl8e-a^QxwlPor8+r<_gYFSrh#dUgW#o~}HGnX7y%sksQZlF+Sb=VHi zcqqvQgx!I0-!yVSFpccgL{?_c;r}XczDDy+WyEqI+DgG(0%A#iWaP)^;-ua2fL#2N zcQBZ}d4nKBb zD{bU0qUG;z&^ldqtD^ha(rTw%BrA*h`5{uj$I|p$7F&bIzl{vl>X}~=V!)QwPrR3Z zQ_~e!t8=$kMGP}xBW}KC6?gGfh)uNI)2d9DY+cZwiBFws!2 z2K2wK%E_D#d#oc#Tlf@GXB-cELuaO9uKa;s&nWE=IZh=Td+D%Kla4U-(DdS7EM}=R z;`1Lw$|e#qGYqyR#zN=z{`dmKWPVTDzws;PWqbFoJZ6*3M&_~7caBD7e_E`PBgeE6 zwZ|ISfAeVaj8q6d#`DI!6Tdw2G`WYN#HC1EyO_vUvb=m+P*N_rK}8P~!Mqp?+HCRl z{z?5VS%r9B32|Vp6iEIj0%(uz7RZWcDf!Zvh!kDiZ0IjhN3^DA@;K|`qX)vgyjDwg zcWk46cSl8CIWc0Ft+bwzIVq3AfB|_H@9l3L2$-bWUlZ+r_D0)XWPWw!HbBrQ!FAV0 z+Mu7_`&plVh-51Jf|lR2?#p+J#~v?64}!D42Fi^EftqwA{jKo@UMY`y#j?F`x2o-D zNsWsp+_u_m`W`Dc*S#}@IDBXMBx?|%RXhEOHnfDF(c?Lk&f(iV;RszSGSlI4*B*GZ z@%<1lD&*v0youI4UdYMASoY&JFraW!e@+Jx*lAPpNFW0Dp1=)wSh8+_>@;xnvE-^A zOasaV=7CKlZ+gw937YSTWB+68ze|aS#jS{jDBt^P{dnY0BY;DUJ#++?xAa~?>QXXec`pMVhwS&!;60?|>lSufB8Z?S zb;p4ZIj?!KmOv=A#}IM~a(EtU0yJ<6a{7!tYMYGxc;U~m+!L+eZ}bMn0-Q^k=aBcS z7;TzMWdm7vjHY5@nG1m{ord~qZU23tmVGN4M}Ne%FYKI6&y2#{Fq43r#(lt5Z2pY@PLakJ@?6Mmn=&bSNx>np z?~<=1u&Q(*aT*x&H8yp4($sQN7Nv#KXYh671Qb=8)P17wt!Yt021STAq#T+lE&;tC_4R zuUnou2_=ND*i_&YU!9o zdgpXZickX866(CQg~9MT@Z~qg3DG(;%Q_=_o^}>%@mDliMXj!YbAMUA zm1Q4kCtQA#Y|@FDL5_*%l!$LFW=J8bNlIS&b#veo>iK>KA2jWYg#PjsL{Vs(F?l0 zg4I^4tGHF}@^<5%_SD4lawD!HPyw&^ za=V*mt%$(w*TJ9QSOM-+8;X1?A_XtqzqfXq={{UR+G>2-A%Hf#OmCtr)y@a)X@4d+XB>jbMV%JvJhP<&s#%vN2iNHb-Zvv3vgO_rY<74p zbQ*@kVE>rdebljVdwaeZ<$LvKAOcz+Pfxog*Sw#2RziqHVlpgJ@YM)s8`1LQ+1;qe z#<1eE57Ds#mUddyJ+GE#7Py&6CVx(xHn1XO#ENB&VX3~K?W-K&eaKrm7Hd0?$^Hm^ zS_+b059d0g6sF^(_vERGntqqRX1HPxL~~uPIV0e1mp&D6BdO&+G!StzE`6d(sC2m= zvtvrF%TXxRJvfX^)hMsdQTSI#t@q^DFD`prh}l7gUHx2$W;PM7`X^R^ic(%aMLuEg z*rNTnKQB=V+|iin{ySxfFU;(c?VeD2L_*mE=>`_ECn#DAi(}%#f(+`Jt<&SPS=&pn zT}q*a2(u8DMXo(vc5Vq;oOXSz`xcdJ?fVeCYN%dl3cP*4tQE#Exc2kf zAEcZmo!3m=_sr!M#t4d{1@iO1P8~vC%plwNmoyO&5qtLg{5?hlrhn?suW&a}pHuI* zEDcl*=&RidBNUB${wQ_vrVK3p?)1ESGS-R)?!lZAaENOFQ)-WU`H~kMw^aszv-7=~ zm`0&W71G;eOkUjhuF|FJ!6$$6xr^qb-?Ivk?b9GEPkkA6HE`e0L#@s+4Mfln4=tst zb_?NJC>59u8k||o&EY27mbSopa{p#1dp`3ugHNv>$=#FtSBln{vZlndj4MV=-W8+q z?^ZEf*OrinV>ZpXzG?H%IBvL`)VieMep+kw$80^Hn#7VTg)j8SQM(W)Q_bU*5jqC@vzL=sGiZ@idm5=T*&9 z&^9M5L(SuUjF4Ye)7$&W;Aj!};TZ>&g}1eq!rJ1HVu*-8$1r~O@M9apZ?8tBM z=^Kq)=1Pfj1{()Y^=iUHc$^JeN3hvVVuIAS`(Nc-rg$rw?H?I}{OeqQ!5jQ4W4H}k z+V64-`lFRy5|T{PzLfj>ox!q{*vNY4&zXvP*K=%xU-}zGPGN-~@PB>5$5U3B{YmBp zT_8V`!ez5RfJfP#i788M^M+_wGr2$@jy(X?IV+}{1f4xVrITR|i^?yr5^~{ZqJ_mF zX*O`rC!fHG6;rl($VYX&u$TxR&c$c3X0^RD)jZ`dXhmZEL3Cwas>XtgFj4rN$ZvB< zs;;Xz5-UxL>SSi*jMRo_tLCmMe7E_9zEu6D8t@8knl`hA5=-F>Of#m+ropWeTWY~$ zti(j`AAk~TY4g&vpdyWkg$|J*uv{5>gMJjl36;H(gog*M(E*JnKUny_PvN_kCg(yWeKRIp-82Q_TL3#T3%bP(f$%S*cPmAhh|<<$%E-~53tIHSLcxgh%l4+ffSXlS9DwN$51xP>VvazapjxO=p-3H##OVX?2Fq`V1` zhh=!RAAck)kp9K)*23`bXA*VNA0YpVzC^#q?HU&SrT-5N5>c|MCJaThyoBpXhSs3k z_Et1Ar>_r%(k7ni1Gl|z?mS93ueNx}lXuMan6v=&N(&AGQ#Cg{@9E8Vx^wwYINxB3|5KuHyR3 z%H!L<8mp-Y-xv?SQy94J58Qjp#8!!Wd!vRQ(=Qhbhb9>nC+)31;wM&!V;6kca`=}d zP!O8%lty|v+%iP~gH)e@I9$FDDq*FP`OB%{hPj{!fVhS&^ zq)g+-O4k}cg`-mp#-C+jRfkTnMaW^}?=(u!s6Sq=uJ$eA!Dl`oC*#AmQ7G`q$NsYD zL2Wg5?+Gnf*k~C3Ax7pVn(C4Kims0!a21s*-P}Sm;ED7o=&ntaFZ}GUOiwSlv3qxD z!TrB>8=Yv^03p`9^>9DZqc>kEGu)9kg9xg0HhQLNFZH-#y{G^~uCQqxLJr?C6`gk< zL^ld^0=o*HC>^Pb|V_S4V1m#ZJsLb zR4aK)e$5uIx;B3{DU`vqUAY`>^>ol^*Q-zc96p);_eLe!2e`0Wi^j4>EL2Uf{KbRG zvSwrZi&%@DcJGqaG-c8%eio_*QpCi(maCdra(p?{Yr8cRE_;6b7#8|>(jSc$YEq|P zbM${Bg&s^yWlev^n8$|-Bmazqq$BB%U>p8WN-N8ds<-xG-f1SX|3z{|>r35)ivtmz za%P??wX1uMlFUk*;tB(@G&~K7G#RY*^vX(lb4v>z*5RrB^vV)v=T$;l%*wEwdC>98 zL;0EKQdg5dchl|g@$vA2{+^Ig{2bZ41{pP>s|bGQ&!+93!4b{ zVM2I&@{_v0^<v|2!@b%k3l#BfoDj{@8m@(a?X8)!#2CsDt7PM ziN%>)Tm86Oneb_vRQ!uSse2fVXBTepws5pES$-0eA5Z&w3(F9e^BlOg_4qB0_Z5*M z|5u2er*;m!9}t0r?&j_9TiEHgVr|+VcT+3xpp>ycY`PY|uzz0pd^mMPJ%y9=#$#DQc((BXNT!I51>lq;}8!@X@#gU}&mkyP3RWii~#n+YvMw~=$1QV1P#8yrh zrcl8>S`6nTb}E-%JGXaC6u%r;WT0))7g}KXm^1t7Ga_GWXhoZZbn-c1TUT zZLqNNv#RM>cdtqgF2g9y{;+|Etmt0md&Y@Wro=cGl&}p9hR46vOg!krp(wi9z4Am! z`}ps=DT?{(4KaD(dOwF2YtSzsriJ83TCX4-OF^=JYMW4N&cVERphk5^G{iV|Xs6of ze@cqnGk@hMaBFQ`x9_MfT<29JQB=t_F|X5Sr9P~K{k~pYAr^-d*qddSV>%y`>u$FJ}bPJy{UtuINzAod_OUhk6@Jmw1GrBN}2NNje(lYA(gxvw2hc<;ziT`A?A<{!lICsFHC9V)*NEL7Phc576y{9iuq)DQ?H(@ce$j z4^~0sO0FWOp^sC{t2HLU>WyuKHU-qxLNiDa$dR)qEmr*~WuHGz-=@5e5t>2Rdo0N4 zb(xDGz$JTrXMA|@=DcnK+8FK z_sc0^piafWiUj7uSdx!8GrPzHaQX^Ep^_ZXPcG?v?Zs&Xu(Ge{h7a|;8^JozsVZ`^ z=&4jm((&0bKNf&>C^z}1P@|^`q)ks{{KXN+F7y(<+~U~|wQ}40J=yv8z6L9hk2P)9 zD)TVt19Ck>RSlVum0?hXa-st0+G(ARn04;=(I^o2M{L~R_O0M1IqX-!%#~zxvzp^TdHm$*d1Ve@LH0l!HD=>0yv~z#GDfLQ?GZj}^ zquVX1SKwrQX6p(idi!fJQS~&!cRu8<)1R8S^I5JJ{ZWzulRUs^Iv)#kQRd~POn75H zaGtHk0UA{}W#a5!9SzO<`eBmE_gn}c(&$8P&J&BKb>j?k>Yd!b?;y1_QrF==-o(q9 zG6w2yqxNK&Xf(wJnVP~CyuB_>z=&TL^co`uZKmpv(%KkM^-Xpn2I~7!7_csQi>G*gaXt|N-6ORmN zkkapZaLg$lC}e!Gq1y~}C824^prM6i|D^G&<9-YRz+m$jS-qXluu~vJ&&yu(3)tC7 z3aV}92L1gplReY$dqh9+sla)D6;H6cxUj%{Bk`Vd;wlMLb(P(DF*K0upT{$*Jj=r+ z9e`FN+NMA7oE;qvui_Lbkb86jr|)@LH_bqO{V_^-RYMnJo1kg%7TYK=<&Mjq3--Y0KwUh=+GL{!E)1I94=@wOlT z#x*S5sd^^YB`zfv^nhWs!jCva6w4<-J1Lyqd6z^!hVjEC&QgVzY${FG%_^|;num3z z$uv>H<1wr7?~PlRxv5XUwGIFr62d(FgRuWKGpc*Zq)<9q=aQP73P$^+|7Q# zgsA;>RSm1rarn54eW(){S>who^PAfU;7uH0S8m10!0|JXaZ9@WL-|)498jav@@^7? zq}Y1tOz%CV`yu{E9+bXS_^)<{@|eOXg%3j9MX`}-X|N^^-}9JP(|RG^fzQBO{@ot& zt%|d&nq&++lo+m6fI2oNfZD2-8#>JL>g?AG-CVNB3}Wc8DcjJ#3u0SOWwFjsgAgFbJrXhO0^V!4T9Zu++udzy6DnMzcZ&LxPTqo>BGBUPWk_o z3-$5xqThGPAHuT=7joc2-R*M=ZbX%HLlLW8t35%ltDH-Jin>WC#!|MQe^nz;+rsNR zDF4}8YCe8Wz1v(G0nds>N4J7S2Or+|@#$|7(ICnj#jDpXjP%0g@`ms{urE`7P%u%rB0?7QjXnCbYegm#1Y zQ*AoybsEgo;JWM`(~THX%$M>xt>a~`q?p*giq5UFl1jqaXuM@O*=M;;(P^=^wDLyv zydPYQ7nSw)6`WGF(LiN5IisVEta5{$m^_U?+MpuOxSF+gIU!0``4Q!#pwyz=UCk&Z zKvlTHW-LrWo`E@i%6(#J0ujpjo_DYSb!&_DpBjkgZ|*+Rbd-=GBl z7;uD&@5z!Wzvm;j2j0D6lH^@bGs=WsWo^eK>!{m{zsfR=QP(go$oZ;tDYbD-v2^~W z@x7`OEMCCAw|hyDknkS@I}sBe5+x3)AN9sbWEeTfB!&j#5MBb&{$B;YqIb zD2#k_?%rbrN;;2SoJd9^rm&&$cj%g-I#*=N_lZ4eum5T;?>=$_DauW*!h3zB+tR5I zRFvCPNAaRBPplxU{=-auvc!4TidxSVL@xVeB$>as{XXU+dgN|?LoahHy{8K4ho4^Y z3Kq|vN%~k;r*?GEECFv^XUtuhWhFAa&`KG>{RazQ?Z{K;s@|y1xS=}BDsyOw z7aL$30POgJMIW}sHewi?i4GgE8k+P{V!-v?RykVlmsaJ8=i^2d?A#+ou?MH^9uz`b zY_vtiR|3dgUkVGeo({VD2?=dKqb;)5Ah@i0?zBDA$fTRg!YjqCklnU(d_ z@2jFocogBac*l#&oyf6FhpL|X#>?|tw3&{Jk4HGSGz=wJwm)HNn6`I;YPmP>W1GOI zWwCtZ>rt{_EyejuHe0F=spFTN{UVd3q#P;EVd1#1-8Z8)elH6y8?x zMX+vBP4c-FV*e!(Iygj^*j-PTGjfs~TYfJFkQzo#Ov@AH`7j~WjJ`}qBy+Iofo&od zuC^M;5aM5Ry>-M`_d#?-*Rwo)k%%pLAehV27U7aMV}_4 zi>LCCxSh$|dA^BdNIB8My`H|tcir^*{lZ$5+Q;#X8uybWUwrUe1N*13xD$a7@Rdt8 zraupKhmceJ=f5_v|3Sk(^|M%a`DKeiUDGTQY_Z-xR2^xo$5Wp#$Xj!{P2-yTPDINh zYkO#8Pe8YYg^5$?e7k7WQU0o%1ODCTemmRq*MOz?G|~i);y+*DhEJ5okykx8Z?=)0 zy*V&T27e{<>#~!yi2l>hEh)tJTYyKSUoZTr###?ksXl?|XpuJi0U)s_5YG>_{_@wu zbh9@5*_ap3z_rQKf#Iauc;r;kPb=cH(BG^za0=GLoS2}rh<@D@v$cX<#lv>?hZ)Ch zS3y5zvCcwAu;p6=?4B$lwupvq-^Tzp(BFXJ)P;_t6`8wQ(fnDIOjUdGAf_?Fa4sz! zslRmmT!mouv;3DD?}`!K2r!!pt3I9QU7=kV68D;7NQ*MqHwL)3fA@q@c}NCj)bq2C z4{N`gEb8fb;}Iraj9{Y4==D#{P3A4m!{P}Q{jTc@Y1`;4vsY-%G<&RnI?EDio-n^I zs0W7FtS7rXoJ0pnty!1M>=0Zm_aJcN46|N(x6qnZ*|ht6JIIEm|H9}(Y1s9 zetqTjq_*r5t)`DlG#`aCvsm+6!3D`Y_(NaZ_Zkov-AOYFrlkym0-y`DG!M zc_R%9@=5$0eAZ;y%_qQ|-~kek|H~^~ph-A-v$IIYcRTT(#WhyDS!7KRezo;_bl=tm z?f1e*+>)4s`Wh4pyX~ab8~!U>mPWM31&Y^3+zP-}# z1|+G!>%tnaWSk-*`Q5x~D~GvBmKO1YUH6u>XYAU-hktDZ<3_%*gyxW|e)}#Ji|8+! z!$Zh%fkGjs4Pw)2sRR(o2|lbYYz5Pa&ticSavCSLZ$mvOB|@6H=*grDEH<@dlx%1J z(h`-XOR~0Y7!STg3*6|G_dKKVXex@ zXpAhU=W$>A^c6nFA7e>1!osw7hDP08X^N7dX0@v)DPuyJ@0!!iAICo%cTY5>C<=Ky zyg?7{pLNc;kM!1J`%qDU9L>?$9gzKvYo&bi4g)>-#%gn!%=*eA<@b_lyCUqNtw3z6 zRK}5u4i`dl>$^VH?_8pScIxt6zKycH-?Vku4w@tsy4wvhOn1_vZ+FdL#lrktx#qPO z>BeZg`FM&xueua$o`m=~`WeQqn$9%`Ob?2il9ay>zi|FoE+?2q$3^(g_0SCyF(PBit;SpnZT50eSJ_~X{HB?7mKb~^}f zooU*SLXZQe6AcTeB(=U7KW5n=lIobBpmhDd8ctm+L4Rr{zZs`opex7!lI>h_wc(0M z5@H97{r-Vv&6G>nGEu)o!#dZmD7CdU@@L&P7EXOzLBv(jf@;oi{y)QMIcgeXG|XGf zbpBm+o30Sng>FoS3(i$h?cbkQBj3+k`M0wcx{`#C%z>vxjOw3Nf?LnPCu0V0UkA$e zsE0}Md?VWiuUE{{e|UL1i73c(eFG{1wxDiiW;Yw`o zrB({R{61XEoBGdO&eACUsgIKx|D60T>qa_t{xz{~gEB0&`)*S4Q-4yqR_XKAI)s=X z!+P1gi+t9yAAU-7jiNc^xwnD06xm4EMSF-8UV2Prr-X#b-LZPR@Oz(l?`|o|watlU z`(E1PIjNoDWchV75R@nWw@qS5Q01GTcjcjwfK&A~F2-VG4v38#7Ig#Mc9RCLBH5PG zCGwGQOYPfi(xfD`o8Sc9efyikeT~*#PVr{)#Y?`^){#V&tu*K*>6#^V#pb(Wm&f~0 z)bP}NSIaHcTo-AWP;u1|)v1jBsOOUe55vO9U%{O3f&g>hFL37o^K4~&1YW-?)U2CO z`a$1ey_GaJvDqd(@Wz!{=qrDv+lQUcWSTFEs$afMWwx2bQlc50ttN=vB@^vBiiY>j zau=hydAYw=b$RI`ie`YTS=em(x7kR<{;R>-JK=GSk^L9Cx5v}=XR1t$-6JxN`VUA- z^vCmDPbKd=VH0y6xbx~>gWT|+Gci@jCHZhUjwBX@bho;D2d%LRnBL&nF8}C18*{g$ zcEew@gnUXQ2J@G+4G}Q&o*f+<-1|3Z3W5*sr&C_LR-<^o6!Etc zcn?u$!C#=gqf37tB|$?6pZfR~@xymECBL4ayne#a2jkLZ^|p4St6Q2)A0{F?yWQAj z??>DvR3`ah{So`|(rLca$*fw;t(5t7YOv`ZM;>tBBCUg#JNJ4RYOp(8IL;!AYLp77D7?Joa--g$n)9!M!O$ zzN*YEsE%A=Mse~lPXc+)$LdNN>pk9FVpI( z48HqEH{9J>RfGVl1_mwCU@Mx;Q34Pm8K0z0ddfy+T z!TJdzLuLj39uBy)@M9u(!JZ`)#|uQPxx9`bf{JrHVQK>6_=C2kpe(F+&_P{)PGl&r zkIF*xoff+uA;rnsYxZ9dM}qRRmAKGw9AihKASTRclNE7MASR|mSlq-RE?Fk6E(HVd zs7c|?c51_m`f*AKnPS#Hwa-OEOnBLWo9&>^6)jhD{`2W5X0A^V07P~kR{m7@s*JD# zBj!dh{RNtwpmj?lHpD02c(aNeM5<p5Y_K}#n{vWa@ z5(Jj-A;?xPyLq5MOf&~Ny_(6EECQmm(`$aVh5B?WR|N()#$dGLoG|v=GnIfS^%@Pa zXXra1QvaM@APA7=w}Fw}Udxl_M!3h2t5{mC~1f z14%vn+AFk0ixI;0#k`gxl?!43Ds@+$nO!l23Yh`*NV52^%Lw=0Qdk}UUoKB*A)>nm z#ggfp=#X)EDnVuYJgAmB>XK67Eu>E8g&Mj_|KrkEBToUSWiWkjPs0@D3WkI&c=q?z zjJYHv>}Iea^}b0tgxltGY4<+>G7R&m_fyiKDJnP~Qvwk5!MJCJ6Ym>%L9`Z>&&XUx z>Y?KgR`N5EM-aD;+PjKHx)mTG1+yI+>iz!jP!A_n>%0K`seN_eJ*odq?2PdIqJb7@ z*y3EsIb<2Q5Htk-y$$D2fX;lMcOp3%v9BTAkR)J%8ubl!ZTg??ZWei-K^$y1eKq)> zuWij}-&{Kz0*Guc>x|@zBQpe~PIBCkmTG-SJ+a!pY06cZm;r0c<3aI%A=vZGND9rp zgNTkt{*V$9ghETqQ7-YnD)5mDXa6q*#%1?t{&*n9H28ZqR&d{v_wEG>M6CMP!-T@h^(-_i;3TI=liGRqw~F~l7zvG6GI6*#REXH zoZf99^Fv&GCex{-fcmYiC;q{oAbLHJ<$C9iaa}MCSgEN|uiXHqFFO3Te_K;ItqUM0zehF<#%etZIIUnCjU zh0Y&RHFvWP`@X$PK-H_|D5)FBRseq6OKe{0`^|q7Yveack*e2!NMnAD_Mk?D!qwA^GD9y6 zF|njJtN4GBHKy+=oMXylV8rO!cn4WwK-F}C>)-m)K|mJvQS4=O`zF9sq`>?WN_GSG zb|4|}D0^G`$BvCq#PiOpkfeM7uGKo=8TOg>TgYhnCXfD)mK~xRpmf^|_PaTDHc&+P zIJ${lM!2B1`nbtOSN>uFk*$s`x(7Z$C+A(yuZ^O9KL~n!KI1xZ_Pi$kOpHW99&T7r zTO@du|2NwkFZ824q|u=4-e+n-Fr+4eBLkA>NAOHB`VYr4D~_1Zx$P11zKD2<5;Btw z8n)o~ldK`wleMyr2DDU@0tVV^OUdOep*63$5ybpo8CKm)F!rlipm^B3pi2q~LYIo8 zQrHR2n!|6nyZ*?;BFnu0s=iu>c;bU0lM1XH>pf+QlhD4LksCz$u{ag zZoK~zLN@z|QO{P~GC-30v*E4~HAop4k50dO5{B$R&6m>jal7z96tw3aC*MQ7JDzq+XrpRG zTw=uRei&Pff;e5a2ji{Y7@I;0vJs-640Y;_T(<<>TEBlEKZ}HjrF9Mxt|pNY;`PSE zI?lz_R6^XEg-O1|KqHTR+WrXfP&4v_aFtU9GDjQ-vWk|W!Hw?*JOS~tA`O;$4JSfN z_&E}D$NPc=QjfHX5kgEzn0zY9&(H)HihbVL*P=!Myynq=sbT=YJn-Ahh0gv^bBpjK zkmCtc%yfBrdKkpL-m#SVDsB(dtFY=X0jL;DEWsKe_Lh*Mk+dZb3dEhCd?#=+0w(<> zuI72iJsPA)s|0h^jL;$}KNgKZM+KtgxPdS^YMK}qz_+ZBLH7U)W$2OZPEG#g2UN<7 zeUA}}7IsB5z61nuyP{iy*%8RzRqv#yvcm=RxXZ<0X4~HnWb{jrcKAIG+z9Ojd{!zV zGm-qz#eK6-z$*#qPum#HH_^}@c-~S`tBf5W4m6jWjyS$u<#A&PNTXSvvV9Z-Ivuz@ zDM#gyAKLSFk7nKBpxrb);csBed&vG`kd(_vUI=YJ;h}^xQm~M{iluWwNSOy7YDn+j zSLK-wDQKt>WK9(xpavS%7}ye_ji9n!F{c6_+T2K1&$+CY*q}R@{QTmYKUAQz4Ji`R znpbrPbayD51H%!|vxz*FvB41YHzj|wcwC@+>9WzM>Hm%b$J|+ae9(wbhSg60J9jwY zulOxyAVGJs=cAfBNXVXb2Ryu;`tr}`u45;0r4cHDc^Y|S7Ab% zzObtW;t;7Gu<%blEl5G@0pDnH0O=?vE63?=)X;t{Xz9f~qnZeHyZby(TyOpXy5Yua z+KG8HBLcLCQv`OQ^0@4OCj*9V;G*yws0gSvy;BxycaNR4L zD6%q-;knoUbQc|! zfO3ZV2c)#^znyomW&*RIbdTphs+p|@Xyo%AE-Bkf$XXPxHx*~`P`Akk6^8QA=$fy> z6Ck~q$g%i*0U3&A^H`8dQTr>P%}jWbK8b`Vc~V2>W^kL3v63Kk>STI*OoTuU9a)sU zySs+PA9OjG5w-mSIW??ijK>}+F9k#5;~AjShpXo!h9ET(T01cC-+6L=YvuEQ0JGWP z?zb{PJDM=j%{K70891QU?;5H@rUcP>`!{dkgg9w!; zmU5NyR%e3Z4sVit4|U@HyI{Y_9svY7kO<5SEpbA%%Y+xo@SsZLb+$Y|p*d`MID3gf zz%UCl!ye)xsTL(8(aggDq}m3xRbntX;`zm=1>MTMcx83fRFH^E_-2Z6)s&)HerkVkUyqzXd?FU3psP?> z9lG}3gz&URms}w=5wOeC0;7IV+2z9NhPP3EcwC}EVX-ovMhl_#o_YwQhF>C!qK1ciRE@b&zI;rg zK^ddY8;uqk?Y;H|8d882o48tRxAt12<%9NKIdUpba3YI@hKK4kl8aIPNL=FggX;&% zGH1S;sj*a%wSYt{3dWqjCUuR!OBn|$UGH32aFRZF5F|&N{)_ZSIVuh#% ze{Vs=iBW#wkesJSlTb)vg{%fYWpBr9)fA;!KKV!^vwvcRq{jX8n2VEfK4W}h$5yQk zf0;90&6HuoDjyP~eq!0BOeG_-QGRJ`q7Si$1#OwLOU)E(#3&>e#PWDqJvCcA>2Uo4}Kyejq&gf=kJ5+`&FPB`}871$OF|{Os#;16Wy`l1x>; zy=N5BoWI~Xt};1?224r%ynY9e0cG;wC+XS<#li`ADog%$zWKR)Qr?x3)pee@P_;@< z#-F|h)QxpK8)aL|1m26>m#~uJ%O>J{Yxut5-a0U1`kvo|Vf_};{SlRNFJwu9EA+X( zy09fSghc_c>nkuujH2H@4&1ZBv@OBdAkwwvn`08ftd7Doz$Gl@S;511wZ7}p@S7r= z@&&H_^C102i!s&Be+?0bw?RC;z@kF|L_Pu{a2b)}fJh@6AR?o~2!rJ3+Ur*iWAOHg zvkT_bj<^c1OFwo96JTEe>|f@6PTc^TvI>u4E9z0(7%=`iVe?o$VVLR<0)M%Vx$L4{ z5%&wIyJ(i~&jo$roi7}(I^%5F3&)x^Orb=o2A*;OMfTL7Qn|)D=LoSNTG6FBGKFJp z*At40Dh`vMz!|Cslt6A@?TbkXFoG2vy0L{Rrbof=DqclSjfb$(7@c!Sp{%~?-PSk= zOE0p6g_aAk8}6^Ck1+*wth8{PUXPRs*bI^v$;NT&{D&3awJ&YMv-B;Ce!YW%b$%=f}uj z0m3-nt_(0b$XJ0Wo_7=`!xI?rh;l!CL*RZ%*UM3p$L!L-x$D@H`5yY+4z;4sT>s~} z##>>$&Nq0)!2LrX-(|ngy<5#7e(Kp9W#wSJu|OR8aUyu!{r&%b2%^0ElmkB=YqUwX z*Hg&TBfdeJTCGfS6IB@r>JhLp&3zo^XhXwCI|+@7JTI5A!2w94=*aW0zG`2Y-mJRA za1Re)(e|U|o|2Z(MxD>@J-%UjbFMkTn4Dg%MYmm<)o6{4)hkZvi`dLdQ`Q9~%Do!N z&_Oq7!zlqd8gHRL&oIDeWEeg=8qEh3V)6upc+{kSa$nvZ^M1n`zdy=TqQWI3oGxa~ z5#4BpnucUa2CuOGI-iXY72Y|L?CzB?B2jsU8=41FG(B7<94J8q@s78XsDguT#)9*g zOAnq0dh}bCe3A3d7hcH>a7^*LTq}_r8+Rv@a#m}GI^3OCF%`ILFq4eGx822Udjf-1 zij875XWk2bp;P~ycqa>GaWdQ@*P~(+$*nwcr4=i0A4tWGK5`kXy+U`m5jtZ4hJ*t}7ha7RdRX`_nefZyOobQ6hVr;<-qToI?4 z!rAgo16__SJ>pqa#ab*;rxu^ZCRqWwh@_*=n9)*kw^+4!R;68%sGNhBw?AgqakboG zd-lisQm)I{N)&_gRh+TuJ@sJO;?>99ynJ3Ews-BXb(bxenHb zy%T&m42ENhVtS&Q|5O1Q6CYq*!H%wofDrml7+8{){_cuIcolMj!ZEx8>~MrNK6t~s zWKM`(Ury??gojrun50YYIG^Ds39dRg9p#@q)?c-J&2`d=9HZ}bY*+i5@rFLZ=xxVS z%hLs#|A^lNZmU{zI2>6CH$79JNNDq8wzDK%6JpuXae+pzljE4a2~2>9^-8(c6U&+C zsbXO`$$$WE&Qxmc#k>u8ctEVg+raf4?)7ZF7;~ANnPRL`5gu?8n)2(eNG~qa=pwRj z=*WIc0SqoS!MM$7ph5USov(gR`AA3FiDc3N>&uM3H-G(BR^KL%oE2JMD5@&Yq_c3n@sep+IpBhvgNXo zK6c28f!peuRc(*RdrOeFtVHP-y7+=TNnM9DBY{7!T@&r$HCV% z)r`8@3F|9SzxjsWzKi@P1n2IuLgyZ=QfuJv!Z}}2qrocZyPmh0 z;FB%VR{NkWOgy>Eb^Y6j#t(mC-jCj`Ok1$62AIJAJifZ@nCqq*eJRoWIQzO?+%Aq@ z%Z;gK)h&M1=!0NEijbZuCn07u{c1mhEmH1AHSg9GTdC2n7m;X=wYXm|qcoKA z0YbSF`T1wS=idj^$IsZdo4x73g=$_5h1p+TvSGBmQsa(-@fnbhO^ElM6XE-{#W@b% zs&hCoViqGle18fqw6%SIE7YqAFVW?x zy!dHdPap&}*zbm_?pN29lz#^sLK{K)D8gQ0A|VDK0dK=87M!vpv*5fvXA$rTHIa7F z`5!=)salO!?M;-AB0SF$j|Wn&3q6~1id7VrC-vZ*lA+Z6qFBpQw6@`QwdNGdF3C={ z<#z+9$pNA73(n_&ejM&4vMs*{z*`t@kM0F@xN3f7J@$%O+VXpiP{zn#z0&y_1mmCc zP%Ys3u!fBCe$>`GbmkEz+DNB&j8=9O`xM2ZBR-v)OQehX)>ZMhy2=H-U_f^!Tyks* z`T8r2Oha?#;yYNfZg9U#Lkxr!@i1Y=17)>n#&^a;ST-r_17T33x<`FvdH;~z5Cja% zt|=i#wUpKzLZD-3slw48Ar6zqi5}yiESHr@a+?(LgmuBlhv@{h3a)oYLr)h*EVEWa zSFL>wCv8(c_vNYiH zXxw3DCD%?;M}0Tl;M+_&=~4@y^G4j?15W|?eNCkFDxbXJXc>gij@AwhzT5rJ6!)p0 z?9qWe``0sAEd?d)kDv%5Im@cxu859?tB1mAY}J%oU_4JF@EdGO)K5zUD}Pn>p8?u5 zd>K0U&Uw^LxgRrxk`U9uC`da(4HGq4oTT0F;ITg8JYu=;e*YOzevpp!<`L^7`gM{F z7_n1gDgbF-m=z!l#KyiNq<^gBT*G(^+#(+On;LuZOT{sBCiUpSr*On*e`nvO`ovlJ zbk7Xsl9R;0jEirI!(j~1zcCj6TVI%CEe%ADN+f7;IIgw%y5Wzltl@G>@*&8G0NV>` zC8?o(1DEpeAUwIr!pNuabzI7s5o+8UBc&3dmPWLf+Rfogmd~(fXtotj0<^j|@ay1p z+nLgY;XGZ>Y}^LId#q_}0i8+LykcJ`kFZ{i%k(e%_AUCHm3ZEkDfh&*!O2xQC*rCi z=N|Dg8kf_PGdvn^TVZBj+N8)OUb>Jn%Zr|Ai!*E2jv^q0{iEPNs*;zF`<;2(X#v52s4I~2*vm^1W?ACvCPq=d| zFhniH!L(_$7G6Xxx^S!d^%ibKEwwTydKRPL56-*lyiIc{-IT`znEx0>lm80+8xPlh z)0Oc@AaX2CsFB^&!huvem0iTr0&zjPS7Vl%n&0rB`p!|gaj8{cI=S_E$@%vM7)8}* zZ+T}KyK~{Yog~-95uT=<>PcXrRVY6%4v#R zT9j)Y-AduWI-Mq_tSCN)2=$xfD_3}r9Vk{@QRTuKrw;-99ogz%Bf`d|M+sb~tkYl? z#4Pg*y|MA(8u41}7`vMDIA87*!r1lRg-_67AR$}k%I$*J@mXf+M$Pd`s8KlvN&_r4 zwYMD5r&BScRcUOK;9er=tt0!mRNnFUiqt9F;p^#+5dDxZnh_;6a{`Ty&52G)F+ z(`2)HO6Kq-jV0Dr=o}w|qw;&tDGv7~%m${!?i%+SKZi!;!<$$gSCP(Ev#rd8u2tV}w7rb@ap<~`XId`_lbeIMJ-lRAaR^wK!GR^%Ap zS%TvfeKB7czeqohvBHTKwU65%r|1}M={i&VAWI=^=YS;*%?atxFt~*w zMH!Y*sr56mZ)olNAVfwm@uD8WebORXjI{wvdh{LqKA%4bxvun~gjdc51^bKPy+R@V zETv#ph?M7emRiWE-|_YI=R62uX8>mZp+edN-=ZPt%+}5S`|FpqWr1Ifh#M=EE`^M<>44{ViJUcS|HgGfX7e1SlWZ1$;J-Dhgpnx_CRVCnr~Je*EZq8`yP3K;E%u4q zx_(wFe)z3+jf5%jiC;V1-}|z&fI|tkA-V^f!KpnW6+Y?*+b9yBbByA&v$#7)@~59O zjzYI&aS!{0RpEV~+u@VX9qr}mEswF@zPyCTZS(x#&kN^x30!?-GzM;n&(XM4DFPkK zJKzuz%{6CJ`#{KX77iF!41QrR{;i0cUYnP!)&N z-!&W&OT6eM9>*DBmD7M11r?N3h9~au(MyJH*82S0iElC`E>1hmnza2wANx{# zms3B8nkXbIM^Oo|>bemrJ;I`xJGRL6aB?*FBXV}dzlnt!RH@#Rof?Pw9F6S&^4_fd?O z%u{292;n4O4sBC2!xOJu?9`wjk3!JV+tvy*;Qn2T;!8sY7s~1!QXYjI`IiqvL+JYA6NQIXRv&Qh%ujU zkV)Bu5NemmsU=`#{uz6OVomhdtaL&MrAie6d?N^PpL%o2M&@W{zTc$!fY$34`c_G_ zxsTjP@HYl{s`uH4jm!jT20W1<^ph;dbpO?7!Aes=EoQ7z0`n90By7s{g`{9Xh*8Ri z!8$A8jYpWd8mye-{mwAs3C{AZTv~=O>!?IN%scwMQCMUjVdF>+j$@el6q{2oD(9r@z%D}4>p(Oc?yO`y7O7|s;+)k&%^am)cGF=P=>onQA^VUVq^qG*4&@Onp@?P`D&QH}euT%@-I zt?}3L3vv3p)x45=BSqF#^u5kDO+!(N9Fwp&u;5_32D*wr-UqOiRQ8-ax^KdTD~Wqc z2bTsTr`H#=V&qGUu<&*RjfjG1_xZ7^Fzi1Q*oAwh=f9cHNdu_*uh`u; zwTHheRdijkv$7Y?dKG=(P%BL&%;T@;L-1RktXz251QEdwx;oC1_lkXwPqBP8YMB~?@@|`lZC;m!UVB;ye**6`2_5_x^Vtju1T}1>gBBJJ^44i8z zvP1BKLX&hb4DfX@`?hqPnD60_Uwqx9$u?x_*?Ei{jqv;h9E(R?Z{yhF4X6`gEz8N7 z(|Py0u})lI#14}_@$fYgHnhDUrWzkqYcprRMbK2OdL@|t-Z$`b;Cc-rx5UExakQR7 zu`i?{OAFx6#`%MK9qOv3qsbPmeD9tIZv>o*PlR^u_9}|Uq~&vuA_~%`n^VKf)xxj20UGujof=$Q0B*fJF! zqBUqYew1x~5IgD&GFp}Ir#_o8J`U%*p%(APESU}834UVw`TAgqc)Zu=$0Pk~D|Iu+ z2i{0=7UdNAY_Xj908;JjB;tCbx*g(<+F?9JxyKR<{72CGnHLiqN6NkqAf^Y)$g6b*T1U@utK81(U zd2rK>J9zZu5!BW{H(K8#q8?6|piev7OgQ_mXxkX~XYdyFoMQax;Bx+H^$JvD>=umm zXA*Q}!Y(L*-0!*9RX~`L4R5M-c=LLSGinBtWc|v7GS3p+d+17rkFxjnp3N{v1|;ec zEc|JLjPGQgX8kQc(p*R8fVC0q_=Nx4p9hbs7ywaBSIkY=%h|>TYEqTUrO8)rF`)eH zqZ)*7!*Fxx7X4L$QScd~g4e^QGwegD8Y2~OWtt|71n1twO?+I=eI7oW$38T)3ysu> z@)C*Sa%irP!wAG;Px-+u_3ALc_=5&m6g`^bbl!P{f@-wEQOvu4x4@R8!2M|jns_t(w)M2eR2yK z>g*oQEr+Rb*SKtAhdHPNC5Y_%PW+W3I7u8?2gMt>=FDt0gU;y8hn~$EIHNeuY7D}v z!nsFlQf>VWGS$kKU<&HMjN$t815}6qmn|HiUVzM_%ywdq`R)yeR5k+9~HW znV3LW)i@roO{I#H9d9+jFzDIIfmpx1JlQnBj`-r0Fyd?03u}0c&RL)dM*oR;bTV}) zVwVgKE)Oy9mC!Zb26l4G&biMLd;0-jvdAMxN-`LVR+Yh+>f5pF? z^2O}iiV~+y;61mP&HS5?iVy`85J%lZ!>mI^X&1Z{!z!B)!xxu<&ps&$*6%{o?-mCW zQe38mhAcplUm@1R)2&_z!fVL^O{|9}TnStEREsCq;t(x6?(fhL~(CMFkU zJfQF$V+U323yb~0p7X2YBWQ$gbw~qLG?VI+Nh=GhH7N zluh6<2MHqu9n-&Uz+iN)0!<8bm!7p9$N>XPLBg;>&$DG?n$S2i5yTrSI?K_ab7!kN zRX{@HV0?=iGOaG@DV+Pwn+^Xf&Ig?PTL)KrAR@p5d{BkT^8*Zk!;4&KKS|3i425%r zvJ9gM2n(1@6t|KN0j}myQ8I*}4z)aM>aqz~d~s|fYy=y&gdQ|f8_G)@ipzd&2}@H@ z#TUv;C5k$yO#Y{8ab#^2A&g}XP1fE{t!zdu6d@86QbX2LCJitSdbSK~wly{>2M(k2 zJKzI+HaZ3$9|EoOsUhlQibS#vY>=H(A>v$$l|u|@g1I|h0=~U^PA!m82W17#S$0fO z%ethy8(+K;N!&O30ohuCi?>T0%)M?er^R|E>WDEfPq6Z}r#sk<)XsQuQe zeV2SWeDPgmaq?l}K=n$-#9Evd!lvSj+G$THAOy(bCnfVVgpAJa=-Kix*=y!aJpaws zcm5Mt=2%g{VmAZUw@1}oiOg0tWEm5At^B)`R-gr{(ty)~fwNeAt5{ZDtpcpZkpNn~ z9|9(kk(9pr973bnBYyVigt^C|>UZMeOhG=_K^-`{@TKP<1RazoL@%QbRsxM3bb6rB zniS5lh_G6TtTX^1_Uki38_M#~>OEsAuK41Q20$mPNLOkrMt*h1G6+Ezxy~e{{qupe&}{@?}5=S^95Ugtn0a%8o!5D^vebRt_#SjSke5})AD1_s_HIr zr8@=-bGg33$~|YN4Snp@NBuV{okRQ^->}BnyXCua-(CP0aTz}_ra62y!-vM;v=-(f?BGWB-Fj(XA zJH_sWnxA&h!MrnV)2&%$ulcdKPA&!TlyONz<^`U8@ji|0s%J!}UbJi9 zVmbaLD@L^toMzsIEd0aS%IVYX@#iKKW~_Ra?vV8qJ*Hw#XVUs(ff8!BRFw_j+u>9e zLk)GP>Yqn4HTcn2zhCuNI&)F-2k`brVlBMS;SXs1O33m%q|bVcS|ETIv{tR1JV7Ex zLODI^?utX&J<@f=MOXp+dKQQMiBL^0D{=|lJsVb{P_{cH0dxFX(H*bOeJru0I;#s| z0e{6q>Qc81EPe%&nJu4f9MEBGX;U@ObuLZE*0+#KcD1t(w|f9+g5yK402?zG@#@P*ZTF43?A$m`cik-%@QYFtX=eWZT(td;8ID{dJ2-BqS$%D0)@u^_R zHVFz?s>UY%P7r>7lNo??kuj4)>g3sbsF_Q>;gL zPA0;>7+907b$UtB=D3%;v${BoLWuSk??Vj!SEJTP7e8u~C&P^1S6X0R)GY{porA}o zH<0GWF5h!NUbg03zGJ%?ogW*jL<9XY$S%S-ZqiNFLA2=i&*7+e>Z2@Hck_-a=CD%m z>YQO{TfKs}pNZEvdht2DbL?vzD~Y&Uh2gK+k$PP=W-!%; zzMSw7T1?R?bWuHw94MUBI}!;aDv8`gGv&^n^svs_T5m47Qu~1`7weziJ!!3zQ+V7a z*!?P(-nAi^_&UoV;by|}vStbw174&YxcbS=FS;puw1lWE+~sR6SDabg&aamJxv}J7 z7j{y@)wi{a*_>NgaNr+`D!;zWuAe(qQ2!*g>b)nJqz#0YO6{0@qUwzGR|RQY`ChBI z9DzK>)G1+5^$RIKvb(R^p!yXXgg^iXUS~O--Urq)4}U@9ns+NFv-y78GBIoTR#DQ= z{`AqK!QQ$we<(!v>G?SOw!i{!q3DdbOBkU~&XZ&vgD_*LGpQ}l_GnffY?Y6tpE*?6 z|00X1Z+S$U%UOx_r#B!^dM8dP-u)B_Uv1y%x>y%JiKJ`OX0Gshv-nLi9!ngjZc9|*m&N2Az|mLnUmgKZ#Svp`=r`lilfIm@GrFTP)WuQ-X*X5 zAMeFPJ9~HiH=8K*EiauMrW8I$ZZ#Gv& zo*LgLO%<&6G~F}|{p;hx-2VnM6K_Sp8Ph&O*?VQ=*hakINyed9`Cj;s)HPNphGtKE zs`k(-cI?LeEm#7z##P3wX;s}_Ip(na_1lU8b(Ulr&t1vjgN59souO5k*bNW9=Wp+7 zT-5yGJq zQZo>uQB8s8aqkJApDY3_gV=x9pDoyT`8s#Q_Ym&ebFZHHzktOH1Nm-V7!-bL#Cbg< zfBAeWJpRko`a$Ca31@KRX2sHlGNYDf{!zx%Euxz)wpam)x=G~3JNB*p_mQP$@LZSe+$4j%pE)|7Ds=OyY5UhSqcAONlSd#&0aP0;*S0?YfTBW4e(3w*3}ZH zb}~WRPuti`_bt_;s}p^&RfE)u?|J{1gMD!VwNXmk$bL$8uI1b$ z2+In1+)lC{beY`_D7HC+_QqxM?(EiNOe@mH?iL8)1YCVQ+k4T-$#4$guMQhD{tkIwP%**da`xK;T&4!jSOA`|S z;=-5uL4nBDieIfyv6LC5h4$Z@^wKfWt}YhogGnYXyDN*16iQe6P)8-gmmyv)1p2JK0R3d|^BO(jyO%zb&)ndLmJuoTZNCESit=0c z)V=#KAtK6$Ak03gScDYC+rOsB-KE_g%5^f-2=x&(T6lXqfT)SLh5(zsM70d{;T_Xg zsvk5H&f;d^nK&B)W#El$=J(63j8RMzm*Vj;1>?Uea{uPywdstdu|nl$dj&jd_2dBE zOYMANDhNpaPLpxl8hCyDyd)KG73}ntffsaLGt8dX>L~(Zde)rhHPB?v6=;W6qiQV*j<{^0HKB_ugzN9PCWV%OKz4qGZ& zSOo$zZ%=-KY0w*iI^%OJSDK!Gp_=t_&exdD4rKS+r- z)bG~#enUVf6rzDY9JA%nbvztLqV*sNTItG6g81HfXb>0vLRn8e@NARS@(<(gH?yr1 z0R0{HEVfof=HG10W9%h%2>^P2p8wa;RYpbCMNtH#1!?IPq>&J5hL)C+Mnt+(y1PLo z2N0AVx=U&Vgkc7TZun@1kQf@ifq!@1x$o?I_SxsoduzS5pKb8>g+Renr|h8&Qh2K@ zbYXo;lVcObC?~_HXZrqCEXt+IzryE4YqGJpbUHXJgIKT-5Idz;i&nP>*cEy z8uxKgRCY%N+B4qQVk_V!oTq;`Tqz!;XQ42YmhSD{8{bLn*WX3M7{{u$m{{nR<7gh; zF+=m?=t$(*qx5Vk?!CVPfyXHP+8hdV5(N@lFT*}aO%@+GnlF7 zQGI>783OeDh)L9pOr>Ba0w$g|i}ar0dN%dqccnAagFxm~ z``Kxx8lf4;m+Le3$9~KGL&wwSsQ{)=)EXuuWqDwHa_%OpB9IOfWtukI<6#u{sN=oa z-fE;53HK{iZYO@|&Y2Oa*>}@R23*SLX9f5-MP~f$$CMu<(r>usS(=x0XU-R-3{Qza zN`8G*u%7Yw>2GFI^V1YNivr>7>C=r#{_iMV~=0%fjb@M|@sC(ck zYqV4WbwO%1)o}9>Cm3QN4i6P>GAO=&Toy@fbsi-+CDPJSMs5WiYJfbMybRUB9ehht zZ;&gHPq&^BmdjaUhiBVnfeaN+(WK3yyS8)=-y3e1lX6j;M>V`G*f)C6D}|}SIK7p) z3o)o%_3b(2;SjkgxTD%f3{rZqBme`~YEWJ8Wi@Ds?Oy$|{lsh}5yobVzFxd2q=D)V zE75b$uthqgrE_F(6SV75PJpGnZz_4{Qq~v&QkMX zn=K;x3lY7SyuDy*?$BeX1rfILiqd2zcRZHflarrhyKA5fq>O7Qa>FiK& z7O7PyM?*V$oauzkCVncLbqHiM5B_`Lh{{lY35s?}z3`Y!ZYxucgN;&qCJj?xk0TUS zrSf)ooF0v>IeUBNyoEDJyXUc*Ee%JM+_8|k|2th~0|#^RwIWi|C_ z8$NGCxF>UER?u;D_>>S3*WoVD&m&P-ow7H3RG8kmsW>aCW;4U+-$|ui8_Cqo-Obv2 zhivBv;pL76$+7HW@sAK9I1#j_ct`fb$?V8vILNM;z4EedbW?juND|j!srt=;l{!4W zX0vEI{@MtB`m)mZcK^jMVF*ElunRP=u(miWRTIvqpi^w1Kt1v)FcZL{pSOdP5N{I`VBP*8?g0T*9X(adc%p3F`i#jEA6iLX4pt&d^z)eh@Gwc z5+hSc5&O-FsoomH5J~5>>0*q!6(JyxW9ul_*ELomVb$+xBzK}om0j5II(@P5&JfEj zQle~2$sOgigh(LUYun*}Nkm8Ulw34wKyFyxcfOJ%NlAVP&{t(oeT3nw_^ya;#HoQ7 z8lxn_uU$J{%A?x8COB3HpCat*TGcUZ)cr$Ns$BN^J>HQgcVo>(IH01Nei%cFzFExC zdUGMWfazA60hu1KJ>J78vXE!kfJ9Y^L!jNHVk_kl=%0D8NL_yw6CPSm^x#@W)*%Q+? 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 bpUvdU1E#~Pzl`yiv-g&@bjG3vY-s-jSX!9v diff --git a/core/src/main/resources/bedrock/block_palette.1_20_50.nbt b/core/src/main/resources/bedrock/block_palette.1_20_50.nbt deleted file mode 100644 index 0eecda74f72dcf026d3f665c050d04a1f8485bb8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 170466 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 JkFhIPadz0t*h z|Jmi^JGA((N*e@k;JRB*=KKWUD>epcW53M@qbMw~5&h3vg?2Xf%^N1T;Y-j9hiFuI z8;CBUE<}Ji)>6>r_&*Gn+YyCYl?B4suf^5kRoM!>^Vk>k>Ho)0|FoR$S_xt4#Z1j> zjQck4`U1r#XKxFx$E&xGVCL6L7@0J9-fT4p3c>rz3O43?iWMwYfzm5_i3tlbQa3w> z1PoZ>+(f1ROEm(bE91vAVtDHIeoZ#i?ZekD(I$2L56n&x%OtR%YpMQ#hLYj2B68vd z0tY?>M50{qANb7Cftnrs)VO#UozsxH1RQ9-Gg=|#^!@1YM6?AO(21RWm!3WZaIIagt7Qblip*Q4S@ zbP7#tfArn_Gt5wwO;x@ZGW!4TjC|30w>l~?{rgNM~vOh+%rlQ9Ak2?|Ttu^~^1-a1b&hn23;wezF%1-fF7_ z^i${=}p{ynyr%Wlk089mwWUVxW6^A3#8Ad;^=HG0Pw@|0v{M5Kmc|S0ww#`= zw9{`S-rvp-<$R_J8j!CgP7`)&MtDw3Jpi z_q_Hr)8X!%)d`i$i7%34B{`g;=+mb_EPa=BeVEZSx&Fr~`K!nVI=I2I!e?5a3H$s* zS&GhdX-rS?HXGUXFr(#Z!&U25>5wOz0Bu?Hbq5)rTVRUYZw1#!EPr+Sa?B*mjcA-U zf~@R_&(J^0p=bKfFhhyUCEoLnqK&_MiQv&w#Z(d21S~32+ zTU+wU4+U4#1GMPp^3YhNSj(&Og)c_ZV~o^7b`pHGN?-o_Qmg#)-#bMgwQ*ml%(jEi zbWN87 zz3u)GTd%M@A^i3gM$5J(XB)KM-jeimeBIWCObt93FV2JN(xwnc(Y-irdyOu z=pwW4nK`fcv=APIJ56Kq#nBdLKxNk7!IU(mkHI(p--U*mgYP;`Me{nM?-dB*aGIluUJGw`)|=JvlpP8z|E z4JjVD?Z3ch=6`ry4dp|9e}1q_Cnv;=y*rwDZT*|i-B7*|+5)|FHLM|}yeV=L3sy>R zugLpXzNmCm0?3^QxC#{rj4+^CeQsGNYmJ9zr}7At@S8UnP$#5W>I@T$z1!cCRZ8!z z$m^!NU(Vz8G?jN}owvPvSEQ}z;~dSItE*SLV2a2=LU}-;Tg3dQ`J&rn0-__-kP27W z(U#F@K5D3;G=Cz$?=FlWAKdRzEE3E+vE*(fU;*aji>`*t1J}j@9hi4X)_(C%g=%izC8Pz)k`llzq-cH+dX+0M)72YNeK9xxEu>_I$VuB&H#pE| z=@Z9D(rYWTyVXM+a`|kGCETIL`m63t zd~D*ZXKm`WRL{rVLWc2MnlK$Wqn2YSJPMNz!zFa0hmNPkHhm6`qg8fC^);0Ch2CpA zXv5-a@gArKmmaLXY3(Mn)Ufx1#qXMWum1*&s?5g&D0P-Ck>n>&83AOyptZ7b1q#L* zO6w~50VHr#l6o^k6;dwVz2uA9r4igLQ>F{)^*=0WT?jZn#wq^%w3MU2cg$B+v8x8f5OcbIOw?O*RS7Z5-89o7nWQ~tG1KEs+uI~RoLtvkE7&%TCjh?CVjg7Mar`9eyM z(9Bb3+-zUxPh6yw7nwG=L#0O=Sgrr;!0lPVa4&E8E+T5G;w3JX+wVldyg(WIAD=#+ zQ6KQ?h&xL_kP~2iZ6A;Bg?xMtA{#1XS+xZ>^%TbTBR7W@%t*Pj)HLw$j;b6rt9;mzexd2Nw#^i zfui*VOxZ%6P5ts<)N8#~b;tIS*fYOp~^egnsrGWP2<;8psN`Nq<&fUfYM57B~G5k+=!(wPwlL|y;?v8BKP zJ@Q~0J#c9H_jr{EZvSnpTz^oI5%{Pia}}~a;MoFa7bCsL5m3(sp@02{_j=x6-Sy*p zc_8=6dY7`oj8RH)cHKQ7*_M9(?059*3j$9Y?9t{(Z!5LR=-s!mZ2TyFWbZDhL8O{P zh$|sCbxQ?<$x`cBT)KjIov^`%(5CiKvea}4gaB(J_pDb*AIr|`mi@o49wo;aj``PA z)$(d|s0THa;4chs40_TW2=Ly>m?c)5ZG26s8PF^n1MXhmfX3v9 z_sDE!s}-p#r;8Jo{|oO%6*q<&pX?11YNHV~>z(u|PtSg;sKnp4RQbVK$6|fxRdpaR zenFzh;S!l2%$Kv1YHhs`o6s_TA^++62(zwo_l}mx(_`+QZ0sUkn&bM~CJPLIwwj(F z2OHG2%$B6?-kC+}j(LrRs7RwLz0%F=l0+TpVlUMH^nzXS$=Z`^biG1pm_LGc`BpOi z7b(s3sa@`hUgu|Kfg918{bMZ228C+XoR=-H;*gq-p&KV9ZMgTzEx%}`q0kb8N2-*w zjxWkHmC5qWJ8Q$C$1LgWq_!;l`=&Helf*kkW)2!;66YXxlrty2Auq{d6KjoS3F9u> zkCc(SDgr%&{00?*44JjlTx5JDNeEh)KOb6h7-Jszv9fY<-o~$J-oz}TgdwD2{(SPu zF8ao`rJ;6SFXX1+svo7c<#SSM7NX#LDQ8GetN(46FMG)N`V$%bL*JhyteFx9-mWil z(1JFRkOkbT#wX!Bp)0YUee-BW^m)Es%Xm@&V_v@x>s$3J5){2c9Oe59GIK1OBz zdc2=1Qot9z@T*$!_8iUrxZC^a(wxi2c$B!nzNu!v#Rz^c#aH5C}mYVe{9evB^Tqbrfrtm6A6Yos?SPN z_o(DB<}9f6E;BQl;?@+@u#IHeu5B*sI6_xl8*6$0nj=L-;VI?_Wzd)PNTtb1U^)R3 zM^!YIepp#{m=qgPQHPnPA`d;d4WGV_bt<|$c{7FP5E#82N?Y{o*X%yuI-$OcD?-dO z%1tpw&ABXKR%5YcA3>ysj2`*|y30M^G|H(Y4+ZXy+(*s2`=WqxoDm{LSV&@>odQuH ziz3f3AKAV}+VcGyr5i#Pk?UL+dc4&Bn`?bWw7MP$4D3AL*qlIO3rJ5!^LfHia&jqs zKQgbtrG(qDsiGGdIF2a%%Dft+`+|vYRa_0hIB5{_7D%hh?NM`3E9+FGzEhsF3 zvsZKVH@&Vzu(3CH~%mU(Bsd9GVVd6U#=X@gDuG?b`0b zF51(tp^8Zx!8HIji2e>F4ezVVZm8uwlz-f%2o6&uXQ)Crz@eZ1k%;&~ci4b!h>F@j2vo?M%L`A$K23p&~;^S|@(gTY@sWke`7M zmaWL2C-y#;LMC<)*FDCOd>)(g7V|61e6hiq7EjRv?nEW!k93Vm9lg%Q6mppsS1M^| z@mgz|V%`VP>C_C1Ga_3ChT4t`ve68Sqn%Vmo6_n-y5#Vc;;E6%my;l^Cl9HMds%_& zv8i>UB_~d#Ujmc!>ft`cm33J)!+;?4Oh-5J4@3|^^d@S4y1VIS-a?P zW^ufFoh>czkVjnO<6c{?UGN9*yeZc4F4Y5@q!PWa*!a-c%5<`;v1jp>}YM(uQ0|Bpxw)ewkXe>-eWtMv~TpmxU&iG*SsthPhp-rUJMWDCTed_LM9 z0*n2oawMy^Hx(ZHN=s(zG`5`#k7pT1*@MT!E_1ca_PU~GvK>n2W%5_w+>5{Y_n)nS zI3Kic%3po(EUS%f;S~XC$}8jhj&{q!%aiq>?lP|ZIevJn+;_v+0|pUa-Db}#=frWq zJ#-Y++wU;DT&WJq2R6~U0klAEJ-<{;4`sk}ZnuO*Q=b^!hUeSy=dB~t-LBQu4A&4t zZ4@xI(l;t%iAy$amAN-_*lNSSq_dcAB=3H>TG5}TKw~7|xL8`DKM+2EraaHh^Z4A_ zDCSy-_3Xj|ErQ?L<27;JZ0^inEm~^l!sO7*sK{!+gyYV~3HGYW((t78>JC39+ag!_ z$)CF3OX-W^3U{*)->x_!t&Ks(J4RIYn>g+f-Zc@{Ms^n)E8$B<+lV;c(4pCZU#{1E zuSR)l(3pHc?QWJ=szd#qt}a7M>h+c>Rj29RPgQpq^1z(~b2P`>p%d(mEqr`^<&`!z z_p=^u8c;WReAW{U#R~fEEe)q|@5+qdpWC!{d^~@kwPh^7zs8upCWRaetr$xp6FiaV zv>XbQ9O2tk#i+hf-0fYETb@DE_nzcyU_<&x9>#lBo{ZC-57-dm zbXxCp5q>Fl&4-+&C)ao!2=V%j6wwgK7K_RCzGTw`^!5{J&qns zalqV=DTy1tAt1Lrng`-tnv#sEIn?w|JPG>6*VUB7(nygH`AjLTbt_1ae)xeFTyf6Y zyj_yrto5==aQA?i;2E21kTbXnod0Jzj9gmlx_ZWyfD)D+yQJlLP1jmXY8KDG!=$e% zwnrym~cGCwU?mZ~NGgw?S(({bgW_V_cPw(Hwx6R-kZVWzX6%xKmEb9%Mg5IK0gDVybc zr3L!0A}^!^$6{6H z)kr!eBqC7Ttjz@I%(&^r!o`n~2aWM;&#EZ{0x&*nUnfN$pvr|Cqye>Wz7>!ut(POW zc->yp*Mjjb9;9*iTV1wkpP4{k88Y?wu=2Eb0;#9xMaDbQ~KvF?%O_b zY(iE!=>fBdw4V7^hr~9#KG%`95(g||KzN`7wP_sVb2KI)XH|Fo!eD$}t=sF@$UlF; zd<17~l{g$%od*C`wkYxl>%Arv0K`jScwB3OLPaMMTL*>-t$=(x5P805RMu|g&~c$Whql89CpYUhJL(5Z{uordyz5|Bw!KU=rtGR zwqXaFur$rBMbE&uI+7LNZka$_u0;8gd-`#Tk&Kpe`IsU;4cXUSv$+`z9o=`Z%CteO zb2oWEHECYYjE}}0%s%8~w{fJZh^ss`uA6 zXfQUYZ#SU(5F#fh;w&@NX7B0Zm*wvT+drFMk>{=wu>sKobzM6om?&2%hk4!cxt|Hk z;}o9M0vtR!U3vIZ+PpC(fhT0n2khO81k+1gT`^I-L&$NphX=-ttirIo%oKb%3R_kN zmOkv5bY^iZh)^=5{gezf{s3mTy zP#RBH3iyoSlPpM6xC-y-^NcKT)*2n(naqprm3wFL6idzGvCx~zvHh2NZv+U( z$vF{`dSn(;RpSS2f1S9q$Qjchx$g;8B?|Zse~b)7i*p0=e!N&@@+sXE+OKsTr_dIR zl{Z?kkMmeOI<9^mT_Pbgy>W&FBlo*F=`Jqbp~u+T-O)a6R(P@b%!dEeKIY|ilWB(Q zwdCeZ7ZuC!TyW3uFO(y)R2-04&1VUuernY?^DeP)z4ACMR`S*Baw;GBUu%F?~?qVBIXVJfjFbxO(z=EZ1Q5c+`uYuT5=@yvkl; zrj>tK!RKV}KffW-PU5qg?iSK_~hhWd(4Tn*Z z(1JVosAz_v6^eO-(YH}Urj_?2u{B<9^y}zYXH|Y;E7hJuS&g2y#?W%?C3mad^Xc&_ zS84%;x;eiasQrn(_10HheddR*)~+*dr?hsxNBHOhoErJm)ta;AV7+7woKl>=uO68h z6CF6bSFjSI>>@qTh&E0ZJimGVow)t!i__`3LuIwY!&$v;6f%RgfR`8l{Re)LwZ{cU zbN6RdWSHQFAn@ZsbQ=HSVW~ii(Niz86`mHCZfOihWiQFMe>I<5=;#7{TJ3-Pr=|wC z*T$#H$N0C_f}_>yDUtRiawM#Mz>kK~J{YNg=Nfu-QCO#f(m4=TF^~VM6I>~591uhoKo5{%J{e;@07LS&U zl2rmXGjLLQz?P&33~~y(ZIA_ZgF#=&@I&S#G8NZ)%myY($!wMTBvjCVJp)ldG1nTp zg2J&$U_ZaFr~vgArpiDhvdj1qrz6JV_Xd^VG}3sN%Mo1y^Bq>BsbFJJHp-!Wg#)Q0 z`Udf7{YoH|N5S!%eSNrqQPeb-o@VJj_Cu=ANlX$d>ia$8jpNO&wVhLa@!}s>GXA=; zQi6RRPezlZ9MLyd^1iKY;mw)h_2H!p(TbcXp5;)SHs!y^cREQ@ZJb7tt7GPyqi#~S zEW7)PE=0^a1@EGzvzu9OVt zv;~1mu}t58iy0ZUiLP2?M06;wWJFfJn9&;JR=DLekJo}L0n3$>ue+)gLR_hEAyEA^ z{?bA>kjnV#kUT_D{ocu6xo;!Mp{y_lznp5VrHf&@h~kUI;5D83nvlc(4kM9GlL_Le@A)0 zNH}`25Ca2r&t^+h`3m>4nwH)&5#FaF#Kct4ov#c{%h+BQ*mCuZ*wtBJeUYBUeainf ztwASl)Obxjk2mgT!I2m)V}yr&-Q${LNtkLrRJ@ZRzL340Lr3UYNXPODwV86^M{w7l zy!?F^m9*$j<%q(fof)$v=C?^7uxItj2TG{)$$!UGFim*RF;#FrKcA5b=Yu?3@F(~6 zjJVQWk>4(iOicMEQ_Db0Xd*65VW|Etmn2SezcMnaUZRvM!Be;*rh>Iskv^;PFt)|x zQl^F_>RxAD(y;XHb7 z-aoizDM#CVYhmkTpRz*yE85xShTD>pKa4|6Vi$g1rZ@Bk7Wzm45_#)~|#`d+p>m90^m02a9(yRc|O1 zkIfHxQfug`55v^*6Wij519KN_)*!b_M(|)BM`oC$1)9fC>UN!*{&~Yx_Vj$k-4t2T$oMPs5T+we_XT|qHe-j6-iE+*CA>&DrHXQyW# zio)viyzE#08LzY!J8X7DrG#S{o0jc0>ce_>c+Km}MEN8WBI7EVq^Nfvs1GAtv~3qB zG(`c?h!W6O>{+Nuj)*e376(WR-a;$#EZ#A8! znd_y;()uKTjE2hBbz^jY&nsIdTNSCar8a{JFKBh29Ow4Y&=72v?WwK0*AYVoU95BT zbZ+VEYAD@((!jlG?=vv}c)R@Lu-N_{OV|5>I!Tj^ybU%3=~)8ArOA>w_uQPFNTsFv zYL@4)$TuT=2%Q|aOy>aO{T~W|>r0PvgD9xP?s`xi5~e!ZKM!V-F_zU3-g3$GN0x3} zCRinzEUYj3M8AFst2?5gXLtH_D5|r3m5q{>sH8)FM;Z)z7dYYk+JIG=G^(W zIf^a60Kj)!zD7(M;ui&=txdhM|*E@j&vEhis#4k&VNMyQK>Z?GkHaWzQ~@ zv)Vda3E#t;w#BZ{~cwKr$9!vGuM*1aD`MPb{)%(a=}^c&8j)uv;s z#WOI#F;a{fjT+*1d(JYoZ1=VV2XJaJC*ig(8?8D3OqirO7O}v>HB#9OL-mj?m93%= z=Mi8PfwS8Ci*Ywpa+d1%g>^k^GCiDn=rk}!HPS4y>$^(O0AgPMJLKGmAT2$MlY_^Z zQdnKm1msn|UeP8H9?P_~cST#=ew?KWS`AkLGC(dQbFtV>Ry#?mNhYq|-)1)1LS1?c z`eMR7Wb=VcSLT>bBEDfZS&SdiI{H&>4QRt#37WMQgF%6K*1}6(e*nhClDd|BFTMu^ z2vky3I69`AP5_m2Gk*Hb2@56r^VO)+Wr8%UB=y26C1BeA}o>118E4YP9%Pq*4!QvPr2NCgE+y#u0spPc5gw0gPD z&rTz(PDR@x{apuryBO07wx2|Vu75=PCnZHLMWfV*UJ;LD(PcA62@>+fp3hw$Kp%*K z&pSzM4uOw%;h%SE68N`6jfvZho+9zr34}&_@Y#Gun))((Kekcq+)jzztb~KSs7B9- z;N;rB5hJ1O3|j|?lX&ks)z4=%5-t&eQ>E}4N^;yL8%U0!RH>${o< zX0)>gl_s5lPw*63G3i)Q?CktAPkMij3QgblQTE(5#)QzlJM?l*zNQPgh^N3(94oL- zFgfEFVb?=uU{b?HYNU`IuL1(3d!Wq9G7OVgC4eQo8 z&p2jl}x#neXGUql4r1-JPhAUeC;5R$0$cEsGdKrR`_XO*Y zQ{;yP7%iX5#f8Mu+KB@Mx?*`at;PVUauh?beYR3p)8)rp1K*%YR_#w&nG`e+AJa0Y zvN)g6Xb-{mjUv%ez+)rdAS*D5#~3&!<%z&{WY<_xNR03r)SwQo=Xyf3n9E#Sn?%$D z1dV-z@+rEI_CV5L2pa1_1eu(WSWrU-#fn|9e4Ac|tq`QQZ@Uj_3avkK_v|C|cnV_f ziqygj=e&gIaIsU1hb}@gvL05jcek((q~h-UZXUejuQUj?-`(5Ul12;l-W6{~qmX>H z1}(TDPdOSTRES7r@Xyj@h-^GAo%Q)gq4UliC`Qvk+{W5KzQr?E07x7bTG(+FnOwvaep9Dg(+Oby=*zDIs+h>}{4a9SwdW|B}#M}V0ss$aj47R0`b<^R(1TCRq<=KVS&#L z`p{6q!NM889=CsDoaMXGCp$G^noj?rSICY7YWihVgXKWdM<41k_rNN4;XPltOxRWq zZT+sG&XN@M?B{i#kh9C_y?WJIv5FVb9mC-`ajmXa5rVE_7^`#3lR2Xrf+B>)3SL0vHv7jqT#Z+&S=7@A}MybvK`0!Mk!9T zg!N@}gVDP3X2~e8oY=dj`XytZ2g#gsLzQWxs!O8Ck-)IVqW&v84$(ihOTfRh=@?&4 z3%|Ey=<68o_retXsTubpC#&#sjh0}8e){kDu6P^MoMcfz4r0-YA)dPln$a3F-P?4z z6c0w@HRgaY@ZSB4#ZJwJ01kVq=mjxxzd!MI@kVjjls1k)Zm&TU#*LJJcxnPK zbf!lH#?%pCgAC&ZcE%|NHMn0>B>8`QUtqAtY+n^rN`Pv&#%yBQczxmr49r_>|S)?Z-Pk-*>*KFBsp4A zWP^VA8x~GaC%#2-0OoWYqf@lyqrUt5&84+18=?YJUz$={=UG{hNnVe%3>rUC_x(0T zY|?W|jc$4Ojrmi~@gEv1a?}VB6r^hYmW&c$j-A03jh=!HSTKr`|2^E%c&zfaMIM(8 zd8Ju1iu$;`ku*2VwHjgG%v=WfVGo$B;HZ1=K)e79ybei3f<~UXalKA@PipgH96*EI z@WLT$R@%1)A8$0XN3=!W zYo}+l%GP)=^>0CpQ_DkL?Oy!-HO$69E!>7n{n0|4>zwklzc-WgmP^xIYrt;(59W#W(%>FK4LlnY)cV}`7>=rj=|PNPyT+`8j8<4l3mQUu@tKSH zJ3krj_L{jtn;PG^URX$up9~T1vVK%(PAmb4dr%`TEGLWS`jKa@Oe`im$B+PTjf_IR zcYO8s%7RzADl&&+|E|hH#+^4x666#;sY`vwO-Oj)y?tPc%0rln>lz-{sPZF{7#%!5 zk%K>==ExzM+RGPX_x>&2jztHr1$S~)=+-84h}PvNDn(hWw6qs;BadP`Iea{?e{CC* zU~~Y338lp|xxjb=hKWHaH}l1-oBV~LRHBT<8=L%yc!hcT>YW3cyU*`; z6r)cz`H6P!znn8-b`NOIHh3S&PGj{rIO6ed5T%_IMZ{OX8Fao{H*g={*Kj_pO7#di zRLvvLs>A|~4u*d1TX#HU4X<&`o~mphw&iy%&oy^u{_wi~Irl)=*FH)d$1TFSZZXvw zUc7`g*{WEITBDq)%2}`d>!6m$tq?%sAM;6wc_^UUo>`q$nu&qAMs%QC;6=w~jabE1J7& zd3z&?^s!_nuf=hbC^F*cZYb~ZI#QCR#2|7W-hKAsW(GRX)}M$X$3myR;^v}q6Q*I5 z-XFyoubP{<5Vnj^%KRN4bJLv9jo(={|CTqssG$PuK21*J?SG!(jXH|P-gh*W!)ZbL zK&b2m3@_SIo0Q=Qh#K6AWLK0Hud}te72OZWb0$ymMn&^Zhm7d5SkeN+AGf$0EYQ( zkZ)r1r{}jZZaz_ZU25qj&=!QtQ_*E8Xn?jbv=+FaEfXrz*EwO-ENeRW_`9}qs8T+tSec~4br^u6$3t_qTEEo|*E3mJuMAR$%avom|EX7-lZ9a1Hm|*d|hiBH2xpEB7>OBB&L7 znR^8QWY9Buj}HeJ%=6w9N}0_d!T_R(nMU**0K+fJDSchZYuk(^$59i~HrMLkXXU_O zl_N)QF7ZEcpK}ub`R-a>!LV$ljsOS8QB9(pa^R^g9=rRisG%YlJWx|`q=U#2-MJLm zZqNJr>x$-EQwQB=((s@{YtNdv<4*~lV@iU4emVOZ9ix;wkSlBP(eA22Zs5j9bA3u% z;5|{ARx9@E^1h#gT=IMA0Iy=HJgx8JbKUdx9;!bcnM~g1tn63r>8=jQ$3jX;vp9BM z$I)nGldtaoCHOk0DLv(M)ldA+p}76c3w6v$l`wKcXYf?c#+V)V+$fD7b{Q#ozFFfy zT@g9nX#5yfM&u&@7od*jQk2IxcC9*al7C3V#mni-Bh7N)>4L#;6k#*^3QYtEL9?V~s zy`^jEX@SFeTSWb$KJOGpf0#|jpsQD=r@a{3WGmauVhfAE$X%AV)085i1BqN#?1l_~ z=H^jcT&a0xQfP$+^gO%stL+aj($WG)9P;VenX&r@G*1I==2y#LEy;4PK7yK>LrVbi z%|ka`otZHvp(MQPO(}+?xgEHCO*wn&Z^O4Lv`1~Y=!lD*E?<3F(h$pTgB>HV-8bLS7AwwOqGD0zT2UoOjzyS5~X{r|c{KH+Fe$Qab{ zzDstX37Sd7EyW1xb=n*rz|NWayZbMtKCf&MSS!5Y@r}+HMVL8lD`4F=49P_O9jv36 z{IehVX#X0thOOKnCuaY8rxDjzla{q9u=+b2TB8f;a;Ikh)>-1$z;f|gMM&p3dl zI=9t^()<&E-X!|O%37TDBe1$dGro*YQv$WK)7|!PKf@#3ZjFD$zw?+&xwBJq*K6gH zMiTcm2=V8kC?dP4Om*O-62dRjqvKRu@^TNHf;C3U&y~Mf@6K`ty40Ru_{=Y(hT=Kk z{(WorHSw*24Q&}^aWON)FE?+24`H zAqDnjQp-l)bR>8=$-q@Os~e2j3?M@dm4KMy{yfW4pRMNvjbUz4Gm0{js?>4=YSgNr z1%j$Ll(6_}VvV;WUO_FlJ&ule;^TJ{5WDkkIXfJ{7C}3BXnub;<%=lGC-t zSO0dOYn!ry<0e=E<+x~Vli7{d#ZIbMU6_YQ@#uGqXnrmak4{2!lqb5huR)9>x1`H5 zsGmy3@GFMY_TU}{hH?#Ylw2}rz1HBFBR7ZCc6#%Bnc=nBe-G?|*3T*Xhu0dcTiNrQ zIXHuJCfl^m65^JKqs9|z_4{ejuP} zByA2%rW2Tcu^8=^{ZL%XK)Dl>cv97Lv^rd$|^QFzG znHlgew+J~MhUeY<-1|1M<_P2kM3cD$EaGoR&G#MLb$0w@*7d_~edRaaCwG?lRx&Cky-D6d$vP8mNuK{_RZ&HUe)n2h|8EE4NujxC7Y8;y4+||F}9mkX}JA`pR zRw6?pj8DJf@XGMf+n3Z3Hm!*WepZPJ>(14MdHka54DWtj+IXFs&PEm-Q2Tn1qvm0| z$D?40x~T?&R7rY`{^hNvhYuH$R#zP?!hp7%e}a$+pwr^RmktT$YYrYsF7s(G%i_B6 zv9fj>#n2#Vve3S^z;^}dk=maZ8|xDQa3XrULgC@}?*Io=EBdz9@F!$4lSMnNKQl9m zGwiG7ioPk2s(Zb0`o=&E&W%3eq^$WPk`!M{?nHLq#l{_02HrI(-T89 zBp|K7nW+F#uL@6y`CFb4qEDYaS){8Tf5(B+BtxzeQm!%}L^5;Or>f}@NeBeJv-P`D^u*xpkLJbUx?uC zp^Y1U89MFqu$=)-8+T~?B!7U;D-yj5mV9PJVUJJ!W6eUL& z66e<9NcZ}vh=~i>RWWWSl6qRoVW?FK;N*`&!GyW9T9ir5k+pfkjSnG}t}m=uu7#1h)ep58>@0jpTwK78XVO z`(k|pVXh8*Lav+AvGi}>D+oNy=^Y7+mFWZS1>{T39i+Nf_=BHy?-u%=F%f^Uc+ z=N%){cMEu*{#Sglifhk5IApOpOe&)zZ9%+r5^h4cpf7-(m{D8)SRF*n-y#Hjq7+x( zK`usNV~MJ@JqL0zK8BB3yTQIxes$FBRWL}yok@zvkLCg<)$gE=RkMZ{7kJV`ubJs( zpoimi?Rn%Slp|orebj=?o!qUa^%$YtNuhbg*-945o#LKU{81HzI6I0ZdncI}Akj%# z5Oj;LoVx=OFR@wfHExh@@_{o-Q}LgI;s6bIi#TI4h3!2ZKRS81(s7mZz(ZM7F#XAe zdAhn3N!_XGhQ+($paG7rEA<6O*xnsFQLuOHz$emq8L}VA7V%#SWe_)uMeO;D7~<@j zitV2w$vYQHd}o~Rt-4JW7oxuCE$$~UOznXm!FvlLrtRk1^w>AAfDNR*L7e*{Gq8oI z4Cw|GRKVl$|8Ap1y88qcfYPcOmYB9^}# zv2(D<>Lk+=R-D|)C8j5SVOIxnfiZXI4KejqCDo(un@7=iPwmk#r!gsFwIklK-Yquy zMPhpAL6blHMe+fA!F8Iy#c|QIr|K~Qtg_}^QCRR{$&dvlKl&kdIRR{>U$aOMSr3u({Z9 z;!@Ev#Q+bb+7&!Kz+xiK4yzP-`7z=4K%FA`JsF7vMtz)@)`|(i`F@Cok!OWO_%gRo zmfeoYofKh_isg6z`ow9#?u}gS=?=J&`y0USg)4RaKKlZP-5bpq_cEuS7kHSrlX&nf zsd&}GC1|YlAswQBV%&y3F1td2;l;qjHyx3IEW^Cm{AIaAKG#+QdKp?5##x7&za+>g zScJ(TMRB$Vih^ebr;A%1Pyl+QoNS)kNVz+aaH(Zi`uu>hr;C^u92X#W+L%th{eL=- zD?Sw;8P~AhHa-S)9$N^i(-;qu&f6ou@}Pt;>N4YsZ#Epe2jO|#8%@5G7ZhLn!*aIF zk;OD4!~8b;{!d-QIw37`;lIp;Uk0K83s?8S=~>N5LK7hGIP%j)Jg6A~;Wl)jMm8|& zh6;GNPXce5R~V4wT)^jT1Or7LApA-^s$X&|fSX9tYfl(slRII6ntLxDWh-yka~Is| zuP!u#-{MyE3Eaw~yr3UL?EhZ6+$4AQ_)76@D%k5%WGFAJ>;x{L3V*q5P4vMbi7?EH zmE%yO4|to|MiC242%gerwf@p~Q(up+4PaJJ%aTIP%>2 zn@<7O1u7-s-y8VH=GAo`lJZF5Lu_7C8-=WUlq6(d;k&+!tan}m8%m2#mWHW95lzP8 z$5nq8i2LoW;N0&$WzXNZr#n^k&9a(?2BP3Bb~WJDOVgBwzLDIZP~PlFo-M3r3`upz=QJ4k|NV-*Qk5*liF znr-Qff=mvpWKbpPOULmOY@5Rk=1F~PAww33=7&zvLx@4^+h*RUyeW=F!5 zuXkP=0O|l1g9(47wPIzCLAjuEV}Z(hB*5dz*oNcp=M1h?z#pYJ?N%Iqh8)gzYEe%K zxXxi1BiglmlM=ST-o&J5e&rzn6$(z+ zzP)23#xn)=DEaf3PYltp&HYTi?O=NP;{s;_?~~eOm=xjy&P3_;+i-n(U^kgtq_Z<+ z#>*lL%r&-{2_yldNhD)V&$-Jq^=mZmBMCViQ=ayC0>IK0TL0x^FYL)NdELxs@htTv zBL~0^1)WrOZ+d`8e!5dn^OD{JCXh*n(bbRxSy3`7R2<+k4ua^x2EQ)bHL&j^qUK0H zr2tHEF~mL^8v>Ld&7_D_NvEuh^?O!4wn>*JblcC$D|Vz}w7; zkMxS`MEM0?ypCeAJAV%_1-4o1=HoaQYaOHMP z8pZ!hD|+aQxxUoYOLaWOxsUq%;W75V28fp2S6z(v^`Elbj7`y+pw#U)df8}IH_5q$ zsg%4emtiWp);Q*2K|!se$Y4}iid}eH_pr$eE*`+|Ly-4lCztt9bvuU%Lpyr(vTd3J zE5YH{E!*FJ{Pw>8t4B)J;yo>k0FkZJ(nSPY^c@J9+U5$WSAX9E4kg@rP=lr=suZKB zIk^=dijEx(1RryPiX?nes-2ehHlTbM&%FovYSck^e3C#vIuX*ACJro8pm3Cp-Wx>> zm`v&k|LDCV_6)R0nG+1%1mK5+W+Splw4fS-t9^DNlIKf1UisxB$$hhM?CJCvhC4A= zoc1J{)XFG?y@0G9I5jdp;h?Xw~*YB(dlF={}~QGhReuD5N)-BEz8o)>qF zL7{K?M}hLhxL8$WH#JX5LyXNw7ATVv@!5?tii+;eO`Xc|B9#-z?e81z^~ZTnWDPQ@ zGFd95d*)D)m&d(N${}|hV+}l|7c-uw94aosGAV>Sq*KJIYS zw4*AI5~lLH5Rs9Df(Lns4tJ?}$hN!e_sHAT zkr`BVYnXOCK_zbAx?+%f7N|dUeTp!ev@JtsQj6@$nQ;&qX!`2sA6ZL~D%tD^+%u$u zh`kuijuA~Hv1i$|hxUJBkCB(BAPyq-iu4A|dFB-zK*mL0jz`Igh}6QkUB|{S?TyT% z@)XjW@sQ325B;km(%G;j8{ndYIONYUw?h5|c*Bb25(?>`ps;o@>QeeS6bH{a*EX@d zS{7-a!l2wmTH2ri`=vU_p%@Enqv?^fp6)<}!Mv?-MpBX!2qWy&uud0aj1l>wJI&$?8=M@wn-&C>coc zkQ54h@?(X?I903E>KQdp6-~yx9mNRRTvJ#GfA*sc<%p1Oa`4X8%ZUYf5DR5K>c{Y21}slnaCT)dGpJsw*^L=K)9wZwu*fr~$cXB9 zAb1jAy{$i$ys_q>dGOf;H@-9j=LK$miT8oI#e|)p92+PpgC`Yv2?|OsVZ+;`W`^O2599ONJnOF25n|DU$9Ajkg3b1ZW z_Up%MC@k-DYhzN!Spza&xe4%SMn=}GJQ7k#9l3N4XMMHBW^>l8AM+oX_Z!VSjOF!~ z2xa$c&0%657ZPdrdo%;(cVQCdU6Z_YmlS9?nT!IaT7GCO4}`|hEGYDA-q6J4*8cR| zPriI76g28@AwMZv1aWYK%bJK^4i$TVO_N;e=G=%OoWVsmb5;u{MUr}T&)Ukb*PCt^;iB{kwn7BuS;BLO!EIwKV9Lz{-z*JaPcd4cVQqZHN-Ttqh6SyYVtwD`Z)4?fgK16=QbqbV} zC50PF1R+mi=~FL#6L1~pGdo(J)Wfp?xtQqQyA3k-wrFo}aPJ#cFY0YnhZZeNtq z7&n{QDaT(ZyqN1GQ&asj8=c_bL?U$C(3An&6G;&(6nDhY2R#SHg2+x z;a3A<@hb7iYtrD}O?Y~gIWe{R<@c$^ z|9QNQcxKA_`rSMOQJF6j5q<$9KEb>(z0e)7Gt;{_dXL~6n0sE0F-7$(Mhv27@_Zvp z&yj9rQn8j26)H-0=)RbL2Yg5Jx>_UxBJs>ocnf?xPoNZ=p>=G&r>_*KF21+a!pD^F zgD8fu<1eOe8U>W6EA0s;wRwp_03>B!_~#B(mn=)h>jWhOHVcj{))a9}z|Yh+*(pEM zggCq|7LEd$&^n03!^ro!y>11nL!pN0!UGWW^aqo0(n|C!f0D%Ycx(_B+8xXNHp?sk zMjR{wDBGJSZ%Bi?dALkl)@$G}+|jhfM1P>GEUTK_JwF3*ouvB!$~HV@+j(N;Izbl z44$4K3m(}Z9sm~?)D3>?DByxDyxbn-y^BAoqp>y zyyUaFP*Wu42r3P!{9zy>0a#P0JR0`2K(ai*u~fg1KQ)?>LysJ1I1poYAOOp6V#fk* zkmMT+;STsiTtZT%@&L#vUO5EODJ(NF127s6AecpbsiOhd zHvWBk-Cf5R;7;Z|`qDrM{SnytPQKD$S{^BM5I7T6Q9+gwLpAN-b#zc7EvNNb)eNdF z8GrL)ON|Z&2$MR|j~hpQeV=4hqDU#aZ=7UQ-Qn?11z}`nB)eG#5A{Uq9K0vaTaalq zIbPn^&k$G{Z{x)(>2pJIZf;*;4Kk6&648LR}rvK7R9MHPDNQV7p-8Vt>^3dDdL_J(OH%nO-0m112J(yZ}eDp6IG~C@Y(0{dBP5Og?SIDCA^TL zmkBioag3WdRsOIVgp3x4fc?Dr=wRWO+O+AONS@LI0er)CNkt*lxs>)vb^)nDRM$Z21Q5TwZZp=pb7nqAq0 zMJx4f*^0%T!tg+8X9i&*_wh|sf3f)7&(RlX02lb;=w`km0nW6hZfCSfH?;Ie)#{qR9LXnXfSrkw}I$`r3wf+I{tJg%` zj+7o$nUpoyH<hW5{Clx~?#Z=4l|W!b<{ciF ztg*}|W$$_By@$tKZ>z2(BJWh82s>XVb-H@We#q3q+?CzH%Xp__Y$dzRDp*XL6U z8I9++wt+>VGwsnBcRbY9xryezvsbDiB8 zD%86Wy0~n1I??yEK}Gp~;?=kb1>{&hvce3|77)6h_>T8HVUUM$VRyAhgF;pAhQXS9 zNDouD7wI2=}$Z_zJ*s)McjwBXLdR~uPp)MH6Nsm1H zKE@$En%F})>wJ0_#jT1i-Lp75i#T^v{e0GTC2Uj1Vu;^0m3tW zgMyIU6FxDfJr!xAS7buidA%}KSqWxar=1h4D1E~;oCBvS=u-UwE)9RMkBKx>@>g@Y z&vEJ!Xtq5php}zbYfK&eOn_1F zsMVCNilx>5B-+k1)+CP}+o@xBmveFz5s>JwXJJ$LdbBmwn5D0tSGkIk*1Gmap}8fh ze`~QtuE^>_Xvndzmv0$v#gtZE`+V?)6}4wk*zzu$g^y5bWY4)P313w+L%Zsy8QpL2 z(fZ8>td3FCVwJz*@NWD&Mu27LWa6Bq!|tB}@oJWPv7bCxF70pdfxA43sXj?a=MWlF zK{GPA5iWlrgq^vD5^Y$%vdi|)>!1u?0yg>dYd`xUX?RCOPxI+m^ZsqP%%^tiGE9iZ?Lxxe*dQJMI7}53vz2#>{umK~IniqEHL7Z>4`6P> z^)QjF=hQIY3|G&XbJ`~UkjA^3Iiy6ZD!H9-$y-T`D?jX4Q~brEHI~08*C~}JW$wrG zG=DhTCffs+JTS8Gst}52{MbH2)bql!X%~YVjNbE>E@;+V`HDkV4O|?w?E8CFGs~K* zz#q)gYgivXMw_Vn{>3sN2HaZ1tkY6o^39F-=o|U>=lpfbufQ_q2<7?fY7m4ty>j%B zz&QS=k@2n8sJ#U_8B0CyOB_h)Q0tGza)C+ESf!u06>e`((x}idUg|l6dt4YgVAK7nW!K$ z@e>~SKxYn^WOJWi&tziMXSWUp;taRCmO;QSq$kLY6eE?W1(P|QTOMo8oQ@S@h6gK z{K_(CA%P?Tv-5|4I=8=%q16oY#j$e`J5S}JQfk)?p`&U#j|o;x6Ae?R)PS?ui1 z%)y#QQu~JF_1~Y9{hqy9{s_cM7^bGvue*`1r?c4}wA#@MotTx|*WOCvRTQMVkCowP z?b4Lmc#1O#hr40pj=u)lJmIe?x^WH)40Fp=Bc7cXKt@*AlzQr!LNy?_^KKc zR*tdhJHxjrnF6@EBBLGA7a<|#!DiYw;~jY-22X_wIhqy-N|tv}2EDxG6+pyVjAcGJ z0vD8G0=%vIQjH`76zkUX&cuvrLannQH0`bXe z)MemUj!-F297aD4yMcmqdsP&Z8*#f-QUXymkT`ttXi11)UUqnOM*3Ho0v1l-D8RLD zcD0^tyy5^~^yOn?mFZm`ho3XWYPMWR$mOFv$XkwV05z)aT?h1<< zovl}nUcUh9JDDhx0rls8fS6-2n^)tx|DpmUNSH?H@fBor28iXm^sG|>BGS^39Hwf{ zbbuyK2c$?_TU!IIAVoqogD;S*aq|E|<(+4<-MOv@;L+4CrQuXi2(vxDteDrD!yHm5 z-)Wt$0rF#k$H$4BRZ;OLr>MFxMYlLV$ZT}YQqoo-+J%7KI`)#AN_q5i-*vSZT!#*9 zBwE3GD*qM7A7Wl?l^?e~3#9HsVuvqnMGG9vAcry7 zdCKx!>xPiD5^xX~32Dr9Kvfrunf86*xi~mNJhYfO3FTZS@!qP*BFL2MWs^lJRHAy2 z;e#KDV37wUsICD;R@e?3C_&*U#jFmW5J1|yin<44XJiDF;AW=D)p2IFOt;hgiDRNot4Zc~S;aT(;UXbdS)icpZrm z-(g#GlJCOGLyCU1b*-T#qLXUlD>P>$%?A!Ng*mVlDH*Vj_i0K_vF0`WX|W0 z;UcAXvl{M3F?Xr8V@Iajh!GWE?>qqFyV03JssD@bik&6d0T&BWr1{6Z{}FZKn;QoZ z4U;Ny@S8OcI2(pVzlmT-u&MYaxJ~^C_#vh0<-~#iRCl6FhM<1}q5I>`ukv#>NUzEF z%;wCU9!iqL#$p+Pjs{IhG4!1;7LZYy6XpMg|1yUG9~ECYpvKdIItVzJ=7W;#mud0c zn$791j`XR62#h^#w-F)~G;D_~I(sk?AaW0VnnL@mvPcL}Yq&8PlsM#Mk*kU&C!6N`D>(?t^aIJYp2%+>SvBpxKB1arb zj~2D=HFP}!gGRf2pQC%3XiDL*T5M*Btdn;akZV9g0eHjFEi{~x|33GG?yh;0s|KXJ zI~ARjuQ?!y%B}s;?0h*a4TU`;%b%YN)TA>7jZR{jthY~wfd^!Z_xre&L+Mcq5DvXG zL@Mu|kosm1MFGX!l=I(}86-)kQ|W?WXRHGJLd$9Q4#82vP#Rf%2TbM$ zv7||kceus|Hw#QshWL~x+0Ny$BjTrEPRGebRJ`Gb7&s|_&A>-%@Ba}XklImhJK}{V z7f8X2yS{NKK;|_PX7d^zN)2+P?U>jq9j(WZj_S#8TqzK}kccmh4dW0`l0`y%oycL{ z?c@+h^Ok$fLE;vA2u7rbaf_A&OMpbJcOTf9KrCO{rAFfrH^qN+opAP|eJ=108LAppt_7`-{7%kfkm8mBVM|1sU<)AiSW>OXBVIsy7)cB_8ih$@4*{*NKjPpFQib=gx^5;w z{GM6nhzB(_;6JvHs3!4|ptKojsIBqQf#P|&T|$iMvIG6$*~`;ERNCFk_akSYyeY)N z3%>BW&KHWHMASdW5$mJ@eoj|k%-k;^A^7i*acm@2msFeuf9!R{ zj~iUF_4?WIC-IV~?upbFJrN>11e-u_w_)$uAs!dg{n7HML|VdA8aJ5n{QfTPi$qwI zYNVxl8(?;mZilZ4hs_`pX>vW?&8JX|+idkJi4sbr*@U@Ux!a)l<%?%ND}+KvmiGm2 zBNJ&+5BCfxdMWNa;{T7TYk6z_H6r z)bjvivT%(phqrwkw{Y$7@k%-glOku0j)MXAjfu*go@Yi(2LMR&-PN(Ta-jf^;y6l} z{$uPEuZB4=kSIhZ+7-_Bn~@1naq{|vtM#Dd)b))mqDAHZl--(D{o*m0{1H*xA;yRs z3UG>c_3{YepbL=A!mIJmb3-M}C@qZq6BmnnJjQZ9;F&q*mJD(AjsJw;RqFw~gCLm5 zRYE^Uw7dnHsn6@Plhd3K793KlnFj+6)dH#SXoJ-;w>wNX~tMcy78&LAfI`Z?K9>t9f`Mz z4E8kK#EvUr>12ZCi=@kogMQoXV_6mT)w=D8w9aPF7j*N6^#ujET{k1~nHC3+jy_n) z{Aud?33Z=15k?q8+H8K9>kM}sRsRX87qzUd@R2xeQ5ElC3k?N;pe-UJSWhe z6w{qtr&$QKCrKbUA`+nXq=skquCj5UJ=W4>P31q$o$qEcR~*Z-#k(SRZ)FNHq@Y16 z_oG4|vOTtMhE?+s)MrAJ;T9vpgAQU1x*RiYk#X>{htJ)^5#lL;=oQ~MzG{Plcc~#S!@BxSs*h(qu3>g`L zqG71_4f9q@>&oYEA3nX;8j=qR!~z-xf2SXd7&Y@{<6tk}n?@}m*(lJ<Rmw87-HiZ~@xqfc1~tax9|uyD_~mG!PFdwgjqVF;pn>Vgb90k05a<_V2)c#p ztjogOPo{Q--B-yVrKTsj7Cix^x#N3kcR>tE?S?bHMpe~e|C|OAg<4I{8l1RA&>=fm za(E9BRrUZhTo>&WM>lIi&9c~!rs}jmwR&2y3{yyceJ=jfE{kNeFr6Y8SlAi=(EOoB zSF7h|6zQp<5=i_qYgDvvO}(gObSm*Re|~QwplwVk$AeY2-|fij|Gl!S70gzks0{k44~5O> zkSe=C)pz>YFMmKzrn+T089151p_4e>-=L)pI|V)RMHLXtk?@$aMKd-Wrub{%*k`gq zkoJMOvv42B6!I_o6M=|3R75}mN9$9C)SzD3W?qZ0D1r=8(hN2i8+wqu zPRZkl72b*~#t{`%xb&?M&di?66NSz=TU4}w6xbanCda(~ZR`q*RBj}aNK!a<?8Ro=@Op}M|2he!6Coi*#R~9AOljwef~X7 zgk1_?2p2WSlSiO;KxOJv1jY@rKj~iMVm>k+sXQe_Y>*@C()w*J@k&LYtbnGR*=&?l z0!bi56kFry_dr>o*toxT@DLgCB3RLun4rYE=JAdAM%pr9ce4~cwc>NHRh364Rc`#u zN&Yp>es@-4VG{<5x|n@GGO{(vauY}HS-V;}WuSZ`oxI0!NiS7y;zwp;BA<*!@L)Sg zioyMvLQQCJ2@uY)6nn9YvT=gLBe7hpv5)78=!m?`UXh1FEwe01l$S5Gz%8jEd)kQq zT4o~_dBWHNn4p%~DD~2>iS#n%CMaI^AAaQ^`ybV+R;I%NBB}5UjI?@#;3aS<7rT4` zX)4nuvF1R*VBXCqs{CY7>;fI&QSS!Y>=y|rpQblit(pZQJre#>83xkXkBVaAn~fR| z%AtIEJH7ieD(HWcfB!a9R_pF(u!|3aR3}F1)@xudqbrI*0U&xIdETCXuR3g7UwY(G zP07o}JXh^7NZXdP9u$j4umtpOY|24ZqyKbv5;vQ%?l=#D`mVolC?T#9*(@6|`{6f5 zD5SDWu${+ZCz=Fj_zYd`;vTOP&VljsNy@<3_6@>uFy{9hdPc#K2NZX&unaPe3}u1d zZh&owtVK%$jDEOmwK1lC0xh~nx*e}f9DNSW1mm`{HrOvi10cB*g{ad(Bm_bvPX}8m zAper`t)AYV_!iJMDI5^Lp#};l=UJZW7x-`>=jQp@CSwk+5K}L;CaVb(i37d-JMfE$ zy~lV!7i?4Yq+IXzLaQf>Q(KG7qNo^A?=C2`X-FjKG zK85a8WZ#Br7!G{diAO_paIR04q7hcQwk}vQhxv& z8ov1RS_KI~mRZ-zSP+&s=A%E^BMrWzM%MWBqAI3jXKF1x*-T^NPRNL z1Zj2`eK6@(PoSQXn9Xv%(t_Tc+QQyim?~RIecnI0H%G6$N-|PX_j`D?ya1Bakxh1| z3|A3Cjj!|;Gr=Tr06#uyFlDwEBPDgcK@II}kfctjMnM{G>w%QivAPvAl<$W{iuD^i zSA90DnXCE)$?8aWuiO%d1EQohw%3UC=>h6=>6$DA{9jgQyu&>YWObX8<&(cRk*c~E z^|#YrgP0_#ZCAUpJ~n#^t9ZvWZT#z%E}YPM`(Guee3(nL(w);L&KHBJPiSuRpNhw$ zqR0Q&Dm$BX)e=*-xf7c@v+@On8mo#TO?o{YyWG2qf_&9#5iXp3N50AHUB;6|s`)a1 zB=hnc%k;h0EA?pA@sPuQ$fGED@CJB8aAdl)PkI{)TNHW2&AE}NvQ|^!4K-HF|MBNU zMYjVA&%%F=|J5x$U}bQBPJWNbUWKF~*TF-01jqsv7J(2l`-I4PQI&;|FBDP^B@>{hkb*L*MvKBs{2q?u=#s(I?}4NSD7|rq7?sr^r8ilM4?8yG zR@koGe%%J|SbaiMx*i$ien{S)>;nDx`aw689TH&BH9hr23%DmX8(f)hZ?vG}rc5t` zZB)V`Yx#;!%uvn*^p+~dF0Zv2p~h;HxPG@P0`NT<@Bv#q31WA%Pn>sHKt?Be`e zTtjoe=DdR1c9e30%0mW<%l|e@dN+l=LU%bhW}Bd?qDiqv<2Y1k3oVy5v*$G8DHO{G zEM1@b7Wc8gd_Z`4$ojY9z3lf8OK0$TqY10dkr>~!`C>sA64Py3t~0_tB_lJN<2DXtiiXxN&kj@MwgW47U+;E=FR>1lUG zAtbDW_0uQ!E1WtDh-$06|C#_b$qq(TDQj^AaJwX(gzIXe$5>`T!a584-uuV5h(S$h zzy>?a>kd?&j#|+Ba0@C=ix`3?N~k>Dcd&+1!+sYkPk(%-ydbqA_9 zUit328X>g|A8tA#LB&a>BH6M!odpnd87r+}GwMLxa53!bu~`oZ>q`7)lE42G)(Jkf zZ#8fOyjk93&XcuxNLaU_G;K_~)>9wghxmATVI>EcIQSy5O@bJbbCV`CkKY%Q1QNT~ zi0#L9IY6?&C4kGnJK+5~3exA{1>@*2aaWN?C=0Ki>B1o?9+~GA>;L;>PZ8SjzQR&~ zpIi3yDz<-*?2zqxNdp6ZAuDfUGh*qVL^tEvvOmPrv23)vU_tDQOUAP`S|t0TV=`z6 zWG~FO+D^eANtgT!Jj?o*Z>yVtz#$Rn_3wy%(ghU~EM_aZGZVp_knTw!c@HGSQ_A88 z`aVBkAL)di&l-{P%ZjU-1w*7pw=G?QkvnsuB-G?>Y}cQYFik@WIhM$)HV*nC(C%uZ=!+f` zxI;JxX2quuZ>0X;980wHbH4!D9P8+^&}<|NZWvdzS}3R~0qoucCWo3$$|o>Fk>9Q5 zs06XD`l_4j77S!H#ShFoS<;cA?sSpVXCyFX{@(o88oOO8@|u?HGa4lIzaDmus}yzx zMFEYVMx(WIWG!H>67@e_9U5$3(ydVj($z)P&ZHu9X(=tyRKUG#@_)ZRp+Yis2dBx( zCD6yF^e8yxNZ;dcr2w+dj{HFr$iBL%_1YiT`axtJVUzs<6GYaTl~rp>Gc$nZ^XYf= z@TwRApsX{|zmVsGnqwU=MR+ulBD%X$_mli8q&XM+mhTIaM_REc0YNuT<@YF?PfVlz z%j106HG+|J)WIf%ADXZ{#aX@%EdTsorZb@fNxC04EzqZln*Opi0MAbZ&n_D6iDhOmfm(dP#VXgmsx`FqMBQz%t_ zvOZaxp}oh`*{X?zBFx#{NwrzfQPkB`FyPBqoB&{g1A&c4b8^%JN=1HT=Fd0_k-Bd5 zAv@c6q^`TGa;CZfEPizKxC&tt7=tF6J`8u!BFVZsYwlMK$P=yJ?>fN5DBoy_2?5GT+rCDN-l0f2VNdbood zJdad^zv>jOf_h{(JWniD5k@M35>&x*B($F1nX*;K9SX?_|9^*UX|enNJ7jyYo$et!WSQGWg8%D~wQO~ew&cF5 zgr%YPGX5g8TpC1qXyNSAM0KeZHL{?YIB-_4x1cY`+2UGal2F4C!!!@(mL6z?^5r+#*6>__Lf{B<@c~KC zTYywssq6iS1%3CW8H7{+^~lDV?k=QX0N$mqX|({sLW4MXN4upZ;W4PjOtNR3z0hwte%+c*2RUf*ATABibIQ8BKv|hr=V#HBAoTT!J1PeS#V0>~=)#cXo*0yYm%+5W6bttfX$(49TsdS$^=@>y+zL4kjy1g;*KKdh?S)smOK z=~VjJvEsHgyCKJK7MQ8oT*Hlr+8=OwYR%qAw{BI9UsGW8^X!7|)Uk{*n7-qgp!34N z0^{kC^U>EjF|{_uR#?x|t>d(ujK%nAI%t&S$Ef@*?lfn}TF=n7d_1%WJfi|Et2?iM3iSks*hyy!9?!N=gIV5zR9HudaY;w~az)!S z)dmdNOK_^lJ6U%ZW%m#+Ac3Y8Er_cAj+6Dwlq z;Dxt+zjQSJFbu57)3fXwlUHq=1Ta2s-IF%bh0!=EFy<|dvX(MZ(Deml)^#lrolKlE zhlJ)-{nptTU}>v9W^OMcT@blg{f^gU1ngcGib(6M%TA+~Mp|0Li{$&h?NsT&{@lV8 zFVyP-#F3^}Xtek}x&kXX{pmuWRNxD8f`L~F+;X?XVrS-&vjylY`qSa9-e15&?V2~)IT(D zWfq)T6JQv9i%asfhPgToW*T;lK1{m6o+zON{>P9~a{ggH2eZaFGua|>zF>~`8Ed-| z=U*^qH9B@hb9IEfTa9p>L(fxw7!REhT+g3_$%{S~93(QeG4k@LDM6^2$@ub5VqDIw zF{z(y{fr?)$vXSf-b7u_UcOgp#Rb^K7Q7uWy?H~s&#t(G4JC{RLN)!KezHB zYbyr3XO0OqU`ws@)yw8*A{D=cs{X9TP?Q+$tUe3e7_WMBMQ7m>t3pt%)9apYOGFM9_^-eByE?4nAW;*X zmOyEDK2*R3H?A2ldvfZXfzj}{jYuNbyKypL{c+`(=|MUhc=&AU51t>Mz{{yIZ1wf| zuD4x;bA^xCi-r<7>o%%_8 z8>Z)jsuOS6zaA#hw}x8&WauVRfaV!YXU;VIxR%%z+|<=`jy=>=JQtxYm`*L;@>7M$ ztF5L8JG<{9Euk%^HE$Z(W|bmXN~+M;plP#*$#3>Ce?dt z+1BTGe0pJn5H?<&&{Kv%D7n(%Cg%PRC4Wy1y7BdbeP(eoN9GsPU{tug;A&nn2#|Fo zfd)@1a&>tZj8!`uGizgre>kOQV5jR<6qJ4fzhhGkZOQ#m6a|N7B_-u-%Dkl&e@g16;n+JAn$FO7RN*0PEcKC z6n}v^3F+e2H?<|L?%0LQAh!Omqcj7MS9XZIo1fFTqHC^_9BJ)ICFG0Hdre zWyOt*0WFUTfwXg|Y^+*ds$nl(vpQpyZ=>@w2NGsN=PWqHb4bvGCX zPWQ_2_#-u|xpqzs-roj6x_sx;m?i9ecIdU3(jKBZ?A*r@mS(FlWP z%vYmw?61aDHZWKC{oCSUM!W&{pVj^e^P~S$P5kcuUpwZdJe(u)H`SbXZb^7_Z?fI$ z)aFF}G>CP!PIhZAvgLX1PqdY8?{W=4^vLbvH%8-F_Ag`Pc!`Ssu31VSGx)wL3Mo_= zmUYVh?IVgJS9D?Y80~Rcd&0xXrRj@r1*cPFkuA625665JlxxOAloZb{I@d~Zeok!@ z74@qW&g~lAd0U|Jl*(iwJbBprO|4NgHWy`*n8@zW?JV$t7H%==gd(G9<{RRNnbo>` zeG3t(b0d^yB;LEu$?llO!Wd@T(KM+$& zfsm42r}%_FJkNPw>(C&|#!Su2ZBRtQ1Krlv07trAh-=*CQPjM?Tb*Or@9Cu{=H8RC zIb2@~1&?%Sq~#@YLu9dBpwJD6*|PrkJn$C0?kG*&D@KywCu=bxJ`H>t;pc&%x>xlV*`8Y+PIlHE-(#V3 ze4H*XF8DJB5Om;QZC>T$lm>_QjyCwl-}B z%#q+5tNAyg@R z4s;?Arek;9+e)mzRsWeJ`=X@ZX;G89i1<#={@eiqy#x#%pN$xzLW8I3!Y7MjJ$3%? zJOXAq6yE8HJ^xPA-7WD>?{%<>h{)d#Z)nPgxkbzHc_kH96@@S}UXIrN`@#n2`nRA9 zXkWJ3qgbJ#INn&FC*8IRd@6dhSIO$39hd@kkqXvYJb<=$rizq5Lk{djV$N}CpnuHH zBkSL&&`D<7!mf9Ev8dTPyaKZKpi2*F_&slfrK3N))-AW7J;^x#$UvO*}c z%%W7b?41TOE3!u@vXi}w5JHlyjFP>w#kI1^E_+?8Y%VUY?f0Cc??1o)KCknf^V#FL z_r4$g5r9~$p|*B}MDczc>j|p>{Ceg;fARj=H_!XT4r)cFSGG+6IK^mbPE`B9wnSKT z?eNq>UXAaD;_yn@F3YTi>?(J{rT%*T93apkX}PiiSS&S-O=bWV%N$-E;Q$1>{F4&v zjXcEwb>vMor!d)PdPq-BnKf;V)udigL z4QWjgt(ctGJ0!s_E#{xA|dTOZ2^SM__8u5VChpk)rI#$Z}N@0)S;uuKZoj4_AkMNu}+|~qXZ7^ z33QqLCor+?FBUkh(6a!q7)iB&3Dw<1i9Dc#8?Lja3J}{r;x7J$ghRgU0JQz((-se? zi<4aS7$Pu4eH7#PpF^udPd*2`*77%;m0$`)YHp!i&j=tIhV$sp@B-JkDis!7PSN^u zaW2((fbSgegXfo}$g_ZOwe94m2LzW_fdnBSC~FHmp|6&u>`RegiF!>@3wXO9XDIP# zW*I)%DG!@43$APto1h)vck>GHO@1Jv~Lb+bsEo?W~Dj+ z277$=homjFCqpZAYQhm4<&Q|Yrv}2pP_u{U50K|AK8b$=0prn>%Ei+_k*&d9nG@i| zAV-I)5i1=$QAu1Z-LO_r$7ZMb2;ZKkV-7j-k+aN6n+fpCajaU+Cxsg`B8=s>OwXQ) zp|Ey24Qv*5OPs3q=ik+SbhbdOcls*Oy|8Q(82*t4TQV+1a(a1V1nyI$TivXZ--~4-!Ek2c0cQuGu)VgVQu#$ zHrYTlHWHU2e9T9Ox7H@mQ4JsVg^1pQ5+t+wQsD|FX^e2E^Zg64nf_v1kT*_k?I}H{wM$xoH!o0_V?pSf;~7vm8mchP=8cN9z7bJdAT0J$4M+Y&fO` zahraNZYYdZ@B{jsiEYFe1IkgC@u9u%C&%2oW(9zQGOnI$_mqhMrnnt66Byg$Zz2Zp z4x6!HvL69kST?`z!csOW;s_bI_#W=ms?Yf^udj7ko62E?{<~V6>Ddrrp(>uLIevr1@Q*yRndC+o8!{Xq5W6L_-zlIgls?hOBLi zf0{tx_fbp2M!uqu1BIhDlF7)9ZnQGS{mXHVj1_W!nXM(0aoFOcelP{h_0`vmAHWNS z+#9C_Q9d_eng%c>tx32;+hx6e)BVOKzt|oMzv}_B%CJ0i?O#^Clyo&X0SbpNS!T7e zN^n;@B};$h!?D>V2O;g0N{CleHor;IR2a@^ z&4(HIPIb)Sidr4;m&{;!1v}X9uppiGFUSr*DN{>fmMWJXz8$AxyMW#>6~ZvT0#qlbSkf&GrB40VObQ?v%Bs6}AqC0X#eqtC=&^71*>;4$bss6b z2|dj&KP7C+e(mMJe2?qu%(h1o4jIA`>K{|TGu6v@kRX|le9HFc1e^`5e}_px1&>SH zx}67vZ75MM;Az^iJrN3r>9+2|z51RODrB@*ObwwUU|Tk6d*J7}0oKG6YlrE;NiJK< zG01{ZdXRU}_@W#a(`vAORT`btGKU=UoYJQC-AS;q_Oax3xDmgLcaZ`V;4~(85mq8T zYGE7S>W-4vRG%PYKQt*O;5jAm(o}%^tT9}X7Plen629AwtSPx-NIfDTd6O|vh@cmg zaHwZ57o6GZffiLHfIn-3?*SAP=EF_5QScTxFRDMF5>Dz$BUeI0oy$)H*kuZNx74&i ze@vPj561;3fg}*C9e9e)hFLAPr$LFn;sGP-*VWAQ!DsZ3h6?MC)>zJlXx z(F|sC?Al`_-Wug{5pJ$#un$Kpq3f$Oe!%jourNfA=^(619v0@^zlPig!qibuG+FBT zu!_L4EUY|M<`+yP(X4Zw`oge)W`{iz{^{j55R{F2NDcE2r^l#%(keg@Z!I-`7GzRI zV9h0r+C}&S2t4$-(op2%u`^uriEuj+#89%#K{YG|lqeuTN$1>dGGFS^v zm^mjz4dPr*#5yY-eB4d4GOl1OkGqNgFFH? zFVj1Hu8uIxe*YCmG50_(hkuhgmW9l-=<2!=0XUzQ9A_!)wIzU|YhwnRw#e;)Jh|fG zTAVC&gH;DL>PjK(Z9T4xt)9bSz~GAE`m+C)uXy1mq?el!%Uov64|G^T8)*rf){YlN z+8k2d(#FzfkogoQ*3tGC_KD;k=>RVar5jAWj%P84u(jYHZzkev<(V$?d-H0VoSvXipV$#gD2hjUXgm#XC`(P&vwBXQw7a?>(#b&z&ec zOK{xi?XU6mNg#wZv)F$?JP^8|G2|AwJai{TjMHdC6@0xs-r_pQp(~d|Tnpe4Z6<7_ z>k*t7Vvob||43?_oQk}1;0jMv(XVtf!dryP%uhO~fFxH1Hc19)baiaugJ{dku-&%t z8Mi?X3@k}r6onnT2hX?#;gOOz9gp|V%r06r+Y94yRA(qN2c;x|>l~X3vkc)}^ETJ~ zBh3dQzBR+)#D+<5g8BD7UhoclUcM(h`WkWHme+pD!FlLf5d}&GXhJfhMz$;zTDhok zLHdZ~wIsP=y&X$-YA zbn+aNuzL;%XaUS0=B7~U8!&;43u>qG;$etq>9&5p0!i_4#C%B+v8rS?B;564?d97y zK5lKQ{_7vJA;sfvuB5O|$3M6=Rx!3g%gW0luRya`DVnUIClrQMrk7)3a9r}9#gua; zf>hYn6UMi15duY+G5?O-iq6Nt8$QafUsT}YiIQPpX8-CpFG7X3T$Vbh|7#pX6fOT1v%XMA$G>7m z30ZOeD`p3lpe|L&p=ZFe;yg&Q3iVHT|5a@lE@rU96t?656t|z&eZ4{ij z)JdhDi(T)@p^@=OERbJbv=B=5?wwU>po|WW#aLIW`mBlOrG`1C=%wCYplv-kqLQ}CT~W!;8`8W_kAW&h)mc#(JYPN zQ&Ho=<$xHqoP$Kw00E(UY4@&?%WIrT)cX50YE$;;l~#u6Zt&4rf8MKy5&NzmAN3tg z4-Qux?oz*$@E5S7CEZO?WN_+9wKZ;i)a^$f@kLI7F}sX_vBbZ=YeW6~m*KpgoT2CE zgl+Q2Qe}(-^(W+ejyU`^%fodN)QS89J2r~P4oioKcxv4KUY@uU^M{Em=zhbD$Asy@ zgNplY^53nOhevej8Uj1Y!Um?#zOXjnV5_M$4#A@;hB3beg1j!0WEW(?J#24wv7_W$FzK4-!*vei%i}UX^?s z9KC#(Q8@Qv-|)kR^0r6aU*pgZ^LQWSU8Bdt4EUU!==3w7*{{p1@q9fZlzVZgOhHNV zC$QLP;G(wJe3{?FOM7=p9R;8dTNIX)6^AoT$g}L+MOD4epJov0=?TJZT^xJxHAK^x z^lFhDMQUKjW+26oC6rl^llaN@XJMd9ZPFOQs?dqssbiQ>0@1!Sq5}dciWj0*6W9~R zryKXKYDF%UuI#-QeUQsG68|XXdB5|Y0Jfpa98O-`&}h3~{B<`qM6TCVbe^rVB^;XD z{wZ>2PjBQCeTb8!cBO+R%XDCetDd27GlhGRBOlGY-LDn$X@}RBSdgIj@>YKvuMDrb zcgb@cZCd>o1dsJJpJRP%C$cu8c61?zJCHnK*&hG5;pMSMUqc>i-)H7M&IRYW5-Ba0 zLqwVQyRLlDGj=r0-M@w@>h68<{8Kg>`d7ei(93@D;iHu3#Fw8GaX}O@>OX)7^PdX( zM3*xAeNrr6yT7dC{)SOxT+p6aw761(pN0gpzw@yl9gCn$kBPP9>06O2>0GFWKR_(8`N0o2t%N11(|0P{ z-WN2uX-NhLA(nV76O9(;vkTDtRLhbUR|P?F4q_|I$Xil5eWxhno9$0FkcN9d!sFU< z7j=*|W;!8nc9{JeT9UF{lJvJCm&_c?Y~D3}H7RDM+wY8aNky{S@QG;{KFsQICb!h$ zqGAD>d9+)#hmY=QMiHd@b*g^NpGL%X>i7%_i@#wI8OV?owNa>SdBprP>8+2I72KC) z6EFRF)bwlkV}&Pi!U|Bm%BFAf`UB_VjIn-RMUK7SLSZ2{IBLGcj=r#LVOMl64q=~A z5j~?oo?v~{Q(dJquyf8&lit^fKkqaVdBVKUP6WRl!#n2ii;B*h3-jk)Uq`w0e*I=w zvxQc*mOOv!?NXseI(;OtNBU`ig*%tzIb_XyTAJvGNpBsdh<$PR-3q79t?ags$zLDB z#uWEc`}M&?q;@R7e-8%4z?H4B$4gc0duJ$ovNiaU8wVf9eeowc^cd-%{4#d!w5m8k zR*m7Fj*0G<=Z}%^dit!dSbbS__s; zlAwFB{>a^Pevf^}pa0SZ?apQCvHFc^lATjK{lbeUyygF-{voS!G8Z~bl_b3N)=qu; zxqMU$lHjZ5Ngp0ESUm}Pbn2bA^#0Cy#P8dlA9IStbw)@KhUKzzjMreef4!Iu$Xz;d zTCPaDeIHxNBu}2O$g0o9SCWtABgjH~n&0+>HJvuH^17_30a@#RNb-XNq(!A};D@-p z#U(Pi>=v(5+&j=em+w85f5IiXee>-?rDgo-sD{j!2bvNDzU5^ad^CGgFM~v2@AUbd zBa;^s^6-*p-`w32HBPO_#g=L_J^g_=dL(`eA|ClLeoFy-M7l#Sk+t#6#PUq2oF%TD z--j+~0fmT_-2W;F227k9tL)Rn47oJXgSb~_hk`-sv&ya9NytBZIyd~)+)uzF?1+Rl zEkc^}FJO;h(uz9kjXGl<=Ac1b!D>=nfs)blM$$ zP;lYi+nVTFV*O`?FN?f1DBaEKX$e~2ZS7B4BD?Or*RSLwPcxSDyBas`+p?iRF5i=y z_dT=6b0-e(uS=Xr{=+zd83mi#EmgO3eA5NBY1{NF*%$I^`<>3$kMrX2NoO#p=UwM1HOLby0$7!#f3XRSrqajTam8p=+ z6F49VD3CvIUa9kjv)X7rO^_kl{9Kv>cY$Sr1Ajwo#ZJd;t-zA)??bW+D@SLh)t3*O zI3lR_%=M<)TgGJxp})juQ9@t*4Rpsov&g=l5N2ck5;Zn&&32*evGte5 zcxBfexikHW5nH0ktNs^q&)O#h73|0n3@E0%y}eP|FKegYs9bP8yIriaT1;Er(>?OM zf46R zIp7A5OAZP#y?GA_08!-~JHP-4jhe(kntP%T?(rv=9{9jbj$6`u$dY1g8>NpU9Uy9B z<{}vZVc%z4Ne&3>9omo+z2wBCGeJ?T+z3TAlVLv+MhJ+lVzOugKqwU7LIFL*_qwmp zLxqO-O4?31vtK53oIYSrz*`_9!B#E*DhGz>4iyb50A+cZ@~@Ht6XWQN5>Ejl(j6yy zvNueVrhOibHYNm13Zax;#DGw~8Ttf>H-AE3r2$;^F{>#!1`tfkS#M7Ek}JG(jW=WS z2O_>HM7X1@Z>b>q^HJ`#dySucp)xV!#m%{HQzd}0m zCc#w&4_L#(IIu1g3XWj+ZI|7Xcbc3K_glVPN0mm$B5^FxJ4`GOqy?wTd(x{3d&7EZ z+S|5H+dzf0v#Q*1HI2xTZ+mB%F)XRz$T%r?M^y}0I${SI=Jd>%AcA?LGLMK~9>H4( z6eM))P2*XFetTABfWi!e(?f%W_!vo50mM=0u}Lyal^Gyw=8pVv%+-J=E3>s3;(dD3 znF-E;kHBo?CrU=BYH3r%CkA}JGH4b~aKtB7vTG!V1IV5)pLh2>3C&6K)g-<#_AKpD zjYrnB84SnKg)8=ag^+bZcWAkVK5$iwkxk18BOf?Th#|rz$(;dq_arj6;4R2Akj^j% zX%NHk)@O2~EMkD>?i14@D2qnug89WeD2p|?>hy*S6Q=-;=;zlyj|fkFlt1|CnFkOq z^X`BHqiYGCs?ln`#i>*RJrrD7TRpdofgWwIj3+mBpl~yNGqs6r`%@kzI_;=$dOtsb zBtV&E`r(+*q#hBm6i zy=IpcOgF~s%w*m@F;@kaBn_4j*!waAMX>Sof*w;qR>q>y9B+!U6|CU18_$Mx9USC(0XP?pLSGbroZb*LLz3$;0G9O4y=vXxruMb(et9ea&(>(#FMWU^{Qhp-O3y z08I&t+2Pxhx6L80Ge|d{wn9$57Pe`>hORMydSCX&cgNKr0?v4zv|pYYGkXkpbq*b} zV2pTSs?Ej-qC97yAFayAEr3sbKKHHGSet<}Xiauuq?#eu!)k`r8cB1= zs@sG8KPSBpRP}@oII_`x$_he(^^e(c_w)qv2joj{AoUE-|6UHlZeYlmJA@WmjmDy+2|yNfPXhR;iF=~t7^LStB{d%|(tEP#V!)Ig$pmlP72 z3tP=x2dpsLi62(=lf#6*-DHZgNJBJOja_v8*6PWTh_GEV&|lR>7au{kF9V+$MGzu( zHTry6nVb!XwdGkKufv{pcUf%oR5OPL`!MFSOg~1Hzp>A9Z&SorEDmxk=hPtGH6rB~ z1fD3s9Z9^4ibL4{5=C=dKt`U;wb&j^91|R(Ww%1;;G}wywCD)yd%M1m(7WvN95NUD zm_FU3@Tbjv*1HN}$0Nb1cljR%K+6mym)8p{n_e7Vj#rk%7RN{f`jiA(XrUHb2&@7Et#x*&F%qY#|n=9r4B=$|wCY+{U zn<#xwF36LT&fxTwkgo)gxq!oB22KLmu2udqU@YvEM&0Z-lk-C)4a`NAN&%4(qXuRa zDRyG__(eC}FAla`1zcl1%4n9_qEnC(k6Fo}UmE%VNI{8q`hB%ZpmB}lSS$(DD*aYNhmhbjQ5n!6+^h;YO+zcq%t(X7`x4d=>347 zK4&1>H6juTS%kY$dos%N8_Wo@t`GDZxsZd}nC4m7+^0RM>(OpN5d#ysTXGS`B$bo5 z>vKcATK3eUAcLtW6bcg#^P+41<02eM^9mO6z>mc;2Nf4#x8WK%OPgZ%CH>J>u5V&_ zPzXHQ5F?4Iwt}+r9>`GdbHo5ov3#7jUYoqExec25(KwNkYa%pwaS}_E*C&M+s1qA+w&0(D62U0Ok1x9*yam zbHhD{O4AGHUzpQ{sX?aI>U0JO4AqL|n|pE*1ePy7@c|MOgS$z0GI;)aXZ%D;-VL2y z=Ye)bKFCMAEyGiQ_XJ zMs)Q_Sn1k%18W`=$gG+Wn00%9g%Rn3pChc>m!H8&7QeuVd|Qt65@m`VXsIhd6#{hmDph-zz$jzJ>o$attTJIrPMxd_u>TP7{e52r#79UUK`IkA}w z2h57D6c2`l9S)eOO@4Is@h}}3VZm-0!5Pkqss6WbYp6v-r}DaeBKmJq z&I!`Hk24<|&oYF!UZs4gJwJn3y#<+5qqBT2%fPErGeyy(7i<0B#{0RO1h1i_HDN&n zp1$nv*#|ENEw!;No@MVrv42yG<3L%sLE~nRmIP>_7T#^T9l-Ci?xVEmBwG;WS&J$S zRP`Fd>NT!jSc3yz0SCg${%$V7OMu$m?jjp-@ImE(Xg<7#)jH|5SGB-lEQMX;{m*X6 zwB%I}3plQ2t(H3$?>B?g%k4zR;}XiCsw=FFZ-7Z&bYX4{#|>?5>{Tc|a_5Itu^H4b zj7YfP6X6rqLIO>8rWkiSAcfZDbQ+IBXMRg+qx#@teoo8WwWtDv78)f;UQGwkUi|`|F^=e+7 zoKvT+Z_hhdzIY{T{B62C=DgLbF5$hM{0_(WDjTzo%||Hh%m+EEzb&gbI8&9*W|D1b z&3E`YMYvmzZ0|fSz93mE6d(Qct<({dKls$6HROKU09UnB`lYxgT^C!oziK-S2~FZ} z3vQ#xa$dx<1S#CAH= zwQ$~hX<-_oJ+)PYgz>Kw(pJM6%}0H2`nPHfj;o$(70F7G_tvXcJk`pZm16MV6(yBl zkveB4s>8!5sv=#-ZtQo;O8>Bn;#B;1|B%YQgMdci0Agp(mgo?w0UDOxcWZL4I{oi? z{@$!TxV|LR7S9&2ThUxV4u}QD#6r08AWw{66=9%1_l@^MJDY>*q@1lRs_8!9Is9!? zhc(zbByIS2Kx}sI*V=DXQ<`xfIx47zfcE0;X@`8I`VSK1)a=*d=3LT6Wk zldAB~rHq*IPJOmt$(`%0O|~iWS(~D<2ZuF-C2F{uFCyi7WYR-P8Sk)~i`DxyFFm5` z&wSBtx+4%z{&}I7QCPM@GEbOn-ODx4faLezbZvLWHxhXZ+Pb;DuW5BY1o|wGWTv=1 zttT|GoWsrQMW3PM(b3Um*q!cF``dJjjPBuwz{BhZT4#~vd&qJ|LS-4U+qCs}w~M5Q zFcoDY6_=AzLHCELPZ}lxGSrW-ic%%)T65SqCgYGGm+z$BmcGL}Yu#CeH;p&D_En`y z1hwW8SlpMIZdE-Bs3|U2v|8)V*ZIVn+4hB+GLeXDgBqt4hdd++*m_NAyZT^vdrk;# zl~FYJ;|F;ac83H_!dmOIy7`qju z?(F_tFMN?jV*gW1SF@u5u6vTqDONUqx-y7D_Lr;v+3-apey@Il$>`xDS&nnjR@Fm9 zH%f&X=!Prhg+*(3)ecnL(6h$+&yb(q`aiU)E)QQ0$h>@Y{N{s>Nd>vMXwgpv@~f$* z`mrBU8fW&z!ddTpttlr+GpKO{rdlcOpngtA?tW^E>GsQrO>jM=nmb*e(mR?d{MJ>WP@HZTb?J z4!Mh*+gzxts~}=|@*+bmW3_h1WdL>brRar8TGC(F*5oMC_~rDwfXKCq%bhRqo{;^(alx9^pA44;+v}82u@H zX+ecB@uV`p!WM{e_kD}$?9oWw-Bhuq`=V;S`6kgnCxLKHI!6`tQ@mc^TQ*T9 z|EF$2Z|uQFFmtx&{7k11CU`#Xo9}1Y#ECqgOr_Lcghyj?wp)9mOnRt1{!SD{1UN^d$-iC=y zC(~HW@gvWvmAd;3PyC32aVbOOq(a_1tsc#*Rtw|z@%!|A2U9NNm=}26Y!_~7eya1& zt@6>ZtCx${)Y{vVts`1~&KIV3^{Gdg9(8v2&ebXm`B)hRuQaWNb}2GyVAWys0b5 zFGSg*GY^+NZ1Ku%@Ln%y=JvlyKIO>VcdFnX>oa`%7n!YNRKnZA1OxZ|yz7$W^o+xl zzR;&Nql5j;Hi$dQbsQy22002}_Dl`#ut_YPjp!&E;o@=mq!!XZr7y-4ZrF~-eQ~ov zdBqsyNb<4hKfBdAHTXo5z&Lua$+R%S{8$`GsC@%d)c0^$o6EBN6>M>O{tuN1Cb^(-Xj<;^38JXP= zU8bsofy~jVLPF6$&##D$en0rd4KtNOS*k?;;x!B8@hO6`~H=?e&0DX z_9^41&i5H9h0SBEylftLEWD9VoZxu%_ktxO4QtCuQ~O@R>o#xPt^71k66af+dq0yp z+P^c_F`in64K6SZ@EJdlMb{-9tPh^f+H&O`Y+Z`EGLqL7`RI|IgRjP#WPNRGizb?r z^~u}jQw$r2v$w>X{3Q0`lBk?(;=6Ci4*ueG;_21m{#tEm_=2c+#NPJ`9sgg9f^8s? z|G32_A;W2_e94U_@zwMy-KBJw!)sJhVZ|=jSBV)8E?JQEs|6C+vMKQ)-#=xY(y|gd zTECw45H*;w-$&Xd8k%afzj6EIwW;T*ub1p@6qnCZ1&3Zo*F_lTU!sahV-AwccR>D8 z((S3D4NHfX<^4^!+iVVm$>Ti1Bi{4h@`4*_y9a5wj1{W*E#;UWXm4$@}+&F@);RMy)3fp_mv+DGa%_zAT0cuiL{ z>e0P1F+U0=zT98(=(O@~O$B#h8KIfZvz2o9&7SBf%P+6Pu2OeZ7rAO;9`U@=m)b74( z8ul^8ghO$W*($_#mF)L+!omY}!`HeKX5(HVooMfoeGZ2&gZsA^zcZ~}Jn76(IvKN< zEIIbMw5oJ{M@X=r(z@l z+eCdZSwcb@Wz17&F1z=1kVCbfEw00-40m~Km7q_NGp%4@K$%-1p~P4CthJ^RtA^Eg z&Gh8m&7;lmoQ~^gXJCx4&jcLvP4Zt4}SwVKhHMeN+AOp1_^LqZ=iq z@5qL-*2+iyuy>5?>T>o(sB@nJE~oh)+BupM4O?9WSCXRhof^IavF z+}=C7@1CmRwD)`V&6xoI=8c3Ug_29`sB1F%rzQ(jEu8|Lc4P-v^H0^^GJA0GK~5lU z%INF_&9~9i!1cUSZm)VtPR9*u5r{QZlpAKOA=|KC4=#SU_*2H94CFaT}Z40tBM% zX{M;r#L{cBffGsJG~YZ?X7W5K60Fpuv(eN{_EiwsIjkOcYg?dhpgDWS(sRx1RDKxS z+PPY3ZU2W#smYxA;)h2M_E}vroOzQOug~|n_@5sdOAuM3i#WaKP~-7ruHe44s(_cU zlK;@eqT0{3%ZRbbY)$dPLB4=X%iLT^W*he3`uO z#GQnT?pENFwuU|qkLfWt#7E&2XWaB1e;L*#L_7{3%*aVPf%d-S=#^BoCOolxWm0$i zg!5=;Si$$qjo#R5k*x93Z|Qf(id{Rp@<%+Jl{K@dg*Z4W3JzA3g~oi^jivh{map^8 zZYS(@d>6uqe;544Pa;7He(80RZS>hLdYHB~JVI#iKxK1Q&gqffjc2o!1x-Gp8nunuW%BZ9C4^E!zl8O2u{-Za-VC>+^cPCLP-;*HCTnREH$pvHO|t zHuov~9`UCYQrTr$^-dHF`HQn}(;i6>lj9Z^G-UY`{R6oQTRK@(W>Y4W)UTsVj2({- zMVPWr5x0x4zw_=m+t5*?QAx8G&mK53vmQhS2xFdBK`CBh0Pa1$vw z2W08QO6c^Y+3$WPywQZdy$>(vnMzI-oTt(vQJJl?-#6Yx69Zia%he@c%rgm%zH&07 z0lH}0wPvaVBF6WjIVDhPBu>=Zmp{>Lh?i26v3g&{_u2}6;7paTZ0pk`T!+06uiF9( zpE1_fO2j0Z>8p49?h+eb+{YIDO*tdeL%gu@=D^%g1K%d@uQ|nSGX%kJ=jz#c%A&3} z=>^Z8=Lui_x;b)vZIGKq>bL30H&ikoOG1;sg5Hu%LWqL0RQXefrFONQh~O6UwTVbN zNq@FIyx>_Hp72B$<-kO$t}A*>dk_EotfA_hXkM}AWb&SjkgQ`R zF1lE;Vu3r=~sREJ%)w%1=Y$XR)ZxcMmz;s-X3f1um27l&||sj7e(9l8I%K!}nVxivdp- z=P@m*k9zFmUp7_{vKYKGsoKdo;@z-f z*UDaN-WSs9WM1o%xcTyTBk}L6o(arrRt!F07i$jpI>=*U45Z?^!+zgMU7`K5rRA1$ zGR((R)B-I=7RnrQCYasr)=XG&`j5?9Yz_qW-%$=)rz^hdUkaZHixKTi_vz{iZaj+` zT5k>(^F4Z{$W+hBZU6B{@wi<~Yfx1Ek=jG+Ip1 zOoWdHIhm^b=mI;!&8vtIF0gCdr}tefs<+wa=Mlr-)o zy`rDFRHm*s)n*}@B_6DCiDxa_a7$M_nEBm@irf7L0AYxLSyAdqM#t#EpV(`F@cQbJ z!vToVyvmNV00n|R+RzaOMCXcB3c&14QYY)^y9om1j6(iMFDXDd#L(1?Bfy7KuLV`A zJ&6EeT%Jh{(Wkqm(s~FiLt3VAYj9#7$~gEj?F^-g{B7g`gp?#k3t@fcOqao;J4AUV zS}nIBklJgj!4`i|4px;4G}9mj_XQ%}3_ADfAx4wM$9_!(SfGOAVteNd@Ri1sA9Ymacdf0g$ zNbt(ljc$iPR;GAI92XE^SD3?Xul@-@l4V^Y7|1|OeCgi&Sq`HG>QWfvyZ}VWwETIP z6`oZ9nao;fvt$GmdQhI`j+=u*FEp$OLjlW_7HC&hDD;AdiyDw%bpQE?)Q!Anm*@PP zhM6G-**MUAW-OH+2nbg%tAhRrGP~n8E*uQt$lFa*dl2l>(tWWFfg_X4C2D8)K!2>% zm|Xd%E-|JfnhJQ_BDcD8gpmt)oRU_05g--|$5$qUAaZ6~VeH!$P|aY%hy$H;6MA>C z*BqvSuk~PXxu_O^B-_(%@IZ(aMbZ<1Jn^HrOGl-Sd{KZSAcNS3kgVuXXm-~e0}-$* zX{SA~eAfa1Lwt&!aseQTX;_E&4SJC4>;R*Jm~}4zZ0a!zM}O5WVnmKcNQ# zdEe5o*uzcse`J4pR^C+MT3QX(P_JnoIR-q8UTOVLLd~p*H!nQh^!mXu3{?5yb}Tu7 z5x6zb;D!)DoH~DtYnKoLmZ@XwEOXhifS?iN|6^_u0I*q(niV<@t+BYL>A2Pjb!vrG>M=2@WwtlwL?;(8{d6 z&q{RbQiiCq2+p{4M)7s_4$At7{YlR*@3la9i-8^ea}I1vaU zLF4_)?@^urtnzfPWlv^(mjuCbrOZ2|_MkAwxE1CZ;&m4+gqcNbv-liCldYdUc7`fO zv72L8j*)GY*gV%`Y=`1CVWe;Y7AEogS@jD5;vzM2uR;haXoF=DfG(O`C_+gG0Ld6^ zpilM-fQ>;3N3q-6b0b+7&tfdq_7C1VSU9T8hm=wCmHd5+h0DOxo(Z8W>s!a@w*v0T z`w+P#HYog}{1^r&78-gfu(Mum=|N4yaWf446 zO7%C(p-7w|3~nK=Y~~nnrPCN8&{{6aW#4R|rWuVQqN?ywfTS9^C7zMX;*^VkjMZgjJ_D-kGgG7IBFJdn+mudg1< z92PD7p!EX*aw3yAM#aS!J{=PDrFRmJ1c1@9EkbK(Lc%BEPG~}o1kM$#tVP$%y9YOw zfZ^K~u;F(|3xKh1(+UZFKyj4M`t^Eg2)y-D*tz+Y%g_&*9|I(cO`b6jjK%x=TOThR z!d`!Rt1f~wOj6iC^1v(#U)JaF?F0CWGI~&@(8TMf{$XBCORca}p_X?zy{3dl1_of~ zDx_T|tojWBoK5*$oY2KSGx5|=6MlP{e-3uAHI%Opw2V zT=j~9lpz#N_Jo`f!e{eo8Of2Z7vh{tJ_7=K#cRqyCc}OF2CQ}0kKbP6c=$m03f2E` z%N>!zSanN&J_V+~f|gf1H26l9ztafspa72?*Mn*5qhGtE{~F|4R13zfss&=-wC_~w zk%IUP;TNCU)rOc@S=VfWT1qwmCdO4Kv@3I`({^q*YH(6a{6n=-RDJ$~{M8N8*@)lc zZHjLIND-IZSzb3PWk0QZXXwv$9ILRn)+s389jWH0RWU)0%U^8xhs!m1^ic2^SI0f| zn{W7(gorXg<4z~jpYl0S1aT{f`{POs25B2>ax+jNf4fmy>;05B{!h@lz05EK=yDXS ziz>Ai(n=D@V7_ucA4FjP;I8PubR+pN!;ak8*vMtpn27n%ouK=1Pelc>|K|eMfkQiZ z!yw~q$H34RKE#PYz_(8`J?gmjC;~iIT~uIwVwftE{=@X4zpMXC!@;jb%cdZc!ha6N z;dmix*5Ir1)jyIw1Q~O`_FvibtiWdF6F<{_0yZlVvfX3oq^S7&1YGV(&|57u64&R! z0IJCzY>A3FMud*3W{|^d?e5za^o-Ch(KoV@da_Z9v@0Ig3Bh2FVgu(rX8rjQ0! znpPdO?!$v}!p}S5K|6OJM_oj^&{S97EQA{p3whUh`UM~jYq?FTVbmS@-5v6Z0@oIs zMcDUkwm%yHNadD+$tXVHFSV)rcNQ{TOyB%leLUqdSg< z_%EzdnPY{=5wr^r`VSJy$7J314-z`M@KDQW9DvTbO<6~%EI>HX>t(S-^E>J{MtvGD z{;($zpQLuR7kP~%hicImiXKjQw?RND%E<)l1!b4+dRIfI?u)nB{MWGKDj7Us_Nd37 zL?s?0;{&?5rO=0j%a$c=8;M)ls{HoFDWFbtkqhQ zT55V;6Hc$qSu4CdpC!oPjF-vnI5MvH^E>$FiS*^;H%H1w9?mc1EGk2sB&v0nRAbB} zdC${W(n)%l+nCiW*Y|U%jz(PFSD{blT-g;qpjR+VQQ8{-zXc)6-XK*E>uft3@bybi zI9KT9KOy}7kJGIJ?(>{(YnR2x-f?s7oiZxDt0w9-Qgh03vGc@BfjUEuyEGf2>>8=w_q71G)_<*>=N@Q$i>{`~SjwhLJYyYEWC38N$ zR<=LFd+dIX>U?*`mA%T;bPbf0w()RfsvGGKC-0=75@!Xu@?7_-&ENgZgoZy~`13$L z3uP%)PxMGW6F%(i^1Tk^rKv_0aswiilx#2S3{9Ps@4q)IL=y?6_f;uD-Zv^yG`X_4JvbM3Nh0 z8=M&9s{Gom-e`uxYTFlc8A=r_XClJIx8}}8m`(j6bZx-^Et~lf&2Tk=oKi7OKW7*XC$O}IPdkZ04sPD;;DTazTXxCUf;pKZzAuEX+Eg4QP7M+#$bcbi+WDfauu5RKnr1eXh zjD84J`!cV4?dU!>aH+dLh!G~`4qC>3{AYO*UlExj7~*8yk(3R~0^0*wu>BwA<~>E`zbi@)PdMric3(yO$X5fBpQ9s<3-L)So)+s*d8_U>)v1 z&6&5^N&D3wuzhIVdvx>jS;Dq-g1ilnG`%Q(y&MVus?tr#v3~C1H|}B7b_8F7_mpkQ z1<;Bb=m844u*T;^FR%UHFHdZ^!(PaA`%#EchRLGI=SYGAQM6*)BJSg5hP$g0(_tlU z;j@o_Df$i2+kbH`{;u^}o(h%k#-8VqXMB}`WXWTA{rQF#^1O-y6)Dos%yg0A?z5F{r;b#bIc z)prvF)UBs4Z4|g^2g{ z-2z4EEbOmyWuHR%EW|^+w9EpZiN9fH$Gp^*Z1-cVYJV(a>bpQ(bWTcs=IFG$2ko=I zHl;a#S}f@glcjU++M-7@b#77Aj4@0BHJQc@isw%=vo9JO+x?^zafCXmvjk8cgLkWe)qYr z&-;7MkH6;3&Q9;_a_&64t>qHFT|peLjoF!kkyT({KzbWt)hhl4BMOeB_&4zAA*dx${+Kkn~5#-C#;1&C)ElR2TMYXlmHD zG9$*s-I>u5y*l|fsBkp5lnvWxM#obxY(Vt^cmFwcLMDo2y z_*wE6hiBvxPhCqvUF~Oa=MuLeeSv(aJ@z+W=PC}@AS`42N>o1rEFXp?$&+>F2PvC- zrH@J%)c}V-5;Y_@lpmf#=-|RtQ{O?|I8%`ARep2{!OjylG35jqTkn8CBYnV~PoP9PChkFVj>Nyk zy*A;|5u68eb7ow0C*G|@MzK6mUAjfij_#Z|u*cz8rM02kJ*0>OVc2_u;RZ>ZA5RY& z#BVV%r$}k?82g>_WdtE63qNk6XCTEd!FPy^b=lK?bew+JbLAsA&lVEIJ{TqgJB0mc zNPhat%>)t}13Bvk(xjhQh{l^N@Ld=xHT+85we~yfl?T^;$B-c;B7O^J z7O%EVfvNS+F|E)H>rrntFg7WQ*u&{CdORn9xF#ID%s8hu>(cq1^-PlPC?XM>+KxAY zuCp%Pdviyhezqyg&;Nb@mQQMS*k-k;p>|W!*kW#+=jgvhV5c2Hf5@jNk#tS`bhK;& zEM~KE!R5uFX#BW>HodrhY>40?+v7`5xAJ3MY^{y)%4{wLAjIB08XBD!&gVGy83_C^ zS%nG7Q#bq?t<5f(jPK+gDvuka2EXjR)go_bxPQgOuL6;PpFHp*x#yp9J9lx!@83!s z$^}ms#YeN(Fs!BJH%gz2LK8{p@^J5N$km5|g0x!4V?t%cFDH@YzPUXs4D}t@7VOnM z6pa%{)81iwAp*FVFyA}jZq_yWJM)?1sA*kd-x|mJ4#Us1ouvFtVNdy~128v7TZPxb zwSABlA5ID5lA9XhCt3VJX%B*jgBTKZ*C5EuDALf31i*Fe_YVhLv#!1noD$d#3{BE! z`^tbwuNmWk&_6iY-Rq2-{NX=IA?2;ZMs9VfSrHTBsG+4EPN?(9|J?INB$ARsTo8MH zr3f*E9=tA0R^L#WAZ~0SoIK{!0xdHc+*R7k$tlHCzGY67We>0fYAaEPg|>CSImL~` zR=Mie-L%ljs4lXnuidRoq(lDTybKJW&up=~Mz)%v{h1nVRz#00c)GXGzJ!L>pw%1n zcPJVSqRMSwsu`3n#zO#_1R;8E;p*k(-(uf!e+yO1 zwk~Uodmr|4tCjoec@kr--Cl9FUM6D4Gl8Ho2A2gEXO1*t5{Y8nb2Umnh%T*B7p7uhyDUPs3%sakq7vj-;*~sJ`W|X^UC} zci8>bwYFLEdzouAc&x~DI9z_SqEm2b+NN`J@E@C|4t(uI_;I7K zz%~_q-gGF$aH1Qf0A)CP!vGS1GURk8RooKA-Uj$Mid(uWLC1$~dXC9QwWlI@UQkvI3Yq|Yxj_Cu~kYM3g1v>M;*ZWqXw%fNV{+uJW zAnKr)E|`q3hcVkkqKGNR) zeLG}6>|DMa)_-QSlZfxy)G#ro7+l*f`cTYeO^>qTcYmP9cwFU{r9HiRHADXzQ8GuR zO!m)AvuaZ@xgg{C`^_OfQ;)|8f?N@g4LAhIf7pQry69~xWgnjByk=(;rrIr>j}Kig zu4@B^YW+v?Ur8iCxH2OCvw{(EW-HfF=u}60m8Ua#Ap0m0;Ku#x-GeonFYE{HS6BrC zt?y}sv3K}nD;C#=l!BU~r;O+0zGZ(e7=HJu;z}bW=r8peU%ql`>`#Rusr2?tU(k4@ zv3vHl3GPfw`OB>jTfwYO{`;q%RrybgBc!I~_gW7l%$>jaXK)qU+oX(NI^#i<22$j= z(j-aTS1wi@+t5J1W zp#p#CykgoRBuw$L<4jtZ{^WT)n?O$2$j|rxyO;cb7ma_SX(y%Peaw-4J;V`eR-$*? zZLp-mCC2WJe7{$eiE(X;fhl|+LSE>Ci%uRQbpN94Hv3J1`S8K+0G35Pr_suR{^Ud* z^^NSugu2%X30NhRean!)?X{B=m8E4pTkSEyQP}hm>lL>&@0Z(UCotGKd;F;N;mCB0 zP$|2G@cXuhPBy=!{=*?0^U5u`AEcqpYMDI96m_Uu&s6J^^Mvs~7QGaS(oew&ZN26A z{(-~_KYp)=Uxp6LN%kr@4Z&f> zU>ov*86tImSqV+t278k%BS9!}RexN&&~FjLnFDgr)Gym8cawL=XNwZ$$zqAE-=ALc zmo1}oO|It~aLh_8b$NwIu)Q)GM$P=zdmM~oIPW*>^}RugM-DicGo_3X7?k0;CEwOQQy#x?$R6NLZQVJW zqy$>HWA!O(*b-@0zl)H9eFN)UF%jO9?5s& z4Vm#*OXwJTM$2yT41RCuG#F<%1cZwh>8|Istu=p{EX}`27rkQ^@?W8y%~Kgj z(XSKl=cGJ#+u2Yoz-0Aq6_}BvVT_h@p>Lu6`Lr$bV&8G89o_cTu}mQTc`uo#sr2sx zeHf0c`Q&8#<_qhVak*-MeymKS-H%h`w%ZppEKvN6SGiVI)p8cqJX7Nq$e^M%;)Gt{cTZP=d9TyLB*)nIO^3s~+R#xy@s#>#8CftX#xouLOU$SmNMiKcC zlF*UzDblIjE}@I&)_fE7{b^J%{4RaX^yhFT-PFHaI$bpD(>Kd4M!IrUr6WqZt;dTRj2;$BPU`(KcjdciUZHPh zYFD^suR820O5bJsY|(#MY%FsDC*wDUO-@?FK76!>y_CG3yCA60>k~D{{&w|I#!v1; zzKNii^Vkp~4&?Wl+ACyjJwiMbSTNdxC;UuY-a0jME7ZUI&v(bj>GKCuX9|Yx5bPb~(hRHQR6b2LJ5_&rY!Wwzx47g0}NI#Fhdd zwtt79`ygm!;XZ4KM7vjq*!U-DUTF}tQ>SN;NBifPSc+3$Ld_U{)4)3hcR@vq;_Z~*{YJ5~ zZ9S(Id>B(jb9wL%QWR=iM>3w2Kw|6dX+J(Q+*TeMO_3G63+Md1RPzZ;xQ{45*wu7! zhGyHwqR*W$C?I+MDNBVVimT1pp5E#43jGmZ3+h{n6Txhpm;_HUAl;45O%5LXI%fjzlc>u^Fl**<7JLx+l z@JOYocl#K@^IUong7p3-Joh6DThqnM{VfRDRfu^=vx~zHr!jg?8 z%qUIbM0>gZi}nOAqnPx=5AX`As1m)cfD&Sk92ppASy;c2si9J)8; zqdKLn%zG$(()?vFD@2#1L;RNtQM2XR`f@s;y_H;h^WZ|+@o(+o>l3cmPR}s+7{TIY zs{11!C*0^swB<}JkN{xeHx)*N$SQ;yPmtCR-Y2v>H_EeC8V*XWe`l`@CHh52CngFI zjizr6V%}qHOLE>}mrt9&R%y~K*^zL7AGl=UWqH<>#xST%OI6tj4~n!=hP>@VF(@V6 z%`7kX{%H7>KFiALIjz^ki=I;|SN!Qf+VEO?8MScqU*|P?&mj0EPUX5fZyQ|#D z{ShzPNGVbT1?q=Xy{1O?<)Y=(X}>!8dbiXf%)Qm3i6v&wc_9`pxML0r?s*YyegsI1llEjXImUlGW% zmJMI&qtd z9(H2Z7YH5nUaqo97kJ?2S0Jec)vnDuk%Sd*+PNyXzILEUgLfM?I>um1h-&i-W8R_| zSzc;5xr}H7AwN8|f~S`(r$aaA5Dh<+i;XNC?fAr%(9;Eb2dm;WgpNjm=e$01!yWj6}TPU70leX5Z8C zS`T>#(z&j8SUCS001%L*b|ItYjShs`C0*VaM2b&GUHt6Xfg#iQ|2`3q>~^-ySlPWz z85iw2X3?sG^B4{L*M7^-ucxo5?-aT2y5(Ff1^`6MOaC%jci#3$Mp?NUXpVBYpCReJ zP1k}z{!V;9Q(4M)-gdHFJxxdh7+jNk5c$Y%jsnPREIjWcHNFn2k;qCmRS zkl54UXtn*L1bw4VqWenK45?ycW>fDIwJx|`E~~uNvlZ76K|Un-1?RBvVe@ZnrAgV< z=$k}0SZS~2xp3bX3mrdGEcCyH!Q2-U;%Dk)=zq`qg4_0T-2cZneLV2v5MyH8sQ^u~tggAPZu>Mz4PJ@q)Y z*X`5>`|`)(*E=CLwnq!)DUuusS86Y|2PoWoQLF74Wg5q2dmc5@WG8u{?G-1ft>W(= z?>TFvnCAAMM_Y;n*cI7_YUQGE5OQNlh(CtbHcC`P1bq59=2Ik|y4o?tAWBa?&@r8R zM8B{siiJAJaOzC2gZoYhO>8}C{Y|6_k6+d7jXals?U?=6S>Ysf1mC4QBD z8yKQrPK)V$_67$ob{|QFlm=weaJ>bhOFErKZ>;Qu$cj|gn%pnmgB^v@u6iDxt3%Ax zstQ8kXE9Nge$VpXqm+}sA?vU!i$(^3K7VBmnFHzG(kvaN9iNq#jN!grkLklVRpfky zuu6vIbYM?62tzF#t)iUHd(o2J!R3=PAu#>{Qg9LEXM`$p?PBsbSz1Pc?sM2W#pL=~ z&V}j7E;uxF!F?1K3uC2-*MyWAGGwGH-$ZLEONzw_Ps?rN|U&|#L1K_Zbh4Ttl)>CToLg@FxFszSgIIKf%>5D zY6Y9leKpCZ0#p=3x=QSC}g>=WoYZ0$Ip;g!!S^JDqCAu%NMGV@uxXMR(3K50UrJ-XPZJtoBaWf) zpEuOEsuyN|N`-s>Q)>_&7i)SNC!Q`V3W34RUh%#n5I%NyAeI3ihU7K1D1+EmXw&tA zx$=rPil&VHX8lQ#3GA=&+(h_np@Vd-N*E^y{AztTORyUK%LxPfo$75p;=AsgNO^6+ z+-Pn!%tK~Du*3F-Vf4M82cKO;HY)G)?ZmnaJnG@f_3h>_BpwH99K_L7<0%n;&37TG;#r&O!>U{Q^2R$Fzu!X&q}DubN)SMiX} zVBzAtFAE+TH$AT@p1x_Y?NFx3$=j@aK0XuA#edW$=doeQQlts32a(QftigtxdnM z1#c9t?ml-L{HXGN*c`>puu8UcXF<9ParghhOVr2$E=#0Z#TtKGX@APGk^%SQRD=k$ zn@cG8ho_e_WcZZ6EW0`lH$_$qPUB88nYi0B8fJ-BZ@&)!G8&piIlpobyi!ziR0XAs z$9bntb@q8-dcXsxldtt&7dz^?K}b`bq$zYOC;)C(vNi!YC=hs2iYo&Ll?cMgGEU%t z!fkis@g4w1AL@FNTX$Zm?3k}1jtPGb1r8={D5=*;0B}6d55n{qQO1J&uN z2!j|CP>vImZ~PT-R*8HqCk#DTjhEr>0%w(s!82-^U#|t6F0q4?D#t(9t?8e9oK8+> zcyK^gr`)^L4yLsTcw9y9TXp4?s*AZ5D86YsUh10@SCrk?Sk+;;|Dx~u{7+=1;8s0+ z=&#S+FKmyw?H3y2v+<`UY=@HwNB!vIQN8%`lPiP|DWag^Z*U^GY>9budn~y5!ac=OTla? z>En<&+dZ4zdB|8<`3*+nXv6PB+@pom+gOaLI--#&hNq z#+@4aZHAha+WVzP?m4b(3`podk0SZ;{$eq-84ey^eFF7Qmb6^U21sT`GVq~RoP|6- zx8a|SU&oOecsh)$=oIc#*=r`6GD~2k{cW0+I*+k0G@lU{Gde3`LdeA{cRHlGLjrx~ zin`zo=R^$}vp^ARsi9C@`-#n$HY~y2cLy&&xnok!jqVq(g0--Dy^Ww4F&*iHEXEY; zWX$u3A}eYxczAcxlb!V@=sL$K4B<;VVuU)ahDkVQVbIuD6tQ96)}T&F;XQLC4Vxm6 zK{&%g#kd{YnvyK4Sh^ES%1sb;BZG{n`Qc5YHC+{Vp*dzz<7$6)^qU~s`}H(5zxOIw z+V=Z&txEJusz0lllr&*4iI~3Xpi%p=dHgjB*{oqh2V=i4MCom$y7#4xc61pG^6?U^UPWX@_;U8l@&@lg&e& zE6v~bi~6iuH(1v())w2eM3{uM!C|^G6R_c50qdw6A9uq|&($%{nDgh~?^Y(;AViQ3 z!lk#!UAyT@|IxP$MdL==>JayePR1M`uijQ+>|n?RK?rs7M?)=qYUba6sfm=CUcbiD z6bFd}dOMy+Q=mjS{6;meVk8ImR!oqXmHAiR7Fo%uh>!R;*DYzK{R~Ng;bxwSx|wU9 zpofe~d?WCn8w@h#)j{B@@crJ>Nz@IKMmW(H+DWv5@P58wWtn2~VABtCQngM`@BUwE z&vsMUx8Lfzc4u@y2g9n~%Pdum7^UjkNql&IrCuEAmzV4$R`+J0|MywaVN+Og&#XRA z6v@pU+a!oVLOPG@<_rUly>wd8@8T6T(wR2Qgz%O-J_HUu(S~9FckImyz#nvA*y}eN z7It9VHC(%1jX1m78k70E@e-hSf|AX)N8lPaVC8k6D#JZq@#y-~MDvP4P@AyK2FfC) zWSwvXU&czgSVrO8H(;6fVj2Dj_!F>p7Mjd#jKKZuLb#=?)+fJsW#Is$j&vuThIHDG zpb7q@Z$;J_is|n(5unbbkrwX4#BQ^E=y}6M!cmn_C7k~K$pxixAIt{Y&In^6*ZPFN zPCwVW&$|*(OBH?24^H`lHlzp|B1iHgHy52Jl-AOE?B_=tVg(Hikk4pJDlZxj)L=2V zt$>-(1wDN~SL%Qaj_n5_)oR6R@qhy*(%b7GW@78x&!JlxulPu1*7mae z4q{1Oixg2ka5TMS^HCSUOzcZArwSe^k>*7iTUJOgU?dbr5@08d)BCK1Lp5?LBn`!DzzCiHxcHW z#H1Rjz7DD7?FPuYRoe;Csk=A@vOYeoKWqXiShw!A=N@dy%fJL;!iYzpv+09};LdtB z))UB%GN4*g73c7|0d+&Hl5L=prc}qL1M9w~uMvq6LJvDP=2;WA)0Cl7&`xcX#ER1! ztZRTmiPWzJP&p{d@6M^OvgudqGU)a*QCEDH*DlSEAMRb34U7I|Nay%+Z1-~HDm<7= z-1tSFE+RqvPDR4--81>(V|Iupm9m3r?z?d$4~f4FxWn~lc74-2Z{G8|PT#)BQbpnP zGf7ah)XHmz^javYM#Wyakh- z&6ekcC)bDL&K)5|@iBs8ae}e+wcu3~$&^};N2b5`E#*{&NB-7joX>i*D4&1J540kT zUb7712z$(xji8|r zbj~?EO@r1dSma6^OkHW@ayHeH*h93$GT+cT@mwA$QG1I( zFXNCEa)d4yb-xfd>97eK6)fGVh)T$$t?lioUNL1cn(r!wf6?{;J88w^SCZx2_S>f$fwoI5X~Lw+xLbLz`S z{HD_fQ6ymnPK!&`^l`$HVq|5?blWm=ukT+79!F^mzy#M2cCVSENq<8SR^@L`*y@Tl7e+O%QzIMieJl614s_n6gV zd+VCG(I%AMr}<(ZY%Q2KF?aqDO%@WDIi7pR213v7xs**C7yVUPGTiQ>`MoDOgCsb4 zqsYNu-vn=1C#J#Y)$$NylC=KZJD4X3P(%#2gdrVfOzLDdaD3&Nq{dv4w{i>H3;{;3 z1S%T+FZ zN9e#+$?N=@JhZGoXNF#DIWAtjOlX73VQR=El0EOi#JbB%d}B+tfG-4Fre>FI0fk8| zenj69Lm|-0p<5O&DgU{*T`o9@ky)lDecKj|QB4#5*rX~%OfJzH&i;Hq&yVc7kRMFs z)d1!>Io;VeBp^<2<$i_n_$JcvR^w9NvTj?;1$B{7>=A3Zt2XI_CvZcNQ3dkaB%JFU z{JCbC@$VI0ggO|`W;+JYmS3W%g9p`Ann1eUnMgBpBO2w``5Y~cN?jF#JBkVCD#g7V zI0fe~4@@kk=bB-^c8sqMO?UokZPpbxTz^k3ah?T@f$3N_dK?U6rmrI!nsB{t?W<+) zwnOHE5gaPMYV|S<;=UB5C$~)DCh6JwNcm(rx9CGyzfpkVc>~$IBojxqS!lFdk4GbknKJV#?$!5G`c=$WE)?qAfFK{UxfbX&HGDp@_gKb zDQh_Jm&SJP!5&4{u;?!h8N*>?cKknHm#~Yz(KIEQqxk0De7JUBgiBOxA%`mdstlO6 z0LV+!tZX~5o(OOop%xdIaF?ivy>JmoEQkQWqDSTip+@XoUG;T-BFk#1ms`I`hGqp$$xwPooPl%_(i>JLm?H%hj9S3eKWD~L3Q?t@HQfBi0h z_eisQApmGxnjxtN6meLJqg#g3j9Ek+!gvOA3OO7Ogf>8VpFFLu!T`Km_^K??_wdla zXLnqTp#lKULr5f4+xB>bV2CuxYoVuuVWa@3v)0yuLpVUUW}0?3sBXff>Q_*;2P|ct zpklwzZR`5$L!Rj-@pzIE6{-3nl3{ijt_c83U-S!S03|_|1L3| z0O0Y=`Gp5M?Py>d1Ia78Ea#0Q45 zOD0Vbb2NT-(b@7Z`w2j$o$^f+0KC1+4AR~MyxkqYG^qnX<4db79@LZVIN83io|4+$ z8*D|i(a(0shg=M^;JIGZDsYS+l z%Uw{kcdLaqdB!8;%h{IAtf><u;YD%>1hOk3E+H0J} z9zO<5yWJ{#symE9xqz@-ZHvkw&8GvjU8yzQk%F2q<`Zb)Hkp2bYUaHWsn|{gIJUKL zQDxy$79z6FKp}*!4kZ_=?z6_tM+ZPRBRST5g=k8EQTyAM1HK#$$QR9_Hr5j97P5ff zm@Cro99i(;HhfcOTcOLh<*7XhYRxrs1}`EIP9;B1-ER=vuMzLCUh$d@`D+SD%ctwh zK;~cTc&1Ar0vV#gjFsI9IKg)&Psj$J8nE}QGcVozW+~+YxN3kGPHxgP4QB`968^Bo z$x1F7Xe`odMvS4>(NVFASN0i-WbDh25CW!=%(i*ELWiCU^3CT^uz{&eW~xIGKpebn z9^XP2P{ygD90-WuS?05g#l?UA8wksK-8EPxLd-yd_t6Un9_szuGyxi@Q{X;m{9N{t zhv@$SGydeW2UJLG)y>KV5U^btZ?x1qaG26jf?ER*g!95s;Rpi8IxyCO4CX?jgG3GV z&cJ1X`6CeOjah{UVTiEKch5zp#0&7$PS7PgC-gB0swhQ2I}BvXaf7qpKqNGC*d%$B zprYm~wKH9BIH1}!2e8%^1*TnubDiCx#{>lbxkRdbk1**GH-^NH(xIP|hK@G#b!x$pO z(8bXZ!;~5t4@J9Q44Jitjl#By1u12)nsb3M>|lVUWEwrs4Xqn9%f9Wv;%anH(x-xA z3_}rHTbAM7A-j=XkKIKUJ547O$ywMgs{k%Ek=ZOIUIVqK#?V)41ux-Ee|{$VBn z+?{txb8AR{1ytg%PC6^SrZD>JkxChF^;_|w^)mOZ5EiiHZaSuu-FkKWA%%9fJ;D*X zWwL1a?CKd%0(`2P1v1>|l3rEWchP12`#b~P+?2rT%>V5K-)!!5XSfN(Wq{{fT93 zwdjVr@oDn?$_OpQZ={d4TcR#N??lZfK?9IrmwH?q)?6 zMTAH|iHq4<;6$HbYCR2W8TA(bZ>r={Rc6MGHx{6Mqx+_0os$Ao`vIvBTcbdJpnsPJ zTV0R=K_$@Yu;qqs%tCJKM8|1jK-K16p_CK{T<0K}iFCZ63E;rt8)1D==l!~hPKEk4 zf`~T_2C_LLuHqfqO;j>ak3hakXQ^n{MgTaIC-qNMMnMaz{^BE}oo_IZVy(_8o6TA`}nH7{o%1NNF_z5vS< za63UcuMc*P#_byJoR?F&D<)9h7x;2pvZ|ok2 zDLv``to48rPk40&3#}zh84D99$+QqJ@Hd@@XSm`)H=LRc>3uoKxOvf=+o*A%)=0J* zeU*XaYxyv+19BU7YD1Y1il_VaK;^x^T;l~wEzigGuXP?`P!9yNF27#`%DtJO_qUrM z20-!etCeK!xIn$VHQG+Cv!#K;EnvB^5DrC-yUnaASpQ}Pb{q4J z-?C7oh7Qfte|A4qzQq#f=a+(3`#X_50%$$2F69`5Iv~30RwP{zI@+qF9N|iv3DNEN zuR}va5!93S@^SveAzt((`$ups{#u*%Cj5A=VvVRcHBigFysP(+|^SLlD)Q#BN04Lt!Z z+4v6QL5<1{EP8~ht*(Zdy9@^$%s%kX7M5!89i=8Zwns~7K-3%WC0Bvda%(TI z%6Gg{_9jI;)r7%qqRgp3oiK`3!`RLyU&v47?)NMGU;LLzTe(mRRPylT4DtAolu4p@ zhJG!yx2DyA(hBriv(7F1FDy)DC;yhbmaWmRNR+a#)4t*55!$rJlO8UMa;ywf-`VQG zd6~SjMO6DKOPU{mSG7=?^G#%lx8EJT}oIB^qUFp3x4^lKtQEoZen>t@Rn$N&oH%U;^MU3zI=!9)1$PXCz&)?Ru_R@=;Q?` z_e{Rs!zqxE4Eyjt_0#&4tS4FPJt61g-*-^J;bFqslWgUl<8C6(5>J`0UY3MbLuPy9 zbXCYXuczmV{E5+ZxAL2n2J7}E7abC&V%T?*);Ej}krE~Htk(I3+Eg!UTOh8E2wv-=ZZ+ z2-}Tt!>`+(3g@9UMazkZmnTWf#}TycKhFY3FLx0y zswZD$EBm4pd=1THu-Oj|@l?X5ZX1T!k>)sLh^BB`IcmWRWSEXBOQ779NnqUxQq z7pT08dc5-DQ!QhE&S#L3S6*Hddam&RQSIkRB&Rf;%?jVEPpdhk@3T{TqZ@olXCTY$6?r~%gTzIvS&9z={IdTT@U9^dgCaP z;EDX>{gG?(DoNyN&T@g)73&w6!%+~cpV99Z|0~+kynM)Dn11+l%0XX$`6++gzhC&$ zRpQt3m@GmIw6>KKLk}GbC`0 zG^Eickhazpf>4o0wjLvXf1tA!S8U6VrFpI0Z(P@pFxK9nXh~j?oCtR5nkC9$2X_=py5##eVk$ySL3@zVYQq^m2=3I zDoS`O!BVhl;To)1cSWd!=adB!R!2sgFU64NwEezZL_+DKiR5S8e7gvc;jV9g7I&)V zdqU8&8unM5lBF&!Q`7lcmwU{cA{|TR)yYo&5|hmPgb4cz~&w1cDM{i)gvD zU+*NC$37*0j+`sN*%HfscsSdoD-ZIX&Rd?U<;{b9BnOGTrY4t&b8!lGM!t851g5^P~(symJ7c$J8*?!)AI)HFy zg9~KvDch3w_r%zWOlc)}$mpNOmQDS@J8Jx`!x>@^r1G^Lnerf#_Z(fbF(kPoFQ{%6^8bwdo7t6FuOw3&YuaYJ1M%`G5K|NKPPamErqW9+IC`L z2N|x0rs>Qg!~v-HGx@%nU+f`NX|Nu|37n@ZNW#;jhT2hQu$~nX7cJlVc$V(O+q}fJ zF+_LBjp|KTG&6S`fIZ}oxSre!Am-3s=zdu;a#ycc`Ccw~;*yLp9u zz}oQ(UxPTceRmK6%;2P*0Qf)ob%q)*T}sP@oVZ&z+|Mj~_28rKq-%e2$5 zoe>DU+s!`5LK;KuyZ9eWXFgEvVX)p(SSnL-29T`<%>B(DO2xi}CurU0DG4VOWwY

oYIzSyh{iiN^y?}E z!Ws`W>yy*5sC=IGU~(|1eBvv*Nb68KMtVBDtWB%+6Dy9-`$8Q3#gB1pm(@rVEA!_A z9=o!^7=f=ge0YzoY;&b7H(gZGY3@tXW!+N|xr7<3uQk_re|#)|B^U|&{l>XJoNuCs z(cgWe#SLE^^OwkiW7}e@6>cy_%d3rJ3(ZTEOLlY${hH^ExQU+k{_Y;_$p`3y@^BWz zeRSt1&q~wdPqe`0N?h#G*WlN#*>Aa`CBssl`+n@bC3k6*MwPRe8 zv|fEBlA#YvipY<8Nknrv@5$jNuif4j`OAQ1#itl2r2BA4*CfTDyx)g^jf0j@?pGVr zK_ip5Ch0iHSVUE;8NYS>A>&a- zp+A065Aq{3%h!6ebEq-PoMXVDCA>Lo2!e1RMaHLP7_HYam5Fzw*Gw@E6_C@`hM>{$ zY3KL%(kSHOTYI{?snvK{2ecq)EC~8(twJb?+9Nb5SSEy2h{OUi^Alty&#^@XMC8}6 zU*m0`gl+4nQ!&)1%6i9-lc=YAWchx0HvWq@M%0ukVq*LMXu9fvsJf>OBA}Ea-5{Mx zcL;)Xcb9Z`BT~{J-Q6XzbO=bNq%7SaEFdXT-@W_(zW<(`GiT)If5$yft}alM~*`LnpGD2Zg0R_%<&A*o4~XD_S;-ZcH;j_p0gPL-PGddC`pd!DVZ zL|rg2;q7kOxxq&4mO{aEgE+{aIUn?(ZuQk4Wq$qYu@yMUpr(~Nzs}hg*-sOAm7d@W zViK)6BLeXV+vB%ZcFRZpsY#_jxIJHS@ziWpXA?0xkCP$A#I!rA^^|^^5UW2QAYRt< z)N@2|L$O;nlvtTT5BKmfsnPOJ_>HX?~#U;!25I`XeB>*`S*fUWefR;lW zCI2A^1PflN%dQ8ff`$ZjP6VETI=(SoZ(oAIpfXt+2~;jn?a_dHKfnLs4`d@K+ShKk z9~@I00|cEI8exb6!Sq)&haoZ&@C5xx2z>y1 zwR6oJ9)W;FpPmW>blR|YSO@o>E7GF#WQwRG-r4mH!x;kDW@b4~4w&9=d7j=3pCB{! zlfqy&cvm_b-QhE3H6&sjA)5;GYTx_r9X&Yo)zJBF5|G%g*S}*P5GcB|siK4S_IO%| zut0_pIsIBl0us9B%Zg_K?I6Pi*l9*1NUXBryafg9)pR=glLG7|hkGChr&B9G(gK!c-*#K}*e+mGb(C_tArww=L~ zPM}NIPM1=HZn-p|)wdSr3jOKY>xYu%7?!9&sU={tHF3Vufli-`xR<%1-L1!WgTc@e zdyC@&c*tA7T51gDY5Mv$7ZLedd(dVNZf}%0paY(~lF)lA&*C&!6aw>Q_D3PBD3Czr z#$6CSnCx4Nk4Vn}CKJ5Dn`p4Cw;=bLzsteBa2ImNM+GZf4iiNBb*S>fsMCrjIJ=zd z7-?86?@6kp;as~08-P1f0G-epAOArxLn}n989ZpAAf4u~i5VW$pZUQB>96TdZ9hT> zPtIp9BBc=L$8vo_NGbHKIypxQ1~Jwd~QG=Z)h7*%0fAsr7TE2G`uG zQ@Jo0Mk!%VG+`__j3m%GQB*jSs=KL;(6gs^7H@Oz3-DWe#=v-0fU7)Qu{DQAb%66MH?tE9Y!#A^rxCi z4`HCkrI{UM*akHqWM~N>d1D7(0ONkt_b=c9LO0Z`;s_~0+6HNb?@{5xckk4!k-C6I z=Y-$vM=J0FV1(?soE<3#Uu)ejD2Cg))y*{kmq8y}3w>2LUx5?DM$%DF?LT;0(`a?LEu=^C_bDLoE=!q&!v>c>D9k$f_q`y%?+g z*9NbV>E$1-jd0-fNyx~&CB8o81Im)LS0xfqguX;C*>6lmf$Ku>Q2qJpCB~C1pq$>1 zcXmklfY39mFN69C`K7*F9~1OQ%&zM=q%oZ?W6C#pfo{~Ryn-qFMB99duV0ch_q zwOs^e`x#smo(7?j9lil@$H~|3C`baqoE#4N+n>4Nj;A_P5y8T`va7UiAVBjSfTI(c z4dkF~()$BY0fBhPf9G`QB|YT}M&~&G^!nN=DhRZ!#bqzxxLpCVTA8)Oauk6RWcBN2 z{?E1LMaM#T2Iz&PTPzjW0`==oj_teOfD%3WeB_f}7DNF09$x(Nh0DyHbXI@BWlI~X zb_n1kOevcwc8T3){MT6R@Pp(lJPtD7 z(Gf&oo8>t6>^|uraYP1l-+hCO2dDIBV^$On4pP69a8ZMShimS85P^Y<9y2NvPZ0^l zJ2y|Re$c}JC#8gsi0DohEeQDSY++(`@icYz18$mrh-C0v8}S zM4odEwH;Ca2`5g)Ru#D516-3Ci~@Q|B{LL;Ul?4sHrBxR`tv6x1HkwYa2z+|J6ivj z<>uA)*RtRwSowR`hz0hO=;fK|qJ!@$O0z5dzN;bdA>a-y2CkZ>jS2duAsriTa90iI z3%elGr4A>|RX-Fk-Fl{%3AUijx8Y9^A_xSv9&PpvpgpkL3!Yq`L%|9M<6{Qcc`x&@5Jpstqj1hEqg zqWSz>;eT%RC&}pF!!z&NqXAXe0>?$ir$*9xVe`K&c+_wd53E3h6LOZhTVVC9X(bbD zH;RF;1fL20MimD5YFs>Cs|2?uwf2oajs0Tqy=4OUbyw?duU)kxcS+~Ut6&QK1i2MVuaw;b#_fBW#U zqE;$TbUH9Bd*>Zj%0tPDzgjY=a6Z7pKhEq3*NA5fy{Y1yOypGyl1#@sZ+21YO^yCI8|n5?o!R@s+9VZ z04;!FDz?2>(&yt{;Fup%x~h7?wk$-pYG$+$I5+2nkniqhWO;e&Cr7`U_y_Oofw^CI zg#ICYwT~za-8;IiUc}z3zAW+qx8E!Lt+&Zcc05xn1Vf}&pKAvERIa_^I-B@*Hahb0 zNSylQ33E3GdwUk}h>B(aZ2eA_*qc}TrrfN_?i=MBald1F5$%SrQsjSIDYWc|UlV(; z?*+`Z@Hbd*2j$+rSN{tS~d7GV4PZn28L1~NNqi# z5Ql>*UCJ*YyEi;MALM}1+7q#j>`<@#GEIaC{zFuC@EyZ!KtP=oJ-W+F4EM>BXs1(y zu1~{7AvBt7ID#MY%g`+lZLpC9Ga;x?VX%c3PFkH$aTN+`xu{<=69k{Xk=M+VJqsGOBQZ03p`31POGpvy86FM6^Ok|M9=1D!Y z2%%c^ca{{vQl;_3{T%LNwU5tpkC&>$bpGzYFIV(Dv)NV=5g1f2J%=irFi>Qx zRm_y9I3Bq_Poh_)R6WZj=&vcRB8rYx!;e=-YCDnV$%0EwEfNA;0ff}{MedgC z$zd$w%I9eA-)L2WhHcR$Zn8TRm61LaCrt(aq74W6DRb~#=OL$alY0A~pU$kZ{rWM@ z^}5XX-v+I&UPd+bGjiOupd=##_`T-lawtx>GiAf))PrDlDnQx=0WST@I@mhiMWK(w9I z|4(*%j@@QalB1j_>YEtx@+7PNuiBv#?{LG5i93Hg&>GHZv&?x4ljLq|#O$dlSWde} zI%U&@6>f3cs5QT9ey^W8$}aKIyF9*K)BcWt#S62u#iY>4Urs8Rj{Ki%d$ERWtkq^V zm*}+)2PM~^i{`V1Iw8MknjB^0BUQP95IT_$f>c>GP;Vo*i%sXvj`95pGG+Z`hu~sK z=UA`J#g*7;4Z*w?PqC{Cw>d0^)syX6ZV+_oHx$qtK+Xd`{*0=mA;&uax^>K);ib$Q z3lv0zlb`ZSXu&>h2JDPN3MxIs{-n+Lm(Bo|{%!`NW4O&t+(sz9skxLj3a)`7_6vT& z*Va8d{6a@wGU1XAO8mp|9OXd+!kgg}g_RzLf5sR$^KGi-Yw*IE=BA~wdc(^w3}P+y zdfz=8@-9yvu6^3Qy%w$tk-dx(tBRW$>UW7ybevVG+&;!yeE8>BHmmC&auWy~>QZ#a z9JmmX@M!d5JD%reZK}-Or(w%Ue97L4oM#0KI)2MW06k{&q~ArcZH{8={hNFBbECC; zMa1z1ChEx_%auLSph~ySKaZ0l0)9K+_BvsCE9>{2A6oAablS(Y>Q;1ox`T2zVfh>D z!U4Ye*}hJg&Gc%MIJfyp292a0lY5P%&1Bzx!3O6YQMjBM!oz~E|8DF;PF{6Qj&YA1 z+xc7lDr5ARayWfh{o`zo{>@`4u{^L{#kNA2i?nOdc5DJ!>)^`lU=6KF<=4CRo?Bms z!+AZO*mrl2I?|U|FJL@!AK^ra-ElJ6$wI!Rvz=(zjhVMw@q6VG*amcyj5`F#O|E*D&zQ7F6%$4&OjUFIM_TU3smLU((^%0e-G6WQ`;p-I=*<&@9;Jmm~*HCxfA6 z@MuKVbvF$EQ(OovePfFXLpeE#qrR{kG-Rnk_;=Zu=lM4!)b|%w*E2i5JC;aC=9ab1 zw^4V5?%s2bicZ}F?0Q(Mdz0sr0p@ywE`;u_-Ihx(S5r=ZvD21PEr0z=A(b-dx;Q-z z_xR~@DzdQWM>^p})2j&_dfWer6rOj-LMUe@%s8al&1ZmWH3+VEZKyIl*W|JL_V?ND zR!&n>cvxTDkCvN|Z)EX6=+_f7{K4?aMvu()4@-~*NV?8?pkMaDrhI~ zY0oQ4z_sn{zZa|iluMb@E@Qe8Ca`_o-c48 zjm?(a3Eh3Vc6e=<;Pc2Wb4wm$;kq7qLO1r*tjRrGrSy6vj~WA6ZU?mKae}^JXM2rR$kuI0vqlKF>FDd}9Ta1~ z2G}&J!3?y9ub=b9i*!3%)EAW>;|qFC;d4sK>)($36N2 z+q0RL5@BCLV%)rHW3FES5%u_Xh?jak{+hoc;~}f5ZTQiT1;q@^QCz7OwX-|H%EX#f zW2vYE3PQ)=i=8e-!iau{Ev!s73f0zUCTO}$%|MwMREn){4Gu|j^Ip%W=J9mHO(c)Y z5jsw^2cn!7AfSkh?-*Z{Gko7uDv1p~2T1@3S_Ewv~)ILoyzN z;}S;6wjL1;60Fs&YhhV>C{zlNb}<+MN2Y=kUKD#>qNO5vgN=+QJBMyiq}RQ=d<7^r zlinxWGu91XIASt>dzC zLKX0TmlHZOina9Xft1G}z{E8*8dz+nJ5Nsb7PJSO+G57z+`#ydt%zLw9^>ND(y`?UJHJt2G zsb{!HqGam9rXu*y<9jSav}C^4P?>C-Bz4+=VL_zb7uAAqgySZV5}7_+|`o4G_91{xVE6AgU(!x__Ws*~&fZ&`9N<9r5k&mwW$Q+pZM&V-2>~&8GHoIa;+# zVs9?x`S^>X5||q~AZcnX&uGwv!c$7y#ySX&g8IO3#xg4;pEMCq8l7Y)#Yo1| z@V`SoI}yG80vr7O7@YALn?=|w~1r=zc|1bEf3Z(ESG zxxdwXJ~YT2jWgDH(uQwe`l}!Fdj&%2k@W~vH|r_zvTADR+$cOKxrx-eRx`(R{7;+S zj+ugIY1YU|^84b1zb4phK7T~)$f}QiTQ2Ip1jO%u(=G+lTphyn+fz)`xms7l|aV}^WNEF zc<{}hUdUcBjBtWbOu9UTtz*NL#>*&D0nmx3@U`6W(2$ll~2xQVPEIxo8Hy21}$Z$ z!XR;ipEQuR0w&5G%mnj)rHC2NTRI+Xq8Mv@>UG3ie?fKYi^<{~kNAMq)ZP4jY<)50 z5Fs5FW_m}K=PT8M^)}fNK@*wuKn?3ui1pSN86y*lda4Z|B)g;K*wZm-3&Db4_}|;x zjzb1ROU{6C{j`y5NNi^>hr9I3Dkoo;9XTI=E#DyZ6_Q`T7rOt+M&gNxxhKxelr2KLod z4*|05tJDCW;A`_MBfT!hKjzVl2b~|cuBHO29aN#;_ z1e4g=R|2_kI*+}zrtn0lMEN|i;L%jKq6!e(6g|;}f{Wo36oM30Px`VB^27-v$F&c> z7=rjC&R=W8(g2%V*AfN$($9P<_8WK6?g>UUAv z0R(bV%Q(lNn&&VoPig3yt+7WM!8V=Ft?!H3vX#ra82czwT?El!t%>^ZtHMrX+|~`n zn1<0*vC#&n!GXms;2m{!HIXs)5r9^v?l3A;0$6$7nhD&oO%Q5;GyPxb%%yk0l73V< zlt8z)6U3c4HX=@E`~{Cg(89{k&XyODopd_i1_)Y-Xr9PHmk%7x^zzd@0!2QS%fcs6 zt>*UqJG~{;{ze3!zbp!lz*1%w`26O9tke8VlZaE)q6Mr~Gt*iFjau#!m>NEa4_(2>Y zJ7Mi!e7|E_)akpF-+V~%@Zr(*@ zXeXU=CcNE`xt0K*f0qhUp12IJGHNn2fmSR}HdVejPIuE!Nn$1ny+A8}Z+)i+Kb~K= zR_g=ROTXdeOSI=fiH6l1iPzi-TDCEP*cIw>)C$G78ab-8Yd>62`KA?noEPPbIs@*j z)vMKQ$+EyFhg9Ctr4EgW@IQgHckZu-Xz3LyOTM-l>@F9MQCiY4o3cqtV-?-!V$V=o zkzr1yk`1rvno4foaCRwHB?~SyEN$w}YFzfpmd(4GMn|UmnnKceH9vZCoR~_|*mj;M z<@;gZaB2Qe2+)gKdi+_qG5hAn`RDb?HFkqh>kc3Wr6_7*r%1Py+H`M=wL zy0O0(JBdoQ7DZzUbsKge_H-5G9HCbWj@IGZ1f}h|)LOKG7*V8tz#kLD=?F$=*_j&F z1~u2+jsw(&!>LW8mEo7T`mn z4W(x{^-pYp0~_kLMke8)YUZGj210GBHZrO?x%N&~Fxu((BJnnH7K=K|GMC!uD+of} zQU0P;kwvS<3f;*vfAav&gJ7y3cm_TqszKDm@)CSR^hVWbwhk@*wILhMBX7%t?P+@7 zrPcH}^$ql)?|zIlJwDUoROG+2*#Z^5&;%wr)8u$sUB9j>M7q{Gn_K6iQ&1wXxMNWd zjpE;lEL`qzBOyQ^>EK-u*ck{We*BgkIP7)s2^j zNrDFRyAVKy@awp_w#uvXNB&GvDW2PQL#rl}V{goBEs16r39E<@U115k4P@+Z+M@{7 zY@k!O+ogH6KHtJ|qQ8zTOgHDNi|46yo6p&7Zg8URtLM=;3r)Mm`Fu43G4qtkNI2tf z$UF@g66DInnPU)8Y!<4Ohe2Sd?n!Q}Kx8q1L98O z+GqGj5AUvxTtZ|l=+0x;-2E4t+mAUW$N5jZC&seUEvI=2ewd8>y+FH9t2WSa#KS`$ zNBKeZratA6;&x-EI2*C1&AP_++;* z?NR6_w!l&9(&yxU(n(zf6Amo|X#ELG#x#`4HgmGY^UA!?H!bCU4kOk<4%yc1N|-*3 z9{&s#TX<%*Pg13d16I-<>owk8xml|d3+tRx>EW5zrbrbp&VF12#m3g^x^srM+0|(E z&9a5lS3l=T7b_@zOSqWG%&yx$R(`&t{7^Uz+5LG3h($YFEh?-~_Cw?j3Tz>1M!N$= z&QBs11_zL5u!tl24RML63drbRMfo#u$;k45-%gP~rk zMzgNXbW;}{=`u~+0{jn=G^UdA`W26(2t8UA`%SK9ds-ML49aWmGKt=3ja@w3QYC-K zv`CzNx(6w2hI}sG?hA*EG)@C=A1B6cs2pdQ-HsKbcB^qH@40Mzyf@2ObB&M+6xHqL zJx~%fueEw!haFpIQ3W_rk_PN>gE%AGuqg$l0|S~nZ*nbC+l z*hr#PbdETE^3 z%)XQDSSTQ(NyBqoaKC!Y9bPSVo9>rx)4yxBAi6ySe;W^aoU;c=3#DkaTwGbi(Y zKlyB%=B4|q`9LKRmsei|i1q`D82F#pD`JoyEs)9$)D!n3APx{(Uq8sP7@~<@$af}w zi!-kgc+WVQ=A#_-@pIR&v>mw=^;l9hy}#Jy_4mrbMn7q{!r#9$t^T`)O0{<)`khfk z_Opvw;P0VlPMZ9QFO#~mYbdG3@JVQcw33rvay&6lP2{rA(Vs3GUJ{?X;1eMpTD~*fGI#<4lfOU2QHP#si=wLp z(8eWVQ|5*Wp$Lk;?nhH;QDvO%PXEW{?zJWK#iV-NLXN6F*oyk6XR9s(Nm+jbonT z)RB2E3zea52-!PwF`6`1>8TwiS13~yp)}J8;tRiIeLO+ZbF(&devJaU+XoU1eWZqy$$zAi3;Js(5^_OM`iS7!$@ z;@xqlB5SsZ#Dc3mA}rqVewq0@p&q9(K(vB$fJ%fVG+vW!%GgdAD-!ki6Z=_06sJg! zO|cC`yI|I)KTK>(*TXr@Xsou;sp&L-QxGP&ieCj;sJQ4WQWPV38)IgSXYtB?ARFE)!F0z8rb z9lK{1$6tg7zR|`;mcx5h&afTlueN0o-W7BBmQFtJ+hqVnU+u5J8Whj3i~-mF0VnoD z%X6;(L-BuHG+qj_gXX5zBNzNJf;E^4C@u1IkTz1!#LQ;@|Sa#3kmy5jEoOBJZlo~wZj znOw*adT|Q zy#eVXOl+O+SZEQ)$%vnE0_A$974bSbakHv(NB1cxiru@i5#fXMJs&(iUbq6mo+kO@ zFbF=}bX`k+_unbvyML8)z+j8|WbaogK2H(^DM)Soe91Nm5*%FUsK|_#YAqp2M1u76 zTz`u>Mu`aas==`3VN-e2JMo?|I87&lqn)tl5A0;s9U>!4cb6CNSB^nurhCEj;ilN< z^JUpoQh_krvjwUC(*Cbw6QNOaO#Vuow>6g`;)BeK{EY&%$}J5imZZDSzPLfdNq3=@ zjSXTAuG??1O@T)&N=f= z9g*^n-RIHaG1{P@l>CV?oB3q1H)P^>@BsFF!iFZw>u= z8`Sr`!*92T@4Itxkw-6}E(et5Khw;Ze!5^*p&EawzgMVSVCH%yfqT=LBilFFU#38Y35p>8+qK~NC%Nc#4n&L zV{ubr8I&BZal*jN3wPq= zRoi-7*1qVSRZHD8L(;UZkT^9jbIhHBV2rrcwn?$c?F2nS{>FrCU&Y6W<7Y7)Rb2WR z3n|oGLfY1RY-O({t+vgIRc>~E#5{|+tK#w_k*b!m!WFY7w3~fsZqBGv(|cLN^;0!z zceXB0u_Y*P@vIcZU!Av);(_efZrM-9&pRVd<^L8wWIvwC#wcR{+>DM?6?z+MRvV!{ zic4jR^)@Kj0ZJ5Jhp7_9O^n5m%d@XY@}cf|N(G*fbk}Z&?dSK^v(o(W(#PE~>?+Jm zb?W8uf69_W3p~#ca;dYP61~onI``nz@!l&wmc=A&L283`Giz=$5%H0diP$p=|Z++{&{Fx z;k4=Q#Qtkt&x&<}jF3TMZl}CJiSGLTZpoM*-WA@9xHDB8>X}6r4t(lH)7% z3;q^eXi;tcAKX1bpzG|F&j@JayIaoDd%(fwLgb6I8zvT;;lNk%nX(P@HuLrvq(+Er znvNnH3%`vdvstZQh8a}`;z3kWk$C^uUe*?fJgD0+8&tcT)aaMrkEhgVwify*mUn#t z0o^Wn@KFt6t;TU#Tx{2S6rq>5Oh?Rlm*=!G>7bj*e0EyU-|sSk&s*i==Nj7Twe7qt z@HW3xd_g!6T{%w$*=gt=zjpD7`K6UmhLRpQuo*;$)$yAms{+`@tdv(Kg$!QM8pnUe zWmu4jDWz1HEq6H1)|4Z(CdA|U;S?-te}!NC?^Ghg3FkN8qF&N(94z?^J8?34-zZgo zyRM&R@?~4*jw%&{JK4MoAp(kkw$Iq7gBgV~YJz?umb*KD4>S}Bb%(uRUi0FRpZKM& zM|stLni%vbJF7~1k5z*;@OP-qKimg2rV@!Gpr#6ij@N@WZu!A_B|!2c@TPHf5r+wqkW| zx^TN_8w1=ik0UbIOBJf2C7NWe^?uxH71FkOnlVhrJGQcT)+n25Qp5t%O`U;cXGn_4Bg$6Ch#U|K^E^84YzHYHtEvc|PkbEQ+1y$2BQ z0Aj4Tn+8z3SFO@;+5e^mF!I~WX3n)$i2}6!Myc9|>EcuoAcc1^TQPWbylM{6F3Hio zd^dIb0U%g;RIYJyENg@kHvx!TaHQa zScmO-7M*6YxxC7XT-{X0IsEo!Ooxr6Eb-&hFO|_0_X;etG!AYu)Z%=51Y6G`xg516 z*i=~!QGY^oMRN=nzr37i?e`Lgl)MAQ7hM{4mQ2jRN-yH(a?K&q6ZEv*UrI`-vd z{kbB`ENtVq1z_#o-86p!k}}T=SS!FmN1pvP*AHlD0UFE}YI=Z)*p?n4<21JY>%9`Y z*sye=>yaHz+hfg_Rykeg0XKmeySa!Tu|^^)YVp4ouKPt&OSS6vTX6EDomE?6jodh| zJy3mk*F`Y?P6z6=X+_OYWGRv!Tz|LI7_rSj38}Z)UFLJajn~!D3mmp{!8NZYEUGxf zt%!bsF-@7ETk+Mxx#9if{zTy+4Z5-H+DUF}{BX}V_6Th<8nrK&aoLS?4DQgW=q-jv zd&3hS7w4k7Gxj((1(8Bzo@|8{^}?NJ^qB_#*dL1380Pff7*rA=xo#N=l&2jQGxMtW zC%v1a%I+0v<3*+C>Q@_ow}g&UpTGBX=<;ynB>f6J__I)X&~-Z_Ym~ z@PKMhGPm0YKs5mo5{>1%3Z&1KF1)`vf-8`G9z``Us%--15PM|SaN9>gCFoofi*djl z)rRcHrqbtXOq?z&3Rz47H+%JyihAVuuaxJn1zkUFOeJ7z6t-){a*|4N6jV3|PSS-T z$x5la(~&O@JJ}6?v5`_Wc@x$rFQu*)*g{~!w`u+!Z>E1Scw;>gdoDzSrv_s%-0yeE)R1Iqv`Nb$Y7XEEkASc24Bw^uo_Z(eu{mqTmrK46v{E_G2w z(>^SZ@A4TeY1CT_YIt?}qZ{Shw!84ymp+G*yLg;Zwly(-oVgM-sqJrb(`ak5HJ`ci zeYcdXH!Cc^;BjdOeW1*mlD>EOR0FeFY`j;Q^7v7a7X|0*(Uu1bZ_mjF;+|K{zG_jUx-3>#Q84I>`!O-hSa+P7zW06x973)7Y}+QB=7Lp z{A4R$_P6oPIzMZxo_m`Ih6VZQE@XJnZ6`3}6ApFj82l-H?!7I565RQoxLUVlgb#6R zE%>cCwMM>a4;3MM)ao@!^MoZt?0%|`I~_GmK%1}J+@)2U_0@+VF8q`Pr?#JKBA#Nu zrM@5NX5$LK`;9fA{RFRsG|Abwp0p0Xf#t5^Xes>u34{dQH-LUoFTq*XVBih)^JJT+ z=vAin4)&z@%@u8Vmnr9Jm=dVYyH#nNPiy`di1TpvljgfPm4}C%D~%C-rG3+sIL?v( z5@P}lSMEZSa^h;g_m@L9#owD}lYwYJQb%)^cm$oS`RouF@v@;Xg}Y?vr#$r%`9Rt4>KF zZr^p0Db9nLYQ-J1|E)#~IoQ@sXV7Lzuy{}<>convyB00>7*4Q!v1LQ;i;x7pDQv3g zo0GaiWPqTjuC?Q7kyzd!Ml_wA((^h&67CUXVN4%amj?ljrwkCeTYcfs%9tZ`Wt&_5 zE?;adl0}ld*(PE^4~!a~dQq`*do4x}4gh`-E5C<~fvo9BK~y&Z%B?-qt6bUu-_ z=Uv;00^mIWuMce#0UyFhvi5_Se`WxwKLAtrLt0y)L#v3zz(W+{&`lfa894?>?uz3A zvKC3YiFmm`eXEZ@VEF6v;;Z1{%Zv>h>T`Jp$l3~K3INp<7$7r)%<6y%I~-Y<7Eb%+ zz?>9ama=2>0M=}5CVBzoF+lm=nF8hvLFbqk(ck-^s1Fm5 zhSU!DXbsG#nB#l|0vNeA(v>spJ*`QDoiK9pZxKmW?mx zykXMys+2x#IvUa!7n8VYlWI~WY`%`mU*n-O0A*6}^3=Dd7=S`wQ$KNnjIz&@SL(B) zX|)TP!6K07V+QAHzH9rw&(|T=w>KJqs(ir58knmY(r(xCI!9}PCKKACdNp15&DD%) zx4RA#_d7u<-_9RrJUxogw#xwxdc6g6lR~W>u^rbDdZ<9_|BB)$B6t z8V}3?=tD6~WZh=LylQ1#e8RB>3L&)BYXAF(vBtxG0163v@CvRp2(R-vbS++Sf*f+p zJ5cDbi`F!Wn!)HK&UChH7R;(v3e@XJTcDThjeY$ttqjUl%FiTNO(_&*$#9d_OG;^@({dlNGm2^A+OYXJ8@zYHx`r!aVWN+an|X z$4!yK>&2-B>%`|W+o?x)D0=3-ABpXosAknj-0JLciD0jlFUOXSB7$rjHsUe`(8COy zhd%jS%m03Dn`+n`UA5$!*f#W}WZ@FJa14<#FvpuY)Lh0f{isTyGjh?kbNAe82-9;YC|(Ux!i#pwX4LFz#KpPX&mR2`<`@vDCXAR0&#te>Pm8&OJc} zwE=NwGwGoPAclT6Y!094x}tMWU}oKSr;T0s43O8-nL3PozxNNc_bqP$wsu_(1w6VV zcRHMw_#%NCnp1~Z%kd)9fLH^$v!+*s7KD<3hVVg40bs6@ao^qcgg9Xm5YvYCcyP*; z$x|mkdd@eBwLlg|_?3j{o_ns4-_g5r(+vE(psafsOxi@$!2;gbDKPcdudCsq_gHU= zutF-pV^u^#c0?daZRN~g0Z^LcI=IAN zh|3Z6-3#{7^^<^a2bs(R=e|uG`s%QpcfT8C5c#BMw{`RYl;q8Gw{x5eXR+3pdv%WZ z_;Q{LUwOrxk7f3bUH{th_A&?<1p(&GhnTUSlvhAwuIbvU*{<)=AG%Jo3u6#OPTFRU zfLi69=M#OkomEtv-<$6CWz10Tpj)xmTTXI;AZUJA$EE;5YTyc!U>kI6nwBp>JRr2@ zs%1T6gS|O&DKwHE`zAEYX8O25*02xKHJLg9k;*C4ZT}vDGv27)5b1% zWKEb*sO0Rjg!C@%Q`V|029q$Vp>xP>T|uwCGa3up^X`>PTgDQa`f6`W@vNyeRM7=P zRmtd58eZA>b1oxN(Wpeu5i`mTQA%+u*WCJ>hlvv>Vb@n-kLeAr2sE6YZqDaEt@o!J zCCOxY(zhmA@dcOb-)!6DjM}IRIQ|*W^u1i{VvC8*i`+XvJRiiJ& zWdHjZ%k&Uxj+9S)gCE^Prv=mfZtnK0ztl+X%o9Yui#gfY13hCcM>u zDR@X`v;oq#)-(Na5l(Ga%)^p$d`?clh}7Q z&O@~fW?2XP9OW~?6QX09Xr%MJLVE?HQ(GdE|MM>K37}WJs8Wp;t}h1;OBc&}%NfvvQ4B)D8_NH@v-tF?Fj@HUgHFYQ7h%)*Zc zvHiYz)Sf9s!lqiI;vprlOH|M?S|>Vw*SqlEH$lhAFN^cvJj3}hC&7}C`t_KE1p&@+ zzKnxFMTAaT7REU=l`3YuJxhPtWrMI;c-MsE+epQtu_m5z4GCXou6K#yT(3rkGhv^j z_1meT=@Hu9&ux#sd*kk&GmVb5sW!H3)tR!4kKDhp4^)bY)A3O*B~v9U$0gknXsc{s z7Cia>@$%(iPy7r$Rpnd}UGF`csbqXFf8#q`6=SGG;VFMg6!G?{Z%>LZ;>j7Aupkto zU-Cr;+eGewy4YugH)ol-7Xx3LV*wX(VSZ{ zdslaSPvz>+aE6CBHqtry$q$J>a6A#=&k-EN<2m`)Bg*pvMbn+97QZf+DERWMTQk!( ziKF$?$^1m`(rQc@<#LE?sfWc6e2-Bd+;^kH?P!j-9j9e^I|`Dn?U{D1U*3%ZhX{TB zxmpW3)|qI@`pM~ke%T1odrG`g(8(FB!or%>uUoDC^-tKuuiekmgIpfQTmu;aoDp%f z*FqA~b~m08Mli)n8EL!A)LLhpWMQhh%Qe~uecSjKRCVKPw2HR++niK&ur=CM&VVJv zFhi5)NW>fjo1*Yj3GvCV(k(2Ib`+(N@ z&cjqlzLs_mPBXK!V(%2tMxSNh4Tyk_zRgzb61D4Me!CW4&S8c<|Hso&22{B$5k!zy zO6f*P5$RTuZs`UAk?sZoY3Y_05ReAxEjwlX7!9p=Qpc^9*H!^okrx)f0n82k^t20Ll_im{=pjs+|GK>h8328`pPdce zi)$lZ9zp&mqm|aN;CGnkfJ*d0Js1OS92cF3?}I~#kTOBw9d?-Ff|N?1@fyD4Ui(+N zq)D*#gBp9+2!>CyBAtzaCEAIf-NFYHw@c-eVPTywYvXhuy7~$5?{}gbO60dDKwx2v zZaO_M#oewZszmr=DBzx_<7X^v!FpFG`f9&XCkuJYXCy2v0PxTfE zGXQv=Al4FKVx~Lk>dhLy>|XoKkcaqRA!P-B?O?$d3(S=4BjcV_~f*-FKS`u`|KsQd2W zvw)*`4iHHJ2IKB?2K@uZ z^uRfnJJF3IPY$7FRaGF>%t?5n?k&;jBfCL77>mJJt>0lAjAd@Z;E0H>2{HJz`p|5U zgaF28u!p`$+@ZSa!Pw5em->BYw}HcSV`z)Qi|P@#i@Yai`10+G z{W6O{hB$0eULc^^=3Dimjxs-b*(N+04g3Tc%1+lz+(}grW~exK#SsuE3Wt>?lH;z@xuT@GYk@(UVk?85S!3J^jf63hni(Jg>6!n`+39B7_*FEo6G_04i z&U6!q3q661rTr|%KObG7=(MTWuJ|WswbBw58GPu!kooUsF z63CFZYW3^`By#@J(|n-6998FPbePBSj+#Fhz|6W<7+z#ov~%A^=p1$RjEznEIvav*eB>WYom4qzr$3>Dy`0q!R1pvC-HxFUGH_t zlF$KEk{BB(dYu51ESy#-e-*t|_h$zi`srrKBFJ?dZ=fH6z>vFKQ)*QMh}uFnBIzjf zVIx&}*~UMULxpX_-Eod?8bxRfyU=9L{kX&%l0YsC&6qo|1xP%qI8Bv-U8}}z>d}Ft zwb&C6+B-qKKXGCt5(aLCkW{?qe1Z)fj}yhMD)>QKZXO*VuW7skYnl5rdld<=@FgdP z5Cp=e;Hii!?<0t6LLCqDPh^-Fzp3^1K46~EY3#ok3g0zp@`l|ND;nF_B@PE=k&@Nq zzZg=jQXhE$Q7|uV?KzHBXpb}gttw1wY42HgzvkkB$VbQx;)v^JK4Vd`0r@<3Zz?M{ql|>8k|Q{a&>u3WC z9Lw&Xdm=pGtX`_yGhPI0t8;W4_dk-COVbHBFhgpiMP#;rkzM3FegyfAnd_+T2aK#v zfInDES7ZUda<3g(8;!!LPQe+<%R$7FVn9$7bgdsCI>-2{&RAfo(^s=QyP%-i*>uK3 zRIyUk*z>3KVN%X!dBJgjqk_{(9Z+z_pBHs`$l$?>Ik?t*bNs*$5?)rF&?z}Xb-WE1 z8+EPT2P9COZQN!co>`LN1DMd(u?6+hCLdS{CmQUQyg=j^iNVtP*?VXx&Wl95iYuTz zT)h#=5^x2kR9&3N%A^BJv3|*@<24XXs^n%;yzg2;%ubcG*g_Q=Rc^YmJx&1ddga5O z#qI|Mlim*JBK5jC6YL^3TSbO{cjenRU+_iteK%N9eXraRx3l@cRTRs4QGbbnQf?(< z4=UdttNoPQ10V~p?k9=;Bjs6phG`m3214uH!)#Ci7sgxabcJN`z|{{IWwCRc59s)q z!D}$_IbhmdmEa$xBgRxG`jp4*Fw@t`d_ne{1TZEwp5D8Ot&$7)eS7Ui!8Tn=_>Z9{ z*#1PPfVe93mwPCpJFAZ9wPVBJ#Fwn~nP@%O6kz`4pemu74MDv3sCi7rADN+A-HcmD z_(|hEtbMYgI@wxWbdaLG)`SOVEJ1FGrn?il(+(7;(qt-GJB0~BnExSP4dmzWZ)LP? z#f>jAR89c?@8E#{AFV^tdT~HY_?}aKjC8F55sY~JWL9%fc^x3m54L{@`JdK85c(-i zD0o9yY|PNi1o?r4U4HWHKNc!cXtMZ9L7{YWXO{TKLVxe1iyWN6?{j_8-n4_03lrDz z^Q0=c2(Np&@MgMMHEA)#&C?ichs<3Fk=82&H{Zbaz_~y3YLl+%JpO%ka-R`(-=VYycy!*hWXwaP7uw=GBt($ zPd#GQmdOuJa;f8c+@`h|;7Y*ncw4BZy*~<9dM5-b_Uy?P)p|TJFf2{e@GQucLUfan zedNFgxDqz|V8Iu$=us~IJ|hm|JmJbmCCIk9!UGr_P!^DI`U@Xmg~^N#WVXVLsGS&w!|aD)`*OC~ zR$~1N>eFAnBReANLLST>_8u*L#2AVc2p1n6u{qNRR0ANqq5T9z!kp7T8Jz9H<-+`O)p>m z4JJKZ%Pn**s4^nt8#Yau0AD@%lPLXPI1lFvWYx`p0FuM%k^8%CjuPTQ(p~<68)r;& zgc%WNZQKss)Dq5p<71^U_JjCCAYO__$Nr1uRWs#C`;KR@J#EGZva|9BK^Ub?ji>p* zuGKhk>PrsvzNE{%8op&m`J6T7xzY7Jewg@>oP$6hR*2=KaY?S1r@Pi zUWr5`Vj@+GZJx^gPd16)7KLj{t~d@oLLMV3A#Yc0G`M^JI6gG0EN&uy=K%fl9zJ%| zI}FV<({;AWff`5J+lBd!T>(VX1Ib@Me&^80d!A$?$IQfRyY^b--0NgBEg`?yO@8Y^ z5pUV^+>w(8N0rYb%-&un3XTE|)+3QkbtYe2)3ul$QlLeKplo)l=F{JkiaGC8YF1c{ z+g|vD5`fA*OGp%-C=l%IhWN9IlzY+Vu1nY4^+@SnG~IF`!tXRf1+u4iVY~|40icseWoy~UK}eg7W>x^o#R70*@4WGvHZ4+-k)}|^aFOvkAVm| zT&ZtL%#9~hVlMC)FT_I>ui@tMS;@in8B4`+fm(hrbX$Y* zh+d=mb-{=e)6;S2%S|?xy%E3a%(Y$6SEt?gRM%3>i@gR)|`@xEm=sSB+PWA|A5t zwK9P9Dj`C(-0{a0@k9N^KaWh=th!b{e*gaMZv4A%UQ4NSKgyk{h$Xu;J-zyWa&yK+ zIMq9Q6CCZKD`mXCN$IRFDHFkjFr3uetA%rZd_rk;p0J=Yw=bo{aLpHf_Ti~4r}-mF ztFyf_)5qqIBAur7u6O6IeN~uMkRRWqOHHZu(+kH?rRPsGnKrdhOej2I`o;K2S+S$3 z+(`X94+8hm?1xa{1+{}tiEXu2DzwgEp}qk=RV4-P(My}x_~+aTqgV&t>`0xho;l=j zXYA{*k%}M694V~7XUA*Fs`KG+GyAW8Y|A5+63m`vUfj@0o?Q6A{<$N60JO;34t0ov zg^kLtG4z46!cTTlTvGTm?Hm!k!cWkS54%&3)X&M5^S%P*?mxmJRHZMOB7;P2jRGkZ z>-(FPNi`TW(S)YM>Sp@W#a6PSe*8A55GSD=Qd4_{7$mDKtsaUOig3SIebw+q)|y_- zThq2W(g%;YF7*nVczCbU0{`4lB%}xLmL6K8k8Cp_Lcb}Y^yNVpv3t*O_dBC=vWjby z-z@}=-janX5AXCvoBSC$0*DjP#tkQ_{{Ar z;qq7N+&owB>5X~QQYWM0^Frete9tX3<=8o^G8ZS`cTvHj42f@=$z@m>Rva>GbPLkg z8AL|D6Z5yQ+^><%9MOFLGEeF4O~o`t-uP)2W6GaT2%2(+gK^e_sdHZSY;+dL^bLkx z`F`KC3Kz0aDqS7#p6F0-C(80N)h{VeyY;Ho&Si#HSnqNeuD7t8IkYs4iJSV0zPc&8 zKTwr}`qOej`O=_CN5XH_4V6NpUmec^!CUY*5?Z>;&n3>1EfIy*Yo`C+#V)U4Y8=;GXcm>hkwZW4J>pdx+@WpqDXlsP6 z34f*c?9J7@)9v65(KeF2)o#%8w&`_?-3tO)QVz~AkaU0UzXwBwGM(-pZ zVW>t&-L1%FRr5-rdWmJ`D@e4{K0WGJ7F?e zmwsmfp%SIHVCaaXV6Lnv^4X)J9;X|YnQR|-EbQso;n*;=14{mH#d2&64AF9WY`(O= zH$FZ#4pO94kg8COlzd1=gD-8=A6&@3o;a2Bxpm@EnjxliU+Kf#4?+0nswWhGSaQ{s z>_U6#?|QPzKPEiGuOXjqEnv5aY;!74>{rosjEs1A_*#qGIBob|G-@JSe}|u;CAmX7 zKPCIhk80~4i2x}T>Nnr{i3!78s)mGmArQGvKf~k3Yqs|pR%!=&J4>^P-#DMhb@>^F zrTh_y$*{84FB3h(ULj{l0BS$Ya4ZX7ac^H^pQ!wdexpU=o)PR{zUzdZ0VHOMzUvxXx!ZBokIKVFC8s0f{7b+$KM|;`p9S_g%5U#}Ll|z5E#&jd= z+0Lws7`?M1QD@x)eX-Vo(HgNP)GGAO>C%OFcYzFz)9J(* z9&O$zc0(MFS-T=VN=^$2nN`e`g_u2dPPdBf^1f#EQ>^@eaNZ(xjdUelnShqe0yJ5> zcs)Z9EOid6SSq6A0&y6Bf}PuEIn2+nTJ1DtX|_WQQd`hF&2Jv1e$x$bL1UdKG2G3E z@7X!u8k4`u73THt;141UtC6rMKF9E&M!{b3={J{HJ!6wwLQZBxWtHPS@pB<#C9%7z za*VMxXW`^lEaSI>rea}7kYeM z_SY}6HX(ZJ$d_MS44Kv^$$IQu7ZTzf)1KG*qa9{Jv{%H)ql=W=`12u$H@n0iy%!CBE_(PIeVe<_NgeT;jA|7)Mt}Gj@5f||%WDZhGm?0g~=yI>b zCWwZ4k_!&Bm_0h~YeRTQ6I)Am^_b#6yh2*dIR<$l$ zQ4BHm8aqB7EJuZ1=8~av{SI)!0%>Bb=%!npOm&&=x8TJkZJ{m+48t^2WlJl4eTT#@ z5)B=q&F+O1cJ|TriZ0<2lY7MqiS!fX@hm+8{V}wVN3K{kvw2N6(%qtiz-m5uJ=X_d zWlqeqEz8i^h3ri&8hqv=o64BA8TsUpYaUW=A@_Z7VTA*G@W>(IjM%#8NQYSn1?Hq) zg@Fq4V3^v|-B;7zKjz*Wj>>Ag#>1I|49_n0Pl`_>1h>WYrxFtcXOXZ)+?>9J^AmE? zXO1ZF*7WDG4UQ);+8U3h0%JIuOp4BJ@L-~6&%M9!0xs`MC>!V*z3VBnTaZ@^dyMi7{$@ zSRZ3D7q!ShJS$E7^>bbziV!8&cS$&|4IK0sF!76p7@zOnMx4jkVwi<<^y5j%X}A){*D)VBryb@)>myYKje zACUpMXktzZ_I&2vpL6fKF(!^OwRE2wg9B3PV2TR|)W83O?n_$^RdWbsIi}`Hu1wcQ z;Nvw@EzpwyVr0);a`URI=N;Ny$#RPp&6veMlQ`zvuhPPCv_(8$oe0OBrD6m9Uxx^D z*~qJD0R^pwel^0xR^ikiAA9BcxGM7S5)ZDVqhDlAL6SLgS3v^7!CYrXeWIyw3YEOH z7jBQho@sYJ#p>B(_qI&I8dDoUsRnApZ+mqrnr4<190j>GfVx{AM)53GKI=K?MjwZH?o)HX-#6a#dABaGDS z`4HVWlyalC(SHu$ZsBh41c$qeeqB5kV4whN?Gh6WQbK{m#%M6CgkxrTEEhUL=xwpD zx8sx}#s)4-rMGo?bi$JJjJ>a72Sjoj*`1)m&eAg=_3k6!n9;96H1&t*0`W0_0+OIV zRP2F&ETn73f*Y)>j#MWU^010lT{@%wdA^*SXSi0A$O4qV$Qvd?rrV?zh_Uz+iml1Z6^8qXGOur@kXXP{5l<94txg?o$s{W45y-*VV1R+^<^*~q^f{9U_ zk?`VrVbT&2q}-x|s%@aSfI-m%pnNfOd$H6C=zSr}pAhaY2p3eCZbf@J1K?C&bXQ0p z<}`r3?$x<$3!EW#VwNJn6OI46Clh)%wI!n1-OO`f16HbvET+KCD?yAZpjKipZq;yL zo9-qCR=`JvO)mP2IqQX%db56me-3>deNzNTr2 zKmm1g^3PG0-BX~raE2ZIGtxM8yMtI3H+`sZ^?zYn{Mb{#$qE+&r*pix%|_^vYyP_& z6~4+-@M9+pE?29r-*jdF=~u9-bo&lSJ;^4Yq3BJFhq9_xUpdoyDiKH^K6cxe5bpVe zA;yXmz>8a>X9+0?NA6EEkCjUAzl~d}99UB>Ha(tC8}3$paVEP8Hr&M3AME zTpj8EJrl6iuVU?spTTZ#7jVuIkvOvQ8!A9)#Rb&8FF^s4P5e3yKLN()-l|*(!i8oc z=IUn%;6^G;S_=`bebdEPPu>_;K%}jEFePvPQ}#p%YlJZ`$iH)ialamd`Ws*lKh@!^ z?y`g@Hdv1cN!ToS(_fcW^A2b3VKU1E1d|GgW^qm4Ug;HpC7bO zysKQLw;S@1*-x(F&|k`++}_U@CLIRe7CYDF3mh<^@|g?n5`L#3bUXciYCFgz^9krN z-G2Op{q=B>w2&b01A_7CXgk7BmAxsOM3<}!6j0F(4~pq$+Ct#UN@h;MhY4$)zetkm zpg{Q$#$>T0_MhPKE!fe(JY(a16u^oIBsu(#B!IIa@T2oN{6YnuW0+)O0lnl9v{-o; z?f7BS)(ny}i}!0lhDYGfSnJ6D*kIf45=uoCrGVFO{A(pH%|D_Vf{cE^RbDLaqrrPfc!GPtXIagdTN5-b- zsDnN4V29v2lwy@QOaroCaEDR!ib1a#gv->ZC#HZN`56U9WhXj zP|V|eljbq%AsaRf{fPN414>pR&($bF7-HtH&Bw}$qThEjZroH;Bs0CdgMDHanr=`@ z`ie$Wn9=$UtlE?lW;WQ+`ZlcE)JJ!&?jf68RV`S~PCpP)x7)*hIrOv4BZdP7`^31d zpax!yH4jx#8uhlcXYQWw|`_K#&wR3-quRi zRBC?O#mP4CzT^5N+|-jWp<-G*c8Edeip^g0I5wG3+{`rv#`&XT?^6aT~*WP5%f|;Y&UEcsG_vCQCe1nIY@5 zaE0_!;hPhKL=9^Bn|DJ?Vtav+h(|9f_=s7Sx(==f!ZF&ipE^V+a`Pbt+5b`4C0Q0v zS6zQo&>l+i1MU90dGD>WACU!=kviHlOBT0(9Iy@#9v)~0M^bx_4!WhWdqUt9e;k)1 z(U!%#G;F(HMltxjd}kCv*+L>0ujMg%Esl@loD!02spm7%hsqvv$dvu{?Q<-3Bs|;S zQejpG&#_#*9xwlV8TN;Zvh!e888dC>$A@Ih7d62qUn)5%O+xm=;&P4jiL#&H1d6xa z{-n&?D92~$_9}f{_fmT$Kn?|+K31BAFkf^LHSv4v)2NEc@JY;b$`LBHe9Q{n>w9^e z53=Kgl$c*KkA&0GNcutlMLXxSBXTWz`_%eHvT(5yS9s4lgOyh$1fENTE1F3iggfvVl}>fNoufhj{0F(+0ny*n^9OI<3ZEo*kr`B zECt0sO?BtUJje$MSy`z2n&%M<)@e}&vj?#wT`0i?n+Ey;m<|uIHXc7Vw*RE`X@NU6 z%3!prqj4FptMRxQ3%_poBwH(n|3>O&$PRhi>-GFmBaE?_Nkbnfoa z^;SP5{lVpz*o0V~YD&@63GeXTuHQF+VaO+w#R2dY!Ss^ zJ0vMUx7aJ*;bUb6wr9h&_NY`X_4Vn|xsy5}hNq)nk zemu=DFADP|gsJKT@zuPGcv0oV_vBDjZ?vspb~E9O@yX`L$Cgk>0e%99-m8ircv0bg zNKBdt9hvQSwFbb8%`F$5ItVzbLYU4h;x!2kn(|ln(X`wS+ZWAeEV|bZ-C5p#McDgc z60b$K>V!$xQt>X4LF-0pjU&c~b@{Mgnla*=wLHs$;;gJL*XLt3jW-@N$*%@5c~rHe$j%^~SAC zD}tSVw~7 zms5SPD3DO3g%@_O$2KXm`%41$nfIP~51Nd(<Ea62(!>mCF<(cX=FKmiUgpnWg}>b|NGTc9vXLP7olVjFevtVwdyJt*EdxL3Mb`IG z*Akyc?8cU=N;vbXt(&9Y9KTRRFbb%NIIE8ryDu{wX2;LwM*uFf#P{P6bg(Fiu{gDlM0Tpu~ceE8yD85N8s`B?k=uRY!BmQ=!F`GrHulFiJ99EnTx*={=Y<@xf-Ljk`fur zPfTJ%TYmoX&dN2WXst*@pKtWiq`pubh`e}77(bri(}j)6W-DL3`-K86oq`|JxS->F z1)ANViq-f!u=Z!^xd(cyMf9Q7PHvt4b6+aND~>u7Vit7k5$to%-9LSSE4baEm<^ ztAoAI%YND#>@^Qi+QFovtPwRGno9PaJHSM$e9+R!%2D~#b2==(!Q zq3xG%N?g$QYur6Ip7&OEcV~VeP5Q%1KVOBQ(7OGN*BJ-7)3P6%cG_Q*YqrJeAmfAP zb>*SOskT6jHD=S#l=XLEZ|;)NCMOO3#5wigi?JSx-;qtv=fScTBOt85)x;ifzbH}j zaA8l==Fx(n0QoXv(~19m*@hv$yPoBkw9`vw$JvQzBxco-KRRmLta36w)U6$rK4DKY z#NtvoOHS-B^(U@lry=kRz@XJaVw}6!(=>RrpyQNRa@P|ZgLXRl1BuFBlFp-rB5d>* zJ0$v5-G29rJhqm+=Bp~?TOUt4qQ0N&e111)>Z{hRCL6!|J6F?mT{8|_j$h?lF}>on zusqGsXs0JjS~B+B6do-|itd_r_pGY5^#;uaO}DgIR^6r5D#~K;?r{&}m=^LJWdzJ_ ztU8|PuhO_kJEEE|~s zz8f|JdWlatJPn3prs6VhlCxYsxrjBL`47J|mL&S%`_2f>!cjpAJx*G8XQn(STiD`d zze8fclEE{wN9gyE*S+X#UXw7r<=^ip4`h=$ze{8#xTC!Cq-C(RcP~IRL(wKeN8~g> zBT*}#5PEcB`6M%x@```K>Bd|vH-{#mIAb_$49M~?@!GL?{jS9je|rVhex0h(z#Hyk zDAiybIyAZ*nxka({H#TYX4|Qka%p9-I~B3|UctQkrlJ*#TPX_%d0&@hE5%e9@loy# z3fdH-Mbbx~ODn?TW;cPC@?jRZEF*8#k+419D4`9Oh@|J7I&L9vk5SCqsH9PgY!iJr zpN(ZPmAAx1oE|>%U=c6B<9&_ClP&N~)%U&Jw4)(@uClLulf=#(Qh`;W{MU&lO^rW4 ze&3p`x|88)pV`f_*T{kDQa3zKTjF7cvn6LiW`Ve=>5CIzs5W;0n-w(XRd*JUphw&0hby=fNbkQP-d1w&InY)Eb)0m2y=50pw0+fy{wFbU^RC8dC**f+k8$-$75~Bx83zbdk|{vA!if9P}Ux z1>~zdfm``?U#Yl((FAM)KI%+LxI52g@pm-|e9>nAj~pS?Qp&-Q z8Qh+__;6H!1~3@p#3~0`3s1gtu0z8e<_kfpy-k7Aj9=h(#eQ4TP|yV$?ti@91@~MQ zCr_kv!=%lrL%xEYIW3LeP>5g)Zqvt!(qOp5FKo-5#03Ev?%ymT!x4hmv8Hh3NpJ^4 z3YDi%nv>w2#)$zmbbYcn}7idYBxvPluRxd z%;|_l1++tY)}7O>SJA;zI1e6aH3G97`EM2jCsD0TONGpmyb#2NT_9ZhW4Zd4l=~W>C?zWHX>;faNVzb6UbXoS=NsEf;wUyq&b3JK}PN_iGx^~IW zYdJ?@d^*+^N{?Wp)>9U=a{$EKN59H28mQ>`OU*W%1_dI3xGb73Ch)1VY_VyUn@cD> zmysdnD+oBXX`tl+WKT+!J0VY3#hUx{@58b z<}5VP0yTiT)lr$If@V~kt0_?w(3MG;Yh#E4@EFc8Faj$0_?D3?b)d7-%JL-8o`V%M z{-q|FX60LgcEZiG04$(|%CEEeP)EA;d-@`^2Fi6lY}g8FqrVT;VN3=iZ<$T!K<6;0 zV~sN=Ak(4pa~-JJ>{&w@24@~{Wv?I-KZ(F2N| zx=g=77x1a}2}+h38gN3~3p{EWVYo$Bb7{te0SaQ!qFX%knFzR2+OOXQU~C|shsXa} z!(akv!p?T5)>aAxLN0X+#+lr;p-9zUgi`>xJ>}-h1v-ZFI~nLfGw-VOj5~;!>Y1aX zEH^j+nvYlUXBI&7sC$FH(qKb9+}3JVziUAuL)Hm5kqgdsWzxek*eGw~4oWK->MWqi zP1Ba~uak)bI#{Iyhd^&UHD5Kb>QE~TqQ~r7l%hMMBO$-!X0k2Q{q!XDr@F@rHcPhEeOn8Y;9wuCr0BT+mZALK|;fN2SPl967 z%y}_+p>qRdq63+R$W6vaQ0gyT?!#O*wTGt_oYjV`!92&QxPdq$$ez>R!l9W4Xo9iY zsN2pD)TJp>x@Vx2CUFaieW_D|XD8}HE+c{fj%vdX(qPJ>si$cw6{@DKxT|x2Jo#WZ zzNF#w023jXi}S|I!KUz(h`EAb5f^+&;+CGn4lmrr&aa`!g2tp+Y@LT5faLh2i*^j8 zWToP%|4Vv-Ek-v8zgrA?j}gOwHv3CeL!gQZjWPb9PLTxJJZDwA5KME-_0K)5iH`@f z6?SX3VC+*?u#%{z5zJc@JAcy?00BMw%*>e$Cab1x;Nbx1tA`Da0O8x~)0%(+^NY>J zzKF=f!iR?JQj85KIr~xb@B1II)d5DA_{3&GnK+CMuLoI@+`Q~oB0P3N5;!wd^%1IP zB!PTKKd+#Hyyf@w1iIz{(pSKQ#jZsSV3<$U>U0?oD9*M~iVHAOa8Xnb68WGS?SVTE zTCuec{m!LBIv9@8I{CnAd%^}@E9aB!U?>rbXp}hd{Y#jt^1T6Kz*|^(>I@RP2%^GE6|%!ubTf+1e(3!B zU9QTrAlv7>Vh8|wS?w&42YRpUcpiCI97e-Eu=Dh(dL*p){>MZPv5>qU==*9K{+o2! ze8t=g#uNL=wC=b>J%NeH)>rC1fkm%(om+nmi$1=+iu^{F(oeP8cI|FT+1J10jux7H z*uZIwRwG#e`>LD$=)hFL9Fmpbfh)&zEN~ktSh3YMeGK`=SqN{57Njq_| zLW$DZ$#n$GA}*>=8IMA<0|?!jLbEOmPzo7ePmgXLgL2aQlo*xIODZ5;vM(7%tnaKq zb659n)VLa0K&sLGeJlaeydO(p?%&q-ddE^{aDnK>Xd0+U*TXji2hVs9p|<&17yA6< z_Yf^UcE`0iS~&BVe5Z3Q(F!rbl$++%+q(^}qUA)RflSEC!=Gq>11au(?Yhi>n!kWP|0l%iHt)Sp+^;wgCR(C77h87Lo>bIPZz_t5I@k{L}kXM7$~r?65i7Mdl17#zO-Ix&x&LLSWOA zFbn!56T+q|m@8VldIzpn<2Iod4`6K3RoS=KC6z#;{w%Z|@%Ogq)_P6CZw)50b~7YS zP+^34Miv-h)t5S6{pf}nroYQ4`3lqzl=$I#NVo5)WUr60*YnswFa80Z=HR6vjMt!- zB~2cvpsJiGitYoLQ;@5+rz3zLXVsdiXjyfC2WP}it`@L>de1D^Xu*~0J7Vg_*Q@X8 zS@vzo)*JthVA*0K{vE{0IVs}34`UgpeG^JSlQ$-GYD) zn&`1Tu^|$U{wLYpSr^x!l1O#X7lP>+9r~~Pq%c0`jllbzz?K0s@8mwU{e9up94mn7 z#U;hUFi@<=-r1O;0>+Fd^Q}!AYCx-aN`+nk%t8g9PWyeBhShu({L3 z@Xh^hBiBmnY(>kiMEUfMC+k1YhkdAx)(`??0ca*^KoR6Rgv*L6+xo2c~|2K7+GSb;hd-)9Q#8-8ZTnS?Q zowUMF93M1_={U8^mCL>5H!r@|$W^|p#CeyZILp?To+Ow*8x;K;kg*B0YD z2E{~0X=va13BGCCjYXu=_}(g1WWI|T$Jll>eZNAH7U!+X#&AiW-2pne&rS`tf>UbH zh>jWozr>6Sor+sSZ9DQtAA70BJJqz!;S>{t3Ny1I6?quQ^60cIuJ%y6z_EYw9lFD6 zq8jsA8cE#`-hMJKUOyT`-sg<+wGH*#{Ra-I=rJsJ_}BFh^jSVlIK%zlLgS-1C&B4k zUwGoa^(R?AY;gJ{Of$Ci&fh4oZ`c>n+EZx(5ewlUl8dmpR3a~$8$q1#31PFNW#kKJ zX$UP3EM{k*W$_cjc`^2QW@vcuoc&15iY%>J-38F(TTBwh!<>iL4<<9 zllz2_VlMxS9E2ki%kI`R@!4G4EnzGvG!sPe=Uy^*?>u(!J}AI7l&bwUS&}ooC5m`v ze2?@g7yn@YKq87w{p*sR>4}=CJLFzj28CqLiD;tMzEK4!W)C_YmA$v$)iAsCy^raq z-5`n{%wA0-t@d>{SEGG8B#Qkoz~`vqO>WH}ziK&+-{+Vgr25G*A0#@w{J3>Dic=`N zlIE$|VV5VF>0$JjV-?&URcLcZV)fSTq1dcmu`vtMmrpb$CNH~8LobXi$R?VoEIilB zd1uNv!?y$?Imy+F-?{nZNe-?!u>Y)}NXVnH@SG2c!n{kzAd#f{?9ppJ2)Pcr>EYGV z;p^T>{xZ4elkR(rIS04PW3qash}7e$60&G4be?URDfsX}Xxy4S<5{6Qjl#3$IXoE3 z_wm2RC3OlEKe~*Fv~xD*y!Rb1`1PEK!s8K*E5=9AH{&?@BX%1w#wYAsl!os~NjrPC zb-2`E5=Fd{WG7HtGs3vQF{o%n$-b#d6rj)yRm{Qkd+)ZjJKQ48on)Q&3cW>zNp|Yj zGuor@n^bLvSQ^mSaj^;(Yl8y_I8IuaoL)plFM6w~sGk)#Uhk7m?vlg4J)Q`|28HWqKVrp>ooum;$^L*M&nUtZBU-m7b% zMLglnrRnxM?cpH|ePV1TcP+Hh$D1B%guYb$P5zOC6Z|LMp8A8Z_@Inp`YX+i9m}en zzkgU*y&KCk6MB2LdJuNQo#wU~53dpg+#FYWcuaVU)Tj$Fwa&Xo$!d*T6iqGW8-*(! z1Mp&#B+ZbxFv}{Ya;3(g&Z3=1Z_J#OICq!|F{drNMtAD79f=`eotKrBj!LU~(DIdN zW#wc}g`@^?bx35Ph4dHf_|ZF-HgC)V?3J9L<&Kvkx+1bm3Qx?E#SP1SEgR!@oE&wo zmp){jw%;qG_iZI{FEY`xXLHdM)TpG1=;bQtBFZQD>nT0R?=G*rFT<417syN zD?GOuhpnRr%&}*`-?n7tH&G-G{Y-k)s@mwMLHb8EI6RJ@0o{;p_Oq`;Qq({e+e@p6 zFL*`(FO=mR91%WR@RW0$O}kmC>6?eJjV5Ym z&*(vmxNwJGh7YC;K8~DBHAh4DhnC58SmklxduPnf(*RQniH9ZK7mJpxz3*948qfIq z^F9)w(=V$JuWwQ>EjU<-^4GD?d~C=|>mNa9QsEb)TWzP7YXSj#T7CKV|PhM0JzvDg&K}m?*_9yCX@%HV{ zoWkTtRx#xDj5XrAZNY8TYt;FB5>q5O2NUni2wHqrWx zWzol5O<=N26B3*6u0^}2@o6@X2`gTH-H?{sSJGrv$tXsN@9!Q@k(R#M zz{^bEA=UR@eKfIl1fMw3u6dA#?mmf$6~$ulhBwV#)`o%w_Us<(-J4_yhE=Fp;N|Hm zhV)Fc{0>pYq0s57v|^3yt+XF|{fSuzjZr#&fCOTslu5IYiQXrSuoEV>Jl0D)y1eNk z)%8LER+J%IvjCH)LLTk&h1iRsNgnwXp`Z_++UD@bo{y@A*_WtSfa$iW< z?Bm%uVUW7jyy+OxHl)EfHKiz+v*#JUe#H)+qjFHuly^!!9@eu4z4ny^#1vb~(= zj`gZog+`Ex9mYJv?!&{dgft|}s3!}vqqX(%32D@rggh^Y?Ics7)#^btk272HFY6Jx zo+;U${z(72LMAMX8;T2_L2JL!USzS3`$U$DpKBxyJj0%8c{RCJELgBu5)jVxk5#@7 zS+EFWOSZlG@M4d%^FiOH(k}()Btr~Ut7!57h`8XT_O<43AD9hU*5Y4x`&S+`lU};^ zqQHyo>t}Z#n1~+RWu@%>Je=XhJ+#YOxK7exrDYQmBic!rd!?6-JpnOv$UDQs4DVU4 z$QRuOi!JY#>-I|$Q|>Ch%*lI)c262=D_r}Sc#U-L^Q?DQ{pJJeTig@^zlR&qga{ z>HUkK=ZNks({wmqcC_d@OQN`y!(IcstyU)4xG zY_5$RaPqCF=6r& z6T3|f&LtqGgoZX)R2Lk*G(nn7qUdCZVSnplh#lH1Ld?@r;Y?}{$e3o&SIN|?!N}FOT z!7GDTp@bt|`zuQ8M5&aSjkv5Ii=0aCMg!Kgy-Rps+9TrcaoM?zZhJgvZ$8uB-h3ANm`rw z^e&_pOg{AK#xW1GPZ{i?t6pwi5w93^LTmYr%qccH;-Z41C8=lk#gwG|GI*pMZH<*-R=G!`{#0qJRt0gk)EBXR_`0v z6wa>CCAzny#5gCeD{~eTXA(GgNq?ZI$L`qB&TJ7L4c;@i&6$gIzAeLxRB{r{-%=^0 zTl1Yd_je5{uMg5BV`JwbUN3KhOh{Ok+Yndx(iy4py=3n&y`wm(>BTcr8I{?roHyJ8 zyql@*hkS!>#BJojM%P2Y7W<8 zl9HPkMj%p((3s_=TSa@>dJ~`YVa>#An(Tq98it70h80950j~-IZT;bFmP(x25@Y2_ zRw9K7LFjushvKg;kL9Zlrlf63pXX$>$*YjD>014g3GYtPRsF^rj)5;BEs#bvp7CLx zAMC^8pUy)xW&OFkVvSHt#tn3XRR(&M_D+{BP zqe_v#w{xkwdRZ)4QxEf*xpxx2df9n_I`&e>TcaPwpHi@&{0Lk8R`$lq`Q~;)Os1N} zg4)FC4i$kfPZ@u#6(Ohlf+j7a_m5%jdR9f%S8u+v9G@OycQz?IQmp z>YBsrdY*o4G-zzwMq@h-8{24XHn!6kjcubz8aB4s*lhgXd;9%8?|<{m&dz*hW_M9sn673z`y?Y z?gQ9QMf1Li0BJUA#2KB*u2dNCW=_CFiq?`$4!GJOUhVi&!F7MxU@-g~MA5!F3+1cL zPi;O2%d?*x#wxL844B3cb;yR>k?;_=R-57`hW;n6f3%%x2o`VxE}}JHjEtlvZm@|q`FI(*ft}MkF8%-Q* zEIxc48O}U#*f@f(tBvX><_B$t*Xzn^ah7*6tTAEdvlMiO(h=f%tx$8T&OpQcFox7m z%d(TC>G!0Q`mq}N-zFd$u~jPE=r0XTe>Ib4bGQ1=L_$7ZoDUFf2SY(EzP!v9=v&Q4 zO{8j^>MV}m-T)fw;8tO(WRL+jpW?-7@|tN6%wo4xaEBqB)T4X9Z2!B8n|Yz`#fCoh z(I&3tK3hr!mcOgYlRFHZMYy_#4Np^_AHLHXduNKB|CL3qUMXdDtk?IePBDIT3hFWs zz0zgN@Piob6#2B*fvF?w=}QY)_f6?b`fyaIH;n<5pj=^}cyjmFUr;^%e@UoAPc+b8 z{%!{|tgy3WZKa_SoBFM6ti$`=UyAG>GX8|>@%&4|et)D6CFB8tYSnznm+8>RI8@00 zo&Hv`D!h2_ujCD+MhyD2ZMA)*o~rk)%W)ET`tia!_x?~WQm-)+ z3*P$Rfj`_#1PTh3Q=)h^i8XbT;U|>6bB(t{y9RS47fo$^~ogzTpvhwyfm_Q+# z>w*zMpirLSINu^j=<)M}q9fRr>^v$%^;cIu1hB6{wWp8k@5(?8>Pb0FAPrRA`uL$h zEb`gSP0TL67s z1}pOb#4p`>m&KAGZ(4#%+Vg?_Wj_-h2LP>nV;0y4Xv!`pK3qT5wFYVOj;iVbY62g7 z@FfBnj;ESL$OF#n7wVyp1q>jiO-9Wlt$%DtOUU^OUkfQuDLxL(&1M~g1!ix4{+gAG5Qzag z3Op-DpifLbn~p-%XlB`l7L$OuTp9PyEBjSSoWUaJcnGDkQ+YsD#fad7rdRJ_B7g8{xGmQ0IvK6pD@?(;F(NNo+0wazD0YE48SVOcft}AOn*>V4JA@^+h4>hs z?3S-$$-w_@p=;D3rd4My$g9UV$xgV?0;Blr>-+v!h0@T29sN(;#fKX=yZiLjk!q)tSJUAM{a@EkT`t#au4?tWkP z_7bsN-guccN_J%bhi&q;N)dAW6swq32c3v_)*9o513%h_EPbCfUn%paQbVX5)a+^2 zP5?8dO=#J6zp+NKfpc^$=V!6*vw}6nk&H4{ZerDi7$B!Qtz*r+ZQ=CyU*y|$-Mv_O z8}pdXD;uF0T^sXp0<6ZGLLlc<-7GIBk@K@RB>rT(PB?HP3L?+<1OUrqWA1l*d@N_b zZl38y1g_Fe5obvZ`vbEOpQ7#`?K!=r49I+M++xF|-@f44kA!!O{g`X^W%Z1HB2t87 zEYMOGw@)}dd4>9B=|PX59pDpuLVv_iNqpZ8$Ydk9qwdFiS-7g|*kh+)T&h&dG)tWP zP@Ft!yIn;W)pa9%`_Y7K`Xt1B-7fttUz$TNwyg|GpZrcpsHRptokP*y8f8shEA;P4 zer5w77PqrtfP%bPxKuG8@s5_R!(PDpC$sR$(yX&Uv9G8p3ETl4JEQTr8x(1~o9mw~ z4u2lGa`^f7+_%NV`ulo|kU4;lAR?%6!f@77x!E1db5?jMAz@+{ygiU{0p2nU$t6gx zj`^f3ECt>U!Anz>v9=Tw3xNbSCSvvc_>?knG{w(J`6W_e0j=^b zDLBz*%94@~;iJw~=ciT-J_LEOZ|Sk?2vMOej3F_AX9UJpeKo&bifsJQ#*)8a8$0xa z(f%Ex)8f&us0$CZt2j+Qu=+(?V5F3T;I-?hWt6pPskT}}(Da32r$3}Abx#4JyVH^s zPw;i&rcaIz!q|_YIBYq0g>wLd#WtD4Z%E20zjy89x6nk@27eYTgx{_rmNea~EmFn+ zHcd!qVw`sm3?j6LXlP8L&CN}b7L78snKaG3kiZIk%+Bv)WW;~KUt)3?u=ik zE2iiC*{XI~&6U>ML%Gq&-&XgyHz$H)KDRsieZ{w?GlTFA`=Q%q-y!&0 zY`8H%zwzF?V)J`Hl=yv-FoeHR8A8q4BSlnW_)7FA{88}QBcx;ET?9C0qs8|b(%3If zAjf9Hqy{v09{8)ge>I2wgfdX-nG$2mE{->+;y4O@<34@YSI5tcyz`88Xw|c{o;l}? zRU6&MbGeodK>f^AZbP~(q_Xptzx3ize1w|3Pv4ri_i=y%nBHI{K7XtG1Oj2+|A#&T z2x1j=AD(LeVR-khOVEWFG`9Ab+YbU!wR#H+!y5lee#7pcF~8egzk1f^y%=dF zp*H|)bLBwnXb9ZQ-G^YN&A+2Ii7pB_^{lJ*li+LGiBT4#gQt$I$7oMq z6&`EiPezR8cQdJwhfX-nQ@UQ&NF3&lT~|m{ir?Db))&nblRV3KFnBzyZ4V3%Py9^B zB%3X7KhPj{UP?7rI?wf+3u|ws2=SVj%}Z9O)~F2Vx)I%Y{Pt4RR{bGBc0*^<0zUtX z6H)10ACm^LZ=XvdO7Yi`olpg;%e68dBbG^N+UHRr?DAE~I40)L$u8GTt9jqq2iBSt zlkNc@IXn3?z4b9&zWXu)lcmwe$@&|Mz7y~$N)*KqX z@cgo)d)*CRl=X5NGUxxp>ZTb_;7^n8#+?7}z^S31thasnXZiA?2z*5&rHkK#ZHKvx zW3(;uWjjfqeS&q3nX&R5gg9v!vFAQlv0o?i3Zc@RQ>4wl*TA!Y-G6B`EIo~wzs?F| zJBUl}GQ}4@9bf}H=i%^1#odH$KEJ;aaUj;N{q1X~@$UIxhSuQP2%XuKPKB5jkw(~Q zCHjp)7K>@2WaofJJ6`_Prg*E5aZiC3(ty+9s&4aJu^N}%k%#3;q@`H4`+4dEEzRqD zHZt17aeC|gI-chr^yjy$TGsVrtC@xL_LFwqFYe!o!G@CUGKs3_y%p8(2Y*}(X~tSP ze9X;KZysN=6!C0{j$AXq8bA%b@Fau{gU;C^;%x^zKBM?RH+$xomoG zUZ%rwn`%)qRg+?9ONm|1fwyZF)nI>BffmEe?~l!@A$P@lkCf&j#KDm)d%TEIt89o6 zJ*9kHE|6xJ-|ONmDpuC^=fPi#hGji#N;wi%|2!%LVs;!Jx#%)>)(FJ@ut{Q8+&}k} zpPxT>J>nYqMTld7+wyaM6sUlQuFJ0HEubPJ7g^QIKGZ1>_lPiZ&3Q>S6MuQqN*1z! zHOFvh{35QWz@5CDQr>uc#DO+8zVAx+W(JO&OYY{O4rLL3o^D<1aB`cqT*>kkMrH8| z`AHP{cqSRi0{xW?yWvW)c6N?C zcQ)K0W?{qnHcV33!|WGf#WXPq__nBi+i{+dyig!FcX@Py{Vcu#(eL<@m52_q@Aw`eN7k!T;ymU}#U!d(*n4e0Z5T7xp z-QkvMMpXxN<*;-vM5B$gud%yTk^JqC3-Yq+v@i57+!A5zcTzoq4!l@{Xt&^`8Ez(*f< z3jSg|?5f%kiPUrSLd^4Kgw_BxgAe`BICY6ni^iqV5ANKo+mSjUI+Cu(y&pr8FDs!B z`$;CH+9MUb6PZe}c>{@TR*suK=^giP15a4=>epzf?>*vhJs)dms`*TEevAL{(4vgvWyG zUhNn&;5TkT^T9ZhMn_Hijl`LvS_^W@QfgTcp|;QvgNk#mqoEwR zra)q8y%JBY_sUoj#WCQ^s?qeU#9EgZy@LVO0dPyT7|houD>!1fd$1t2}PCK05#EA&U!ashro|0Ws9D=G=B1*2LuZ&(wt_Rs6xh^kB}KGbmex z^WMQjy!Qn^v%p0Xo?3u{ik`O3-bU6@6fXZ^9C>`mprTml28*r1E@AK45)sCi*b7~< zPZ4982Mzs&tEY8h?`HCyp^k&!|47R!-~Hr$5d2J73YnYZbC=uWp#L=wWleQh z^L=4|M;rFIH~X8<9d$LmCa*FqmFI}2|CG_TF@W7!4bevt=a^aDTc*YM?#}QI6U>Fm zmMycWq9gl_l~O0C4N6o6Dx%NpC7qI6fYQ-sT4rThM?c|OwL9kX73z)nD1JZS>kN%= zLDt_6UmX7Xos!YitY7hblbQB}NRL27!zJ%#0)D2a!cJN}Tv9>9O`%FvKe1lFoFrSj zkh+ThV6B=ov7LzZBO%E=5`;R2gSyqutF1#B`-G=lt^o6Zl`!^37bRg;e4ulYUx)J# z6HGS8YXJf*89p{rNNV2{NN?#Oa?>pweRUmiJ_GRg7%9uG ztv@L#mVLO_v;K5mcV-$ImnU$(t3Y}P({xLXwL9sUassa;y=jYQ<_Z#*=W+1$A z7)3FR>yOM3g6Y<+eTQ^;E}KmjcVYi=Vl1L58pR~^SH567Xkxrk+_|riP&yDb$bXN| zn)P&DFHG&|1UT!@Ugr7u6YZ{IReEWXBp10FiTIGK+UgpK=5VuNS`pJ^Ouj6XAoC$R zYBD7iFDAR+e3#U(OQI4mlb( z%82^u?!`*-?-X6TFJ_RkLl^kx?bPa<4>?#k`wGf^(4=w=7BwDf8Z~u&IU13u*H@9|F-{aDL)l5lwaUd{r^?v!14AVstv&s$I{~ zn*vHLALB3i?g0ZqylrQK@VmE9LaRbUw7=>NyMG*k$(K8tBhUIQp)yDOV$(^lV!RKP zW=O&9H)URc?l%wERQ6<%zy?pEps)=^`HeGstbxNN23u?)9eD~Qs9c+oX-Vw{zqf;z z$W9~TWV@InCovsEU5?UVFR%@BDuD>)P*&%zW%pXWrI%)r6@}WgfZ=u^=3>t`2L!AGD z|8SI#(_+x33It*VtEX)<$@WYsTaU7&)dZ}LReBQhbCY7KC99mc4YPq|E#;1bhzsQx# zRevy(qm`Q^P3o(d8SuO(C(`4S60jM6HT#|{Y>$ulC5f}qGPk+A(vYW%2@9#_Puxp1 z;rX0Px zdSA4p;W;jNA7sO3o@+s@SUSN@C?!N5`@zF?GVC$a^3ZoM8GsN8niQMRjfL})d?y7^B$pM|GsAOb-zAx zjx6QeXITP89jZ#3M+`MvpXV6mVlKzGe?Rpj_Mv{(od!z-ku}rYhWGfYb@-!!HFL@D zpi0PC&6Cq3i1+(5(!mC+*;wCtj{<%iw0>OHXWit^qlj~BvFMUY(wE52qdNB|($L-e z!l?oe$CvTx?4&!i$ZxD<7i;{2GKL9FMLrFq{Ak}9>Z#^0)NaVcsiI2FLKuCsxrpe9 zSGVBJ)Q9YkW=15)Y*bc*BjZv8WlXEAX4+u1O_k79(_hW$%s z*?e&77iORAgVETiLMzuRbJxo=qazaPaenqGmhGyGT$w*y40G?iZAh-3MCCn6Dj-nn zeF|5a<++BwjK^#7`jBfLwpnjVg15FK;*$YMKS)HW#~-fLz~1`iC*J{{v%EF?SFr+2 zKKy4D!9dC5eVH7-d`G@8`{CAjcej_c?!6Z{}n0Uygme@x^#1oPm<7RUu@ph$tOq z8cPYAIvAKi@iy^;HhzTcSs(tS`!qPS3+0O?W4Q1czzLhREA%8EEzZDX>o`g%tolQX z?QOym>WD@hAq-RTT|u4&H~utt5mzRB=*iH{}SEy;AkzY{$9Ioin zwKg$YAquI{-h&?FOMUlsTSIOl6(h;;r5<}ZAD-gjdpej|)FctC5OiXuoIFI_)|Tt# zXOgBuOs!N!pHH<7vQg?ix%WKuSPPE=;&mE|)KBrJwwsnsNuRB*!uFoR@Rn5u)vN~` zgiDMovUTaqKg8hH9`o0RRF4}J!_7EahsczuSiN~D6Bo*wHN6IYnF%9Rz0Dj$jo13b zQh+l}vQ;opABgsAu!V4qA{8;3W`ej3)z^f_p1yL0bo%HtUATi4> zB2wTBb-?~X^Wct&(ie?o86HCwvxsmqoYdkfx0m&vhZ3o8(&)X_AL)U>-pQ@2?J`#_s!t)^FUo>32A^%-Jn`)OI90 zLOL=lmu(Mt@Q4ciowVeVy&JmqLjPpL9Mg2k6R`04jPCbiUl*WHKK3Yq{zb*l|DdoUT29^M7ZbIRg{k1hPT-3@3?xlv3n~I zYF?q;tI`$DaMANAVydmotLl__ZlEHH@48nxt$#f)p)veu{XTO^6?6F9ZnG5i{Uhx7 zGZWtPTO0p40pOBGh`NoMq&Hoe9jygsOn1lpPu?~`n+@!ihSG*HDBU6q&70gh8CcyI z0O8po3$N=6AgWtRF&tfyRmX5Didjp8c!Gb~yJIPqVdLJNW31{pj3l1K@~EvFmk#C| z?L`l1ir37T)EAz;B7GC}_EAgeI3;BML|)$9oe)K0nnBtQA9S|PKJel@=q2wFrJyS<$=UF474(T0}_yhG|$@_P?+#OMd7g|}`}T6qX{Igg^h zol#c8lqwmb3GHKDNdpYZO(DHT-m(qRWfZcXwJh1B{sDN-cHS_;Q5lT#cuC9bPD?E=ETI|L^IA zB`E)5O+dy7z4S|8AN)fP8*(+k3Y@OCk9uM{ba}HfjUD#zXB@Vx6mcsA=19h1fq1zk zp#S@Kn!{)1M#dMcH_4?)`L`o$dpq>Ezz`sv{%vQTJ(M-(`1Z=VPpE*9B+Omy_-JoZ ztj!-W^+DH7AuACSE6fSy6U5aY+2WRPKYN50WdVZo==IU7yAwPX)My!fRewIM0?;Zq zK_5JY9oH(X$b2iVRl>bw1OM+=%e zBiw+FE#AeEV9Npi6&^jG)Rtcx-Dy56&smsTYI~pFY1NYKF^km!^Rw9SLmPTq0KzYz zciB|YWm&_rKhb+Jiyta^DP(>_sOxBzd)LQW$y2gs^d;@H`~6D;5&3MkF}|8ibg^=n zP!1_bQ2C`5Mw@lKnuq~BnpA4VC!TW_UJzNW%E-EF91%lXMhgN*40fW*#@T{g zS!8a>Ssi7ugF*lle!}Vj{Vv>RV~&t8&l5HjR!T{oC3fD-?^Zql=i(gj!uSlkgF_mI~=gNTa!9T!ve}pVRKEgA{xQ96=-r` z&X($1Xr@-mqDqkJHkM8s*>a|4#_)znwEB(mnH1)M<%|TIpM9*2D=_51Or)C+-(G*P z0$krVE57sAg3$%o!gQOaQbKPKp2sR~QR#=-#8Ho;44~Dm%0l5n%FF|8^E zh#5?_=p|kfP)r>?dAqcB%5mhtKJ#o{9f|<9YkRhU%@6Be9CL{@3Pzqo_WB_IMWYI6 z9VnVJ>Y!Lc>&j5~z%dLK>{(R8uWu39}rwML~|slPJy)wGHo-#Mof&RDyfSW$xA0jSBfkHm@6jn zZ@3uR**M;x(>dOR&q2kN^dQ#s0z)SOz-;xeTTcW;)x|x5*eerVFGLH%mZAoGHHV`( z&_1>=QHo+rD(O&)>>%BW!X_f=P_w|*NT~R`93b{Hb4LRl&a^6D`c|nHLL;hpqPu7@ znX~;>LED3c`sUU%qLK^1TywI!W&`Z~b%ujCY*OYSL$^#kXE7~&4y5bUWT7A_mfMU<$^9El0nvPyb%CYi2(Tclxz!H`mX5%zv*t%~CUvzgFI*J;U zP|D9eWf@BdeM^}^N6#-t{}xlMEj9_WtdR!l;09*9CsJT18?_O2;Q2)UPFhDq1py$T z$<}%nPN3B15pGTkCCmraaetFQ>&{LD)&9I?vsLP9RhIkET92*SM?jJS+>|-oQ2JUO zSD`HX?1W67OI9q^k2w)i=8cnBzjJiqYd7qJC#`^T=$M zDA~Df&Yg$l^Q4KviegRvxNvcn(_vJr%P5HvPW$;3mDbZFUBn2b{#eWwO4g(mZp-Al zZSp=dBLa*^&tcsFEI!D;5@IoF)`n-h*1N>t(%WKm0DtE;zIUvK5G9k(ZArOee84k% zd_Y2M(@V%~Cd^o6$2zB;2$29KTZDxgaD5u{b%y3QUzG^Q+w)tYQg&;C0*Bu$(@RLt zZU^5ZtP@?fNQLsrUz{Yj`uDI-+y1+s)P%zj23WZDcbzF=1jFsh@l{2Kt*e2R^w7&p z=ewIc@vem=tNF8+B`BurBK5e?^}3}qmeB_81|w9s zjAPTUGnLwWx+bZG&#yKem8}a5Qrr@S!+5Rx0OHRO>D|{eUa89J)B`fiW)WNeJPpgc ze-GSal>OdQ%E=r2d7ES@-aT$tj%YS3^A1t#9hV@#KihSCI(w;4*W&Ay@MS1uE>kt& zG<{i3)3*i>tL}2P9K4U+!1=PWEpfr=e7i6;b5Hp9I;D_1EcHI)(}GOw2GN(5%`^>y zqeJ9^qIL3{U?picl-v2k6(J<*1M+2Fku!w5s5Vj{F-ZEZE?n;%w6acpVH0k80M$ev z>*k~!MMtA%Qp@AH{5F->{I!+O z)5ODFEs>GA5b!ik_{mExaqL`#A5DftP>61%_R)-qBvIH8R#_&C&MXI!5I9! zvDc*wEgl>teOdR{Wh#yjvXV2`PJ5UDf-8~QH-7=_12^EM0V5LUB|QZ{Dd zQcwu8#VR(3f%1{*^cm*LTMp#`zkW6G{DrFW+!R5{#4@M!rOSATLYZy>;dVh>=kG zrJT`OFp45kIGJl&fLLW4S(XeymiXPt0>Nn$9BZU1Mrv2Te$mdoJOK&u?m87@@NA>`XZ-@%fOIqQ#v8yilyo9ns<^|mHZn89Cb8w4 zv-k$hnI_urZEnv#XqN9LQp#UD&uoT{puzDT4sU!dO7^Hs(nDJ;$fOyfSqz)K8_Qvk zcg-g$@`iSJx${V02E-2}r-HTJ3MBCVM%0x!O_^M^x|sDaM3Gu`cQuSZk_;J3*Uu69 zI3@yE@EF&QZfv|*kftM8{E5qbC-PLQo0?bc$_>+bEIJ(dWcABNkKUgu^hL7Tx=y8) zzyZh6|G$zZrJQv3sd`Z)&z6UC`2ltY6LR$a+c5Lr_iC~HJ)}_of>Vo!d)&E37s!OI z@&2D5p;hiVzHC@>mKIJrCEREzH`SP_qy|lg%IJ&C`=ysz_~O{5BVnnXb*w+)v8=FI zF_f;9G;sb#C`3*g3o7?r`@&8b&BX#P9C}abJk-asLWJ2kNoe;SR&q5d=>EZF%mc@c z8DS+?>>#Aq();t28~pMDsw6)y^qGP8qC~GHbxGc9A5SM^bTcaS88s{{NAUE0QQoWH zy9;Nu8v??L16%Y3MBy3i%mkBG?NOr$R*0&@e1Owe)M8yfd)b=>EHu%hV86QRj}+w6 zXeiBiryXM6FdvymGX;69d=V#cQ>k}2a%oE#{iWR9t{XB=f5L~X`Oits4;y5_zGDI<=B)iL_XZ-J(V{WaTqf48|u9hm-KH!dG;7L&-~%O?TvV}QAtBA zq^|cDQ%J%#0Fpm1NQeV+YG#jB9+hqzc^s^f%@av%)=MzR9L(Nnk2U(dJkEhAOM7L{ zgIUh!{(}%CWhOylRF@4AKNy? zMlPPu1?t$tq!)$$1ULn`mQ_Foi(yMQ`FhN^La^}W#X}r%?4AsK1j|5Z7pCetirGZ~ zI|I`rIa%Gt8?##y9v8EL3?4`ueGQcLxD%m*Nltn#%z(k{%2xG!GGT`yLlC ziJa&Vf-;f#1WgkRXF(X7rt3;Kw-usy3A$a_^H)>gSLgt61ed_kjR#49F-g)X=<+Im zu20oqEOP-&$`xZBRse}BD3?I5oXvfJJs9L~>RKAEE}eb%L#cUi4H6V7RW{YOpZGf^ zRK2n2CwX+!OVGr{k=lEOk!z+bn+obG_IQ2SN`qxN?&mi>O-|gqvV82wOGP=XC2onA z{FX|?-!NwC#|mMpp~t-59yR+4E|62KgC&x}oVF2Q`>fs>kz+cV_#3Zx2lbvha(~fo zVhp)Z;Uxb2H6?^U149VeD%$&NN~y%b#yB>1`h*ZeOdU_gaY_E4Zly4SYyLbwNObo~o#a-GdZ_N2 z{mZ8d0ncWYjK}Gq77{*)yzX&eKeS;dvFoQht%GwbozD(+jKo)z!rg1G@srMu&%*^- z3;ypuoOkzt8%*TMFBE^R_ObM*44&jG%fq2Cs5HWQt(=sX$Dpkhz-{BR8B}Hr-GE`^ zHusZ1j6oHEtH`i}uSjIAmG{;Xseh{IiEbrZWBMnmK4t3$z_s=NLW^%xjq^o09186zE32Q3#h1j3g(e)Vo*#&eBj0l; zO=ApZQc_LFCD5_~FOA4=AZP652UN9yULd&}vd~NczCcp5895{KNiNS+Baoc+N<+O- zEK0`prNwh~+9F2oR_;z@?P|7Rdm5rX5_%7U;@Pp82MMeR_wTEf4VAVTq!YOA!TC6C zg_|%_Zkq`54yGS5448*FGxnCsjo&2T#=6vBC-CYPq;{H$DS)af;$r;z za^yXTtoQjh79=nh2>|mC<+|cXIsb<_ffogv&tDj^3bmdkde9(Sb#|E6yK$}g5u16y zS%r#OuJ9TjmC#uIAZ^uf-d|(7Y7GtP5LJxUP*c6)pdmk7ha>FTRo)^a!W7?s__(k6 zpo>~(Xc&p6Vx-IV(JK%jksXfUTzCD9IKwh=x>4M)o0~fjlz+vQ?c??U90hC5CfXSm>#7xIzF%8) zR7kigz;{~JCvo5G5*$y_)9A+!Ut@l?>5oX2LHF!zjzR>XQ*Njm5E>NlNRug5ivLa_ zGs2r78fkDR3~!SWx8sP6?Tc&iz~Hidm~kLmMjH*af;tKJ$AA3+dRuKdH*lSC*!tCa)BEBpNzXr*f0xv2A zHkkD`a>zBk!{Z*E!} z4Yyc`{bTGCX-%$}vv`YnanM)t%QVy%mw~mfiov_e*XwAPvuM8f{9s~^HsvxFa9<5W zs9}DL|CwX+g#{cWiI$ys8vBs?3?3XX`dJE9=62ppD}|>mhamNneT~W0)D0a3!g1;lGL*q#(eY(`kV7> zbs>fJkQ(CqNw%V$pc9W>u#&<+iIqX5{V&A!yi?uFrE}O6{V;5k{K@^I=i&nYwVhudW~L3_T8Hx+oIRfJ7$MOpw466qSfbS(<}zlC8;5Vp2x_iGqVFFdr!g{ ziwO4CW<0e#a&V#Nr<$uOe|2`k#m$}Mk7msIBKWR**I+BarJ*#S*pk(u}*nQ59C!W%$xl~?N8I}JPSX4 zNUV7tg^c;3OA9e(H~XX+=8%A;N@0pe-&IQ!BO7vmhk_&4q9RRQ^dO*33-RkGKMft) zpQO9SjN;FL%i@s0bFoKf;}QYzTzu83-X?KKApHD+kCI8;<<_U&Dw}B}){cNK_QA)O zyiK0nNw;w580-Bmi`N)OLYDn`TXAk$^TMXZ6tzu@kc3hlmq*g7ewk6tg zyEVAs_1TFhjJMT9X3i*otf-2posCK`X^7V0qb>6WCX^&kYGI)*Qv#@Jp85}H%bbA; z{SHuWlHzW1hI^BtzgN)`)-iC})QJ7rMdG%9gFP;6@Rx>?{$bT3=@EE6r4xz!3E|n8 zZ=w)H6byYmEs3fkM5ziSM^cqmF>Y}f;)#*(S0$%RT3LiQa-8*GfpSi=CQtZKf-s1C z-8$HsWQPD{?_WyS#ivYISdpr&i9otYoEI~p1ViZ|P46x{{xj*^QmjD^6mQ9~>lU3d zsTH>WTqJN@B0dTr?|*xG5d-n?`VU8s0;b|a?g`?HQGEcSC^>m@p#aV_81)|co;PF| zc)GLjl>r2QH1C}V1QoHFfHf>{$k8I8($@=op5=!C03vr%^*t$YW-g&iGd*xZ+wM_I zX)Zb~&{SG;Gd_^_xK!Mo1n-4}3Ny@~`}>VDkKAK>=y2$|)G!1Ce;Im^W}< z(WXf8vu?~$?GH)U0L%>xvjt37MZnnkk&dWvtAf_UwMC{%+FuY^l8XO7?!a)@Ih3HJ z6P7l!g=`*PD9{6e^I?%WmI5G||p&;!AmMqvfpG$5>~HaBsFwp1Y5#LiF}aR$WVbn(*+ z6_ERGhExe9rvCtB`GALgS)c@}I;h?tZt_qBMKj(N^S=xzY95kX$0UQmmhOe<0X#s! zg6+#i%-i1qnGK_U&ifBR4biLQe+YsnG^PGSuo)*1ow39OG?CWs7Y10?rjsg>m~tMf?HL*W zpZ0A8#Oybmxp-zX!3eyh;L|t}+B^qik{Dg-QPtYPZazp(|g#KCyijtVk!O7N!sNY=xjKAKOI0GUoi zuYQRo6--F+-kML@L7>&zIUeET@?@ecR_%8FiqH4TT1u*k`yHNB38h{LhI7wZFf2(x z&n!^aeee1TB$u=4i(YOdd=G?ha}$jEkI6z~zyz9HV#g16_Zeat@IUt_2ZVp*N&s3+ z?Z%45;JlEyVTNCo?8=mYyuFI?D3E4>A}__cbOI34`P^rH&|YiFeYK_n`JNl5Yo!31 zAYl=jhX(_av(Y?YlmTh>f9)*-A(*&rq&qHw0)jR*OPU-%1jgu8uwp_^2`G5J1A)L?)Q|Q?V}LO7yW8;0=&b(gp@FTxsFuyNAj|X_B4<-cdQfM zm^v9p1L+dVUU=sKfnzu2D)f^jc?N`!DD_nb95kG3-M|`|H*{$nkkxgoKG#JIf~<1P zP%7sG(p_Os6w;m$1j^id4apqkCy>PIXs-CWv(0u^9EKcjpD+Las{WGvIFo5F!db^@&Ju{i91 z2*$j@OO3<?=^$VDck&W>{Gl^DK{uhCC@rC8=rb1mJ1(<=8|ndiWYe| zMHOtrKuNe-KrN+R1O}0?gIP8vV+jQqjkDt+GAqzlJLMk=u*LxezJ{L*y{Qrr6vRwD zxqPfiP{4KDx7-uC3F?Hq{d{q)V=zGp6~p6(-8bPGJB|~nDw3Mk6T>DU69cBl$8}F> zOHdWe6olj<>;gqnJQRfFvv`D8_%O(l=BEZG0yJEZrP)6|6@c0|ffR2r4}(2vPN8|o3;fWj2#sgBs1*nbHqm?g~u`BcDe<$jh3kscQa9JW!-2zbQ7A?gnSzs~+D z_Jj`XSBOmvNS&zo{lMh_0aHobVXNPzz5Id^;U0NApC!u$mfA26dDDL$$* z?zaeV4>5gEZDRv=N$uQCB!PrJpkem|UcD4xMd_?~Y2yQSPSdo`^%!7tkGgZ39W?+c z3x3?>2JN}!Vg-D8psu&4M<*)KevCQpaRN2>3S3@dK(ovSzs|6k4OkAx0iIHJMQj4T zHvvhfzptNre}4g@e583WK?DNv9L$Hz0k!M3K;D1O21^i-zZy~kN84O3n#@5C9xwhu z1ldr!T7?DmZK;x{t0*9DfuHT401f=oG~l$S>_!9x>44ci@Spwq*}y~-kPBVE37tU^ ztkDsA0hN?#Zv6$;b_aey41zJU_zZdRFEaQYZh{~=jYZt77*Nsmd+Fl@i3KCN zqfj2QcH)xUTr|`D3z6KHKzDUxV2U*_o{~Wa8u|{!6;R|gIK5kQfGTv|Hs3e^-HZ)p zm>s{^N)8yxbM`~F%TKnz!0;Xh455QO7Vc@*0Y$u8AGZhOvGX1wyzLQSWhAl-D}I)~ z17)pJ`4Samp7bb=7*v8g7-PT|q(MuKP&UjAgv0-n4i_Q7(|$0|Hvg*~kP9*ivRmWM zz{J#hA0)tljF!?adjpAjxpfx926!N%w!2XLA^;Erm|=XS3|SBon|tRBP-NT;ILZHI z>TgtJFM<)sg^s2}JCL@6DMSZ&uV_r9_*JAYOG%(bwpcZZ1RAXWIu@X50D{>8$?pP! z$<4$1f(}gl<9)xV0>G#cR!5@iL<7h{6Xct*e@meGk`ZKmf+(Sq477?iM=Q`kPCaF4 zmo_5-s{sE{NQ(aKQJhGP-BJNeulJ9=J78le*y5f6Fp+s}eTe782|*j#+iv0XU!RR+ z@Rpnc4tu($;g*Kv0ZYreCff~xH6a(MG%yMbofZOG@0*IdSqUmI7O3xoxNr2 zzmDkDK%jp`1FB&L-^BA^paJ!6%KO#aMM?n%R502OlYB~jqkwE1+;xA~e+|l^GTs^e z->hc>sTeF!i6WTW;j~_50U?c=Tbj)QmDU~~7$gvos$Is0#NS)Sft@`oOmh&v0J+=h zNXFMIvu@hiDM zpd$i0)2($Pt}a77{mXBUD3DqGyTw*u{4Tu4`QJ*5SU?p|C>lwk>R(^vJ-I-j2LrBlHsKeX4UU}kxzzjv-k^vj`<3I~1GN{q}R6B2d`PY2~yOK>|uo3s_Td3_p*|^@w zOlSh?a&PgL+EfNfO%i;DY$`_w6<3A^9~B)*P+=A@T9%x%p#_Fh$Ha#xdcmZ!9q-v-;4tpY8u3nJd1$? z%-wLkRk$y_m;455I%5ss)SxK7+|Iu0|BE%h>&KB*SS^ypYIWqM{EtA}yt(}=`OU~c zcn&ctKS->dxqyqLFPwc)9JCkOh6)LlK#JCc90iZ{Qa}MC=6m`30Th#%1AX;>htu`x zE-Fy^D@~N#A?pcjKw;g3+1698i3|Z^Y%|y^00TLOs%P-=PEr|Y zc_u%0GeZ)Tf!C{IM$mHcX;)aK0SU&ToL>fk{6_et2H34P|7_yz2K)Y2W~AZ|N5E2@m#+?*%AtR!I#4d zrP>*A)1oj_?^`?#zK_~RZDI9hVJV6V8eSUvF1Ut8v+*f8gU`^tvL%%Cf=A&NPFhDU zrbUd@?%4q;ib@*o-qi}QMn&xLDJU^oO^6zN}YP-8oLJqe|1F{(h9~u>T|KD#PlEmF>aZ-QC^YwODa0PI0GD+}(>qaVzfb z?poa4y}0uZ+;_kGZ}!?Nlgwn2?_?)uk~kr${?u0?4Oiy$vu0XKB_yav=75;ai+K?n znl2;0>}Fj+8=}mKv1WP!>>x5IaYA1G=_;D0*P!6~S7HY;vnim=Nv~$w%s=?XKXF1z z-Mv0X+eGu|<$FOg5w!-SdJ917hyo`9BPfwkTHW1`Mqg0#Nc4MwOMzNlNFt-0x_erO zE}Z5O>GuMzGpl)I^%iQaquZmCIsZgPN%iI0lMAS->HcAvR@(emec`G|JRnrASGKIHe=iqd@zssD2lb!Sp3r2q>Dpapu5R^G-)l3h!3uN`mB$Ls- z()XWZR88*<%Lpmk=|R)!`jy?Z+mxF1%4m?&d9C>TL)Sc#`Ciaz-QoqV-omPN6eE~? z-y@?zLieif=8jk9q*gP{)QGQ#M5l{Dp24E7UA{F7OEGx_51SZ!a6{@l2iD$(h5k$n znxavmX#G|Em#}G$@4)x@mA4ujPlZb6E8N(=r|5hCHf-7W&lq-7c~+XKn~*<+^@t^B~T!PnHZ~UkVy;{sBYO;2f!pR^A#vw0X3_ZfTn(E z26qH`Y1o$r1C}GFrXN$=RVCpB1s-ZZ(zFH=UVe)%y+4T?wSp1YEX328EYPp{it66Q#8Htc)$N-F6p`2}GVg=r zY=PnhbH#cZ>HUQ4A&5|GllujeP%9-++sO8@*ZKQ-1yEaFcl@{b{kYiF===*g3U6y^ z0e#N?B&PicA+2ZD)p;R~+ELv-OPv=DLMn81z%+f!Gg&7Brkc<83z*x|`oG;ILumas z{8Suh2?`ZIcG}Eu?cZjDv5Mkzq5V6`10z!9hXx#XpDr`9tibH8{KFVz|$_gzGhvw+_C>1 zMkiM}Dv;71ZYG5x5Tqp#=^0uG0+Q^jCu~bHK`NFvEIYm{Yz>?@yR_N-q0PYe8JOwI zfA~f^azCrS)ShCEhG|lcS+s$fbYCBAQdX?#>+m(=T-(3TV)C0)yL`oM{G_jr6zG2a zcz4AvwTog2N64NKVrb}5{84V=z=AVv*&hmF&#BT~Wr)$WrY~2#5Ed7KR?qk^wcG%6 zJ-7a)a(m2j=H$#i>Y&H%i)F}0^J>pUGcW<()Rj(PzUpY#Q{#^XHdLi`0r|t+pw{^~ zxk#mV5TM>&R5LSdAytfL{qEv#4!2$%d3zbX(^rp*KA&ye?-E}Of&UFJ9WGO`Lbo(d z*?P}fXO4>2z}xC@snK-z(BSt2rYK|3qF;+YSdE+jec2v1s@5pP4JfV zg26OPy36I1EApEV9n@+{+Pl=55H`kbH>H7;RGfwo^UH3q@d}-$HRfu5}o>Cd<$H8D}<`yxd z!7>xB>_~-vl5OS=xQ3tjGGzjr2U?RhSDH3_2bA%Y)t9o4i z`+;EpHB^=;JdnCStlZ`&`%mtct_3);wA}8jhU4Fzwg+gr-F%rN9_W?R@`Ed;2U)s{ zdof^6tzNcfXkS!0l5EcvN!7{%B`aa(u<655dtxgeAVMIBG8ew4pK9iasien746-@; zREMl`yYfs76>Q_U`Epw})TS7J3p3k|`xl8%VJf)7gl@LW`Y)1Sk=>EbdHg#!S#q@5 zu1Id|GymFo7@K3Wt0W;kt`<*4%FZt@ezN2!vt5$y3o#QfsPtI6KDL@BN+;V)Z$e

l)oFUY1mqzCZ4N&Yo@g&97tOaU47=r^eB{Ror*YO@_$p;8iL@>SgtA*))i%qa12EL?BaY60MU2EF*p{h0IBKr ztq_64PCoK*Trv<2Aq5+|ahI_hG{|XqPhN0vhp1HgriP2jiK%TCsm6(ofHyOaZS)I4 zvUh;pj;y|>+kA1+a5Psq#Gv@CGrGoR*!n$7t$!f#Oo;QFh<{XYK?ZNluqaTdCYWrY zO#sJ3@bEysC7vcpYs^#`c;N%1^HARHH}E9IZMc283Q>9xXQw}QekVfv7v}que2kB6 z87c8B_5B?wYw_(H4JhB=7R42j=7@+|GpJ@A6kixoX-(ZkHvQF(i}j5HKyFW>Q! z#bNX40N2+6kZpu=pb?rz@ ztbd>ioFX;D5P1gBzIX;p;4~%4_=sYFRiaT!>Bq8dZXo$ii&Nxx7)N0bGQee_28LDD zh8rpvpgBvOMtmKg6ag$~5?upR6LZmo3WOhku#3qaBsQo4O}@3iXN-SiFESv4%mfV` zcl08F1dt>-ms9oU zFXc#=(3A@oPLZ=ufEa^izBw)B6EJ>%EjF==U)n^QDB@nU^(mk4hE`=tr9bGB>}B<_ zpAax%2Hz*7-ue47;}d$FO=ZlVhjIl^vtqoYtQYJeTf8$05-Pq0A?)^X9&h}t5VP&* zHuRG|d{dPCNvE@nc_6m(QdG3Zy>FbWSvHTVfOzm=#-h@8JX3gMSYd2jVeqHH6{Kpg z0eCM4lTV)!tidx&D}&&RkQ5GN5@u_>r@j9W@MsJvjZhmSTUW$d<%OfzQW;)}Zxk)x zCtf#)ua^qzbCX+$sU#@(N!QnDzM`3Q-#Q}&5m7IfWDX91E8HvTJgIL>5_2wEkKsNR zBD-sJDMFlkK#_VqIXYv&FA;P0>QnMrH4{||IaXvKa+tlyB8r{N;Z^OF!oSrpJJ9$E zq@M!mZXGx#A9VLVrLQJlLR~;gniRfs=gy=Dk7~&AztFtQe<>%LKrIM_4zn{R&w^t> ziVKj^7=HjpP$E|Uvroxo!dYiak)WiKEV|`u^fM-qEl=Pu+ulu4hk71sw1yL3D0@2(ENsrW@F!xyT#zqcp66(op$9()w9WU z$2u6LWLc#oA||jt>BQgdI`Xmla4*zGB0ITgzYkrmeCUDPTf~gl{~Mmk8ct_696|T= zQuJ7a{#0W0W{gvfdR=945QRjXTXFyq~|nC3t)y z*Al1L{zpm{y(^9jox*T4O~lD6n$MMws^yh zRCT7(@L-=Jfeo#y$+#I_XrkN{+YK#q=;3pb2lzixHts!N1HXfjc!u^fsZ4}qK^GH> z(gX#GI5;}l?OW8`Tvbkd72h_|)ePsL!#tsh~>L*VN6b^ zOZhvc>N8bwR`Dc*(1&36$bSV|@)|$ugO@oRZuw4r8_|))OECB5_vCMc@R`ItoLQkV z1}&}Qc7oyMq=BJboOo15cje+xB0Hz`YQNn$S`UERVim&AcQSNoacE2b?>w9=pfHEe zxUZo<8klY2Je~Dforl#v^tEZ}4l?CbxAaYqs{m#1`?{_D)7X-;cX6KscAh?B_XuoF ze2mUqfEb@HXbGst(~w$udFOwsSF4Tirq^>geHK z{797qGHU5`*Ya;_dIo<0cfkC* z+3*6>t~%{+^D)CjmV;03Rt3AHrSA zBFUgXQaBT&nCMwWt3#G4ae1*a;8e?;VhbthaHg31e2pGANp zTT-z+3dcKEctjwI{|z1pV)6+75F|5xyATmTj|6k4`F{U8#P^8M9piZQ{*Z&P!lZm9 z<|-W0a^5L2jI;$}bJ6g^Od%8qRmZpVq>}K0OgI(bDNy)Ha(TMkp?)Oc&&E3l2vPYc zrU6Ht2mM4M0)2XcLH*YTb4SnDQL1_VS?ix)qd50_={av#ZqqWOtQ2|`DJQ)qnGBQ% zlQ}zXwZ!YZiHl#NiOU+PzW}b1F)9Xyrcq4wy`B-)sd)c7-%sP-Hw1(4Ou&mRR@?7c z;}3kih2Rd--40fHFFY#Gpa?u*8kQ{1+@N~dGJm*w>8xyc5z3|mqE(cLc&}4A_tlRM zC>gQ1vyT1@GRJ%+67>YR(dIycsL4&sC{LGc#H@*637QR+P zO~;gdWS2$1qfn_+qX?eWYjt6x^|0&BIg{KsD-+ZK*$4z~4X$D@_f68o`sg z>=$lnlN2vb+u;jbRTi;lPAW$iV1e4uuyA;waIWZi__Vm2^6r zUD6MXHZEFksMyKu%&6Ynt`&qnFp-~;@K*f6nr_dP&5J$XRvW!J&v zToU=>flg&~z5KfT%MQ~z>@UvY12L|%-Ex3Mgr}#`9OVZzbZQJ0bE)oIC(u#SVI^b- zA)S^dKR0&WhCyr-g(g*QW%tF;N-s8PHv8{@u}y-I38NJV9k|6xx}&=tco}lO{7rJp zN=p~4$g;AE)jJvt@LfQL;I_SxCW-XQS(_o3Q!~OI+K? zSV`Jj_e9jis`ldce}B9@Azcj$2Mv;m#;!_a_VJ~%;_*vVM%g8c>9sA2k8)9!_~oYq za6-qO_%|{1xRA3wnNlFHBhz(%E!;IQdL0N1t^b2 z!XPb*yKZ7Sl*}J~vnG|<#&qbX;z*Mhr&%RsBv){opv+~rMX_);Qm6`}4*1sh77I4B zD4x*Iu-$i=le{FJ(95trM57C=|LZELo~nROhP=4jDrqL-(zjUoK&+6{lhxIX^jhdB z_f&-(i1>KB{y;eB zdn0wmsNcV#`-`sd-5H^N*Fg8@hg?4fJ0fAEfIvpM65>Xh7IOtJx8uGf$Pc-M##Q!N z0hLDDLQy@vLJ+`0`XZgmd-ibtTZdmv*oR$CFdWo8#x!vt4>6#QZRS_IL2Ll zbNXtBVTd8;vRe6O{shqwOzu?nYFrs~L;(R+u$jl>YFEJ|4kLy3aPPrykp*leWhg3l zXLXXE{hEUHqqrPvmM?R`jkpmZ#aej-h0ae59hUSNc{Wi=b%9SlQ`b1)BuzI2N@NeB!YrJ1n!c69jQ*m6N6&ZxA2; zZKac^E@JnKOx}^@Wyay;afezw=gLv0vV;eutP7}IpyB3m7gc{P;*6UDvgFx(zJQS$ zqeC(LJF~)|;*@llQgQ6^M`i^=EM9MjX$q#1+r;~N^Ya{m1JsC?nWy+3K_3O9RO)*v z6r+_);rPn+{)DN^M9H-4Q7+&{u?mkJOMxYA5c~$&&tt$z=+SOB{~4yxW=(xtwwyy7 zM9Xrp87)dhxxSowre6J883IUh?p-OYsY%IziL2!tUs8dBleRN~cfbDXOXM0-`E~%C zrj;{})cbsq-GGl+kLjsvW*Zo#!~30E7#UBSNuTck?5NC8NAGcjK~i#{_pr>c?6t}U zl#Fag#Hq`H)iRN!kXr1I5;X#C74`kk#Hx;OE{G3!*-l>5X1pgJY%qsw&MDxl9$_Stmz+AxvO1?AWUJ*U%GR3XCbQoDnZFgS9K>Qg$mzWmOP`{-Ul)h zhgj|MS>l;u8falh{mBZZJFvh^hUOM8DJtf0fAeBH!~FpR zV0;tN-GFj*>>`e*)Q;MMXyc2w932K}0+(~2y`w0E9@?F4kqOr8dL`R>ODFY}6>bG) zuV@nQdhBHKIi&D3=X^v>#;%fK*0=Uzf$OaL+#KZGf9`6rN&mEHW9I6|kLFH-=;yqr8S~M}af?5>NjQ=XYLqv~z;Owv9o&wVFVFC)P3clio3=A~7v; z06zk&t?;tKrzqp8PE6KUgr%e%KX#*Rn#FcH1)DvyR%T!~4&jOPDnpI;bW}biXu!iX zV3hnqO)mX@v>+x8L*k4ca+GDb;h(@kndrLzx|;cUHR7RklTP6+@n zi&^lZTopekir#*$e&R2{8)Cx?8UD=qgJ`@N2M@+ng{x8}^`ury-&N|(fW-K4VmA#D&oJU_Vbbm@ZHd)-|OAP(f+RBkUX3zuTIIw%@xvWD;6`-kJw zFu-Yg;zHxn0@qEDhNOhYEmWHZ`P{ekC#Pzo&%5M0r?R;npY=cHzFRnaxPVmtgb zqo35&_5KGdB@61bQQS{CxSC%I(&}T4o#3ywB#FPuQuL!wRYY8aW#cG(SjLUKMnqg8 zV^YN6R-*hb;R#tNk|G~5d)Qq2urWOZ_YZMkeu6z?`PBW&GrNpfGUgKe6ov_TX(B%m znB@WkPkBuKfWfY1tZQrp>uzAl$YQ5s!9cUiP?$tcJh&|!NfyC<6`4Ht_hUf2a;%F> zI3_;`%gJSSf?dEx2Z&3GZiC)FN2w~^P6BS;>;{srAlkKoJ=sP5rruJ^q9(Pu5ALBe z;N~x(^J;cBn0a=$iTb>8JQKPTF~SWbpk-q$x823;O;8c7Y7W-*dDafJ8;K0@L?lUaVQ3&2p$^!Q>zJ7>|Q{QLN zofyafz%TD4Uq9VL32?XAEr3?YNy)#$oDWZ<0SIiO*sJ`~11R07eDqTWq_9-f$WX99Vu7CmR5q0C;5)=e&w627M-}2H zi-|zZ2or&13pv|dW5V)=LOxLg*79DH-V~?&*rx`&`ZIFqpYL6H4*|G`JAk@p{lqNc z&#nMuBT?}r`+hi55Js2_##IOxlDAG+m>u0|?JvNo;7f>TPBxfD_MopmcwvG$Jj9t4 z*ee+zL(58-8@)~l;YPCx@I50(5ZwtH;f5RF{#ur`$W)dW0Bq(PjBf+pyeT=l6Eeb$ zE3-sR#tM<*R5$z77r;&RPd^;RDMR+Dc);PjP!t{*#2T>8W`LHbro0`4Y%y4Haaj?c z83fr|kS%<9z`Re24|ACtxnV zjyi+;49OP2P4v$UV6X$n=LyKvd&^o12n2yN*ee3SX2xIxoEjK;=2hA^tr#xe0se@8 z{2(uaUj<%PEEK0m*ryNx<|{2LIRgWdIlu>y!!&0KMPp-4KT5U~e_Mc_4U5(qR>=Vz zT%Mmdh;SC+9O%bGzTX6-P|8IG_}q06#FTI+M79;fWytYk&x=JiaD(t3%B4k27|&Ndb2?Uof~JIhz%?M0I6fXAW`un}vkN1c^w2)ThYj#Ledp~a zIK>kN8O&`%pHlH+px#vxWOrKO`z4%n`aYC(c?%po`0TF(rU6SLLG=4lc9t#ih+zm? zmDzb<&?=Y#joaF(t$e*)AuIYAz1!veKa~viHHgL}btapMxA96HK}S6;#VxA^qSf+E zUY_qTnz1ZQ3C`#896gE|UYs`NBAM zqaH@P_cKrijlW$b_Z|{df)Y@AwU6}bAMn5KA72!7Ro79R?5}V><$HQ?z>je8J2&RUk?acCstNPNhrO%hi zu5>Fvz4nq-!L5AD<|pkH6Q>|I zx*YC}@&1ZiNW*r;)AjIg*ZA%tcy3H%nzvvqWkz7A-ob%K3Ja4^tP)>&x~6vduRYTWk4S#d4|ORqZ#qsGqsa+fCSl(w6Kmd^#y|k zF&Y{@k$3R|#782sml9Os9K&OEyE4>4SR#AquJRd)fjaJ&omKQ&*6XM~%0$EdmEbdj zj|BIMb{GXJ-dnhRLp@g3%-1W8z}oV5tt5w}PEy8rjqrfqoGS6A0+$YF4y!J)3^o;h z&75C;LXA~gG>*0|B#qvLBaJS0@YM%tHH~pURJ|-ek2UqsM+$~~Ppvy%3G3LLP#8cNJM9?Z<4sQXO^kVDn3Iz5Xf%m5m(Kb$^ENS>yk8_7Wgi;@CIs?1-`S z>)XB=5~n1;bdK!n50B5P+(;&-vzkT95t!^?7jxj&JM=lJji<-tTF!Km*VIhCK@->lBIbuJez_KFDq?-$n-K#d!G`k?%YThK)yTCn6(J z|HBcsYRw|T8!z^=r8$8EpUm1pWq_64gl>qP`|CKS)8#md@4QlF_$2Nd@6x;j$k{lo0R3soao^=4G79b53d!C3|!Ccbhfd=|vT zjhB1Jiuk*GstBMrR}2bujFJIjGT(6&BzB;PU4H^K8NJO$=Y9jFTqkCHo2mNSGQ_~j z07cKQMW?j_Tsc&mAQGi^#_{PRH_>0*f2=Q|xS3?6zsNmPRCA?cg?)*vEIWfekT60e zi&1d#yC!7`3qPU2BR;`uPFES!-?l5Ix)7ab+KzqrXMT1)^d!NLs*z8r%^Ri;jq1`l zdF)%J-$&-q6IZwW`HpKvBP;9!svbBy@gY0G`X|l5m{$qq!Xy)Jgd1zr7~#OGz8E1v z`Y-ATVJD%X3M)c<`?RVUakX8O95oA{fFCds(f0=hXZbubo@G>zoKk6qJkdeMYAK?R zJhK5O4dJ7yXLwi_A;4N@obM}6d$@6S)_@Jfp7!C{Nl0?(43#o^Ki6pZtX${E^M&$f z%ho)W*c1j_?;~8vIU}2TxeN9_3Ta;Hnd5zbCCw8@x<-r-+ z*(HKZkLO5#Hg?nMRiKnFlfrhNo;{^Jq$%M?lI|I1T#FNdT0P|1N1 z-n^*V2{z;UP{t8{^M=2ba$$NBzMB&a;;z(HX9rwJgO%^>+8iiA&&1?7r@zhR@%a!O zu8cNUU3op62yf{9lyBF=GxTSvi*A=c=i00csBV8qsm$ugC)nQrmti{>xM*{5kPUd! z5T0!}HCvskaGW}9N%S0pIr|M2RY9dBJBY>yrB_gs&wfnUv??4PQdqu*LG0wjlT^ z0$)9Om3%h+2Y`Z;BGO&WsZRO5U`DuTK;>sUC>BS*M`M5xMyA7KgnxuauDaUV_L z(bM%wQ)g+q7@b22&d!266&8mACBe@P^4IxeLM(=f1kBS4En4TdAvO4)lVxu%$Ced# zFpb8DU+y)w@+qW3XY+fD3p5Xc4|ptws~Jrh&{jNK)8Y*s%OkYp8jO9z;!|`^j4*4j z#>yP#qZA^4ut0OP^HS24<7X(2R9opZ=O*T%$?y=x%thANI*AsWer;Y*n2%JTu6NRT zI>9fMq)ISS74xWQv~&`s+5Z>RU{{Wlp=jw~E+lR;ei*1M+w@+J`yc+X(2V&U5E|pW zP`WL{%}@--;TyW6$iV&*Tb7Zugw(i`8$7ix%o7hA7_w-(K&({FG;_Uo^FZ*vF5YV;R<_k2Do2Jm@>v%FJ2`)N^w zGpCxb+olS^B-KA1^?!VarD6f9cy6(=HC#IkbS%SH=N-XS&rMux-&^wZ)U= zco~W%M~#sHXKYFU7NANo9{FqWmk#Tw#SW- zPbcT~uQ%TglPWOSMlIDWa_gqsBE)<>5cE}f9xsl!#^0d`bCH=nxk?Mh6z+1pts=i< zyMs0_f2W>`)SH#@YEbzH+SXE5*J0DNME0AYCSGG6Rib}*K+iB|wGa1B>^bdiXvEga zh+kz4_Z;w?7NOb9@NES5$@r<9V(Ey1)70wFOwXNQ_-&n`-qdQbJ#GQX#H?{PyA4jw z%d6SKe_#9r%NdUgx8_7gU%00#sy|)xo4O(9el3RnL#q=)v(O@h!M~Ly+MZJp!^!hn z?GPtLCrm7YB*aTLzLfe)mayh~XaFm!8bfe8;|0RduX{K3HMwAo^F1)fa>@9Gkp1<< zSU#9S>U!LQT6u_NpV$RzhPU{(;Oo7tsq5X}eE0f_DgmoLIWxGCm{=9iqE%J>x!fp$ zzN0xKQ;feZ9E34Jp~T>COAoC#*>WF#vh)E8kpzKzL6QsTk+U0N6OgTiWhLbP$eT_g zXGam<`_?0J!Q9>88|iR4Iti}fBJ8cm zr;ko8eFAJXl*$5n{gTA~p3#LnTT^f3YjMP_&;Y9l3Jo*+v_;XHJKPp$+$3IrNlvsz zWPB&{utDWA2xyU|TUoKF6PtuDr(#=}Y8VM5w^x{}&Dci1Gf-ezCa+((Nu*pQi}dJsp*~&i**;GfW}6E=1^pFNPy<;E zX!7QPgRKr*cV$|K zzHL25$VHbPs5fe&@;-PvtAWCtq(m&(V z1*5rd{IpfDOjnZF?8h5_f!#T8jUJ^^Qx)DegqLHgEH3rgOD%*Rf?o{O^md~zM}zxQ zKYP8X(A+D`wg`F}wqx|?D!LT9y}O9ZKfl5*+V-Ju-R~wtET0Y~t^8sJS3X+`eTQAE z@e}QXW@yq+)(KlNAJK+GxE$R?9LK!rBt};_fgiy)l;{!5)mt=}#XbLs?hNFTc(+vs z?yiRumm_mB8PZ%f^EA`OjTI--s+P4aZ z-If{2qRWUj6g{HjVduem>5uMV(+$q%OTw3Dq;eyBQS=gO**S861dg_OJ-Yjhs_@Ps zJVX12RlU!Fk@tlN9<=n0)GlxsuID6_6q-B3zHzN+OO)=N*55Af7Hql?1tMLqDE?PLJ8ror<`4kTzPD4AWL`kz2>pnt5? zPh7O3$+=Vm%>$Q6ezbhj>?y3az8R|d?@5N`BkV5;>N5Bv8@ygQ-D~~uOY}o&?B3sr zpbY;|XkQq<=47Y_#Qb7j_pLr7U6qmR3sn^=^ET( z#j(IkU%M0-WTT4Ugw#BMYPjW|hz-?sko5ei$db9E+AJ;RI|EUBU$OnrAFH{9<$$N7 z!~1LJejqmrIJ*T-ti+syK2ETvB+4BCoMZ;Q@sAj*;+VE2A589I!GJU2 zd~A*pUUc*C-Q)I9yd0k?^yn|GpW$o&eDH?ejp2dPD4JYe%M?Zi%iX>y(8MxAtLT7; z^nUV+Z6Z>|JqUGl%P3wO2lQu&of+!53~DaYi)n^vV=47~w+Nppe~Xtybu>caH2ytI z*;vF&@}Sy^Z0LtCk<)dPch)faD!9pPz;@>d}1q zldy&UQCAZ~ug|8c<|)EX0vWWd`Q*YZPC)F7FDJL+KI0Nv0{CG7nlz3GUK*n zXzS6yKipMPMBs#(-bS89S2Ybp?N>AyWr2|f%)ef^gl(wy6WF_}>hYrD$e`(rRWT`h zR8=*M+nnYz`J>Fhnoo+VOf(v*N?L}HV1Gb0qKH6a>nf56fy1_kyT54`Xj4V0TJ2SL z)ovU)6^*n9srZ@sXiqNfoYbFm^BKKM< zx4<>ep1WGQAMQzB0&eqk`t4qBx7mEc(;H-$yOFpi|H+|sG+`bq_1r9cmw9+N=oFi+ zkZeUPE10l;6ZIiAojb<0tCIPwr$mK@vI<=Wr(Vu%T728_#)bWlgW659@2-LZlQPPb zS$*cycyqH(biB*>PxYg9%s!Ks^#G^(u?DoUeH#jDfE)eoWwVd)YnA%%XR29!x7|Et zB!g*eoAe@%ZxeQZY29=9ItjH=ApG@|`t!rpfFDw@jc;V&m3}v=&fuuW|45hz-q>|i zd!i&zOJ2y-Nnw_+6pe={eB5oEmwkL>?{1$u#Al?X%Po;Y&;Hi-2dtKOfqO}j#sROq zm~|@}<9C&&#q=KvuuYDwnwfpUosI5NqxuAojv{U?r*!zKnZ~!CmPSu?Un=exZ|4-} zMS7ctOAQ<+nJ5taU-~goE7wJ0_b~>HduKeYW2UTxO03N?XbfsaH*PD)oXvE*sFLlp zyxPTuq6QZC5Hj7Yt)Xf3u;i{7Ixi1~*b$)L+F*YdXkZWJb|F@RR$6$oX`wIfs4@T4 zm`1~dKy<}$^%p=5+D>2^*%G7j3?+06nD+-|=Es>jt*8(UugL`?!8+iu>=6q}a8p_}GB z@>?iai#lynW@%?ugsM8P_TuT93PFK80KZRVc)JznCht(aW%>F5iJ+uJRO5p=nJ8p1 z#vkX|W0T+J>22-0%VmsXC*tyu!2K+EGKZbZwR>1JtY^E6-oWb|mpR+tqG+e!1={6N zgF{yDgB7|#Zf8I4nC!JnD^z50)iY$!B4VB8mt<=#H1lq2z$44b?`)eSu1yhWIe;l( z??+nGn9MWPGl^#mzGuXnE`PbMr%` zHfFE;JL`xACXhg3j}kkX%Lx7fZyL<(NgJ{0qtDUn1iSo$TjaP7F*ozIzefe8;_ zC#S}19^jf1RUl}`Yttt8ALXh-n6hFe`6Sq+11}1)OKx+Y*Ki7xci2-Tn=4OsjDM%T zkufFeD~93GN)XbmtFy@88*)w*7^r`E*cXdn$RAa)KWUA7d25$d zn%E9FOj@3^-S5@Y|6q%DRsZom)0Wi;gsUek&!HOQTebF0<)Z3;KkMye^)mcm`!l3H z?qxNyIG@yvqheCN-|^E$6K!-glBO0|^p$!u09bTZtF+mruHt@#mCG2md~Wrda;Z@D z*m#PJ6~}!r6~_68%3`3(ha1AZ50&#kl@B5ZaUUwJ%l8FmYvfsgDvKM`e_Y5~7@4J} zvFy#$k8>#(BoCr1G>s$LE@`snKY7{T=Ub1f&O1je9n7^QXr@Z$OgvIxl7}9qJGS;` z;Q&OeJA&x#+ukx%U^?J-*iD$ONhKsTL?wD8GwU%pD~>r912U zHBxl8S2w@U-2qGF!oTUv_kn8;#fe{}yUygSuNXGF|g4T6s z7ZABbkbq$?%iLi5Q}Z4V*+1d9!rF zY}0_tqy=r4WwLN=gB!o^-?S>Y#*kZGBB~IyCu9%Yd*xz-KdgClwh?za5%=Z1gwMJa zM`!7J40?2gi{4NjT5FbgLc1;<#uqBbumLucnBs4s?ONnMvR4n~VMZI)+Br zzjcluep$CfZOSp6N9j5QSsN0XVn~Sn zuD@ST;ZJ$_E&#Xo6J`K;bCpkU)|7kc40UU%%WCh0U8xU{hqQlA^iWx4Sr@vpIda81 z-iHht$!P9DH!E)-q1|W0e0LepksAskNt8fzK346Rs*{N6K&F%OH{STnQ3(np4^7+7 z+$-d?A?z~Jz~!`2>yvxvBQ2$wM>^tXs9S0X9ib}D!&nwMhq5k!nu)MIa7NnZMb1ye z50hHucX%FlX zwh~STjh!(?o3R zR$y8{+p9AR(ChghnuY^xriMEv1wZ{Q>5=powlq4T2|@dD*z?ofhj$HnHC?dHp)1*{ z#lVDIAMSoh^URBzqHP{Jpr=xZ!IVN~<|VoOY2@RF@dJg+|E=gk|C5%V_(+VVE&yEO z$eAPSDSSj3=wxbED{NUdum<-iJt38kC<};&*|UsY6++2Ih|3Rw`W#l$k%4ih&a(o%>OfNh%K}Zct+T!2GaO&f$)Qlzc!A+*~nr;qKjKmw|z|H(&;{)8oi9xXi6t}N1ov1c}vkLdWWx_QS?rnS|f3^u-RCN?! zYudaw*(5$|X5?6Qcqx%C^N*;5p=|yBTL-G|v8gNBEQJ|YQ$UzQ=E+GnORKmyr- zT{vYw9?Ag<>_VFWvm+^V;J}%fsSUY+Mb|#Uw7?@TY+A*VfMmgse|wKj0tGDno*{9#g{CT;VVd*d?3JkFbFk{D;P1QEgI9YDLZ@ZR9BkoVV9`u} zOekjr(_gCc$?6H60C`M}9`8HFnBA9~_rs15x+4NV3vjT@9 zhD9uAcc0IB7RJXMW#Ek zkDsh2h($V;`I-8KQ5wLrm*De%)V&DQS0O`v#r7y3@8wzks?y4l%}~$sboSALgb&Iq z$lPhbK~jq%MdI{5B2 z+)aVM34?@mV~n7k=m{DhtV~(}4KHa~^$WM&-7S)5_}Mlq!>facpNP1)u-K-fP?zz( zF#msR2jCG!RtqDJWmg17oUlPW&TZme!G-n|cF&u{ip^Y-#sZ`1s=cdmX+&K7t0z!7 z(zjKWL0GNmPH(;Y`H6A!G0?S5c_G6Y_vdj;?E&dIO+X1Vqmrt_bxr_gNmn-Nan29JS%JCM>1!ZUcp*tAw|g76F;F{k^#sR!X1 zF6+E#y(~c*t(GNH%N6=*(}#9%cZ`_r`xH?0Q(BL*W{NxtP1kb%!^S>waKB0{>=>VY zq@j%y3%e~o_8%*Ec4J|;!^b{dYw%}bx5vkx>NPBkh24RPy|mdHL90;au22BNVKb5q zsq_B;tB0JfcVJx|c;+KV%HkrmT4|itAXCW!^ks|us(0+T0X*+;-X||s^z!-WdRe?w zrPoqzTdkGH0`P}C#|3Q|{tAF^85}#8&(cP%ijFZ#b6<^Irq?Nr<_sU#wp?r5_(LV| z^wKJ$TeC8h&1cY=^g6Xt8n4v?dug9W?Fm~E_xx9|ezDa26jtmq`PlS<`INb%)x--` z&x30|$463DXb-c%$P@+kzCJyQnCQ7&1}^wGI?=)$O9aQnfbPocpu;o@&23 zPS_4`Z<^QLynfMDr&6nBdZ}!v%3vc&z(zY{>)f@Bv_rAcz8vq+o{=_@!xW8L+YC_x zOOMZk;twA@Irs)Rk*^`Gz-Qq^t(J^h3R@SGAT`P&)qrO{&w0^e!oojif`_~t7Sv#6 zF#E8k9ja2O62E>?mMXMbV5a$bW!>2|1KP#{Bz;?kx3aLg=avH^jZx)%6)*TvLt^7@ z$|cHOP+8o6v{vPSYIiSM*!2^L$~D0mKU>%i6o|^#%TGsG*e4W-N_pt2#c;lq5LEg1 zwdK3vd`VJen@%N%!1o2jX zJk>bjJa=D8ifFc>cF+2TyDy7M zK?o2jX{4+h`2D1JVo60kfj-Nr+Ut&|4?YzA+vi`D=N}K-! LqW$og#cL=429()Lj?hmZb@kY>F(|>rBM)+2I($A8bmr30g-Ny?(USlGy8nc zcb|LtW6sQ8?^^49cO5u02ddD!NZE`yqg%U zlP90*JF4R!U`ZI`{4mXZ6yLi*#rl-%`tY85wXwz2YGK7P>f6oxzzu{;$WuNrGAZR)&go8!fc9|i9g zj$Pgl69x^>VaW3k_aV{o&KU8cq|G1uFJL>rAAS(TF@Yh^Lfm(sj<;#Yskz5RgNP?5 z+SKG?w{T3FbWj!dPo|5PZS~Kldpb%%%;E(HZjn;iN>A`O&81?5{1|g@%G<{>a0-OI zD^AuX4E7>=RD`e7$l5*`29V&O_KNp$mHF)}6A7H|9OD$9B)GbJZQb(quegOqf6Tu} z#@;I~Uw|%rd-9F0bb3(RT0DNMepUC+g-_Gp=2zuxc8iYX+&*P1XQPP+j&P zhu1b+3z%FPC4andb}IJ0)=bbQxB1{(ob#}gbRg2r)yen7r96V6uk3lTN$3$H*49w_ zzqk)>B;Rhd=grgo-N?24)cRkf7q=8zq=}3fj8-zsf}<3Cl&9G$+ti|qKG8TS?&d!$ z%DDV%hPvi!W}!D&XE3Qn$A8Aiza;|+uKYDyS-kr5vtGu@*UTtQIn_W*Q-c;F&ta)Q zfi*Pf;Nv(oI0Du2$Kd=ae9VtI(eN5;%^?}9NGl$c7BhJ^aS#K*{^p7!vze}BQr;%h%&zO}4pHYIMMa{pe1lxdj$ zQc(83ethIJw=Q>prc)#kQ4v)2Gv_mQme}$+m9i3@)<{ZZ-+jpf5iEw`!|2~ ztIcKc?|+pvx%6ZYMJoJAqOxsOk=k!a@Rei3u`(xwg+)WYy+S6qw2+ck;%4$UzMYny z&%pk3zI`ghKQq%i8Len4e_^mm`lQS8`;I|RwS6jzTgO<2_sP*-q)ryM%lW&>g`~}Z z%5+bz2a=qc4!_=KmE-*>aPQpyM;9@-t!Go!TRA1wnUGJ*`Jnkvbv4!gN%uv39~Ewn z(Uft8t)0T(!*6zVyw!zoT^>`KsoNK|52E5P+-Ldwy&ZF$G(xiXp?-Zys23kWEpD#S zR9tP=`kfF@K9PZHmeUo*d1qhkAp1}9^+ADnp}EfKfA1Fi_N8c)om{G^ z7gLbyH&CTmJj}lKePn_Cn3%`7&Md{A{LNN#KW;_*%%GOmT#wx3O`6$OTSdKN`HymP zR+7z=eUivs!;O9ItGhhjZ$@PDB!(q1@u`+Mc>eemX@AizL+DPdL!Pi!u^1J7!<@&)p*fW* zvm(h8ms7^Km`jv=uO`08K(lXeYwE!4$J@uLa@B(5X}&mwpT(3bxCq+S=iLK7mQ>JJ z-x;G{#x|PVNUmh=KZZ*`vmmU`Q^GDPqem7@nydw=B`;2#@ z^xXvKdm8hbk@rg{1$E!uBga@UuM1|}$D?_q8;X;fG38P@)3zWmzDbF@R>!xyuq{Yr z`MVWoFL3MQNUs~iw2M3LR6u9bu3zS*F5^@)Zo(CIud41deg&RQ^J<^g8TZuH zzm~j-yE|2UYPa=^#i2aB=IK?NzFJhw*qc{D8;1qbX?U;w?7q)xsM+MreM*kfz2slO z%uU8DUl62X`Zrr}m zzelcaQR0%>ma@FW;r4ALX^`AT+NN=RMKZyyFXGJmCR41q9aq^YR8G{rJcP^?|C^ZV zH09?gio(U!#K3J>V}_P5^4xl-PntCSMc&X~EF7()svUk;h~ZUX=8=rP7H zmU%L1H0fgIJYx*g#C?Zfy?0~(xAPQZjA5B4dCk1M!_By=EY?msu&v_GJr%b)r+seW zw5vCNLOcrFQj+Zs1)e<&NyO;RG1i++bnGcnz!m7$UgZp~sm2;##qITYT;lfQrsr7L ze08MgRQO_QH~*gI^5FO3%8@ta+;N5504!D%YC<_;K)XuqG$Ruc}kC3EEeJ%AsFJ*kSoDAPWeS7ltzNDpR)btBH`hR zw^!_)C-k}WL=!m^WlUcr>INv=ea#q{{z#nCpKi%mDKS?|RT!wrggSo`47pBL){d3k zQQFps9m>`_u=nn){tz1D2qLB!(afS}Q}5^m|1QGdW2sg1pI;i+Y2q zZoHgVvecuBzA@8z5f{WNjayQ6PuW?YT^16JusFtvz4b5BqiijkLN0ak@W-6Nbu8&d z`OlTV)s6X{Vgc0p#>1bvo?;&DC-d?eZ)$7d{1^@QyODPv10baw3zZkw@g86{0m(Cj zqyj9tj|6~#K)tUqOGx(sA^^||2vGD9l%#SjH5c-ELV#!>5CjEL3=RNzATgXyqk2Ev7P4tr@GdTHLv=-%9wbJ138-IQ4Q>+Et0i9moN7Kj` zUnf}t`CIW3Z5oKS0=P}YkL&V-BRX-WdCUD>BorWI7zKo|)q&6>Kw?z|q#!_Qbp#|$ zWzZ&x5SK=@$spPgah3@293XCj5Vu0aNrJczMBH1@mWW8AyAUMnjPO+gaZeF(hoG(e zJ;<;4E0Fz+kflY)YJqTdC6GD;BD@e0o(IBbaXfZGC@G%2nfOIML;eHNEATT2v!LKN(TP6CBT0Q(UH}N)Y1@8 z8G!f^Py_<{44~~|05u?>QUI~)0TXu>kTqgn7~Vtps{rU!89R0gkhyv^1@+rK$5+x=+JmbY35QPC&uq9-I z6=#SGR#!7v1($g4SxBA8r*trd7c8H75wJ=Ez>3EOTD*bKF62x;uLzJf1cIOd_jzdm zGL z@D$n~1D23@!2UIj7zStqh6+>%lqukB4|Ss;AFd-hFh~OiZxC-ih;IDf_oS~xoyfbO zH);_w$Up`iI8!2a{zS0zwLSqdk)R(0B;kJ8=LPx?0H6R*Rh_8gSTJz~5VN=+u@EZ3 z{M=7PK#1kTf`CF1Pz-Uj zpkM?P4IpoXR|W#gM?gsk2;pUbfD#Z;90Edk%^{!~1cX?g-Uu&Y1QdyY5Zl5P!m9-V zl_8)MAb5rF@>@H?XIak%-K7Q) zMT8I+xEN3adrm#ry+z(2qO(A>AmTj>;eL#Gs}TaE@<5Q$F=7w(MF<%HAv8pKB0z{Z z7YGF)_WzH7gpD8>0TQb&AjKngTs%Y@;yo)Ku?s38+O$Dj2SQvEh-)I+;t|`N6CzF@ z#65-LROgXCv!fFac=(Swa#~marz6Laj3Q()JkUG7QxQk#J^5k2`pcD{nG8<%&@((M zndAz?P`q&F!jV@N_JS5u%LilcyP2NXCZ3`#CTjY(>3hD2c!kRQOoY6fX#TE0uR49J z62_ut1(FoeWy0zLNd#MHBj@lO*R>Sl1Frz5ClC7;_*@n@#m?&83gaxkRT35MeGm|Q zlxoj`v%zA=rtKorTh?ehd^xK(rEN_c{3W6*c5_&(klS`7sqRjT(@#s>cHpMo}CZ=@4;hw&q5MDs!^rR8f2 zy+ki}q1R;SwfU8NZ9ViFAtPTKgp*}}MOC_yet)~IYWl%@pW13KQ7@{C>c0D@do*$# zLwhDlIb5l~%{Twv4(jyP@8;?i%c)c*){iG`C{v7gY>29bFF>Eh6lRX!r5|$=HQJ-Q z6XKSpIN=rKZ!Abh@W-d3`2ptTmf)QboK(dLgB?6Y+x5U~8LoCodHO;%728H)OyTba zwu^zH9xW3i7#|LOE0P{yu3Q_tK;+Bzhw}8XXQ51Kiu8L#I(%8>dqjj97W8Q5GZK>F z$G3VGzeER9QxFxrct%tLz#FgEP{${ zICX`DOx)^TO-b*VBZ6GsRDzC##6RJQgjAkWf{qzD>9vAUYMs-&;Cd}Ckou=|&ZiCU zHIJ|JZo}9GKVR6}>i*$#(!bet7vdKRF3%+LarqtQwTFx2+?ivIFMWKT6gaAMzQN`u zIXLa6Zz=N|%jh8Mjh(z%D|C9pK;XXhp}{6gPM2kR<3qMflj9r4*m9`JD~np6Wm+&~ z6Wf=0S}=4I+qTw=aFk@iF+jo%jeEKYv`8wYy~C-AKTghSUD4gBb;}*c{^KMDj&0z$ z^{R{{c8NPmpM$>Bj;6_6F@o$7eB=)}PJYR^D>r0=woXs8asHt9$kJZ%75%8$$4Eh=xLxhZO0!6YaiLavc?kGq~e ziN2YmctLaIy*|4XJABokC%7tMGvo7>>fjNboTBien0#Wc@2}ugR*CD6_xOxBPM!!Y z2UY^uHVXzExuGV)vsDkxs`f+*T-5*lEG=2(#|sY1{%hUxP8IZEy7adj-i*dYZPdO? zatpNI(tX*p-8RntZnF!1mI~T!wz&!)V|O7xy-XHxc-y7=I7UdGo|t`Tu8-3kEyrBU zeNbO-e5TT`8&_B}bT{QBXk3u;lVrH~KqAGfi>nfmkn4xCY-G|Ex5f;s6Mhpe%0b57 zr&B(U?P|p@UJL8alWgdB+h6s}3UXik3UTr05dLqh$AyG1hi@#ZdAowryMw66-Nw_f zxN7K~M6!S8@k@!DWegcA-R;QBJ^`lk>rTBCOB-E2;T`g*C;90W!z|H>gvCKL#y+6xAj;FZS>b$~GADG5u+&XKGtG9vaCx_wR7Op%_W( z#WrW~vWJD+$l?X|QOiHYmgoi@EUK0A{eMY6mx{}3Py3It2n=?U%6xD4#$1ZqBi%K< zYXqoPYPuWNrT+Q2C;R=}ETCu`Q|{zV#r;REVqMS&ecFGKlCLo4J`;mUhcBsjkvH+X z;Kf#u-`?!SPFsoET0Cc}B({s~s|VJ=Q7VJ z8Fz-swKkc3<|qGBCu$th`#(KcP-Hjj`1#}OAVI&;zuiS2b&Q*Db#W`s!3#e_JmNob zCUu$Gl$(e*G+Dd<@SPFT&%4!I!>NAQ_|r&#GMO$xn-?`*#d4-osGxp1Qnutn>2vl3 z=B7h6iH@N!8qM_+s-F1*TBe@|??-$I6L_W8a$yzhd!S?OUv`nx1%7lg-EQ()n5Gp3 z&&Suy4l38315_URGxMyP6&Mb#Jk5WOq-WpPjSrnagwI#k%nD2gSJXj!clXc-iG-=N zZ%D3nPgrCLLz&;aFhgE<*3gf)eyF$W{zq9P!R$ytXyD+W=|pVUm*wi;(M+(P_q(`d z%3uu{KcePa%P^WYJI0uYJ~Rb$2^|?N{fRu&+E@C)?ZVwIe96|OWd_TV`F@9ay|cvM zekhHJo+-@)$3-{`_g2=ac~FvATQvybqAq=MWS>mEi@r2gbaGR+%U!YcfsEzQS|615@1N59JrK`zuynvAZI%7TZdm z5Ktwxfg$eENBM>5{)&fJ?Cfd94ygzGqT(-0c9X1#q8ZyjlC z2*^pld}QdE<~bDXzk#zkncjMZJxt#n(7JPPnfbKq5}9Rg*yo~JkhIv};e~Ce>~hj} z7l$VMe0WMi!<#r3(h{@TXNNAu%3IBP%lVpL#(eT8`pYA_IkciJz8XhMHKLbt&gZ(I zwKV*e9&Nz&YwlmI@SG|mSx+?YF8DrGQgl_`U7e!E*tEtPg<^eTaC*Ku(SY3_X zotmcN9C_U#bhBNmp(WeAx9>QmV*U zS&T2veD7lHN=l=wTK!_c=nL7Qkj3;sA||uuxAE!{mg~r*x;6fj<^tIsfm<(|(a3KX zu>sc+-`j<&30UrrJlAzeK8bogm4EIbv_$cCSoWF{qp|$=Uc~vY1u<@_wYo!HM?Bp* zavRG&AEW7(rH+KT!?tf@#u+cJK2av-S9bPV(o7~c@Xz8u#Jw`!u6IeeYHq07wlM9F zydU5rA7hO6>}Vo$%(9Sc*daeYzZFfQwBGXXQ5#EjjJMGdy+K*E1HNt8_wZ9!fi`Q8 z^wHP53auAkdXIeSD}2q41~Tl64W^;(Z*T&tIdCqVdg(T}!L{%8Bct#7Pv1p?OUt*) zo1N*h?c!U4HH~wnC`bZ#8~`&b}g(DUeYy^9chMLf0B7nW`B@n)xNX2|0ET| zLrBw#HOGSziR5^gu`?x-#V@EznFm^*y($Gl*44RRKBe$wFk|b#aJ_2x>D084L7Ax( z>R%sY`=@h$9g=AudF6)nw$vhTcfYS5E2C4M-@*JF8+l28f$+g#569#g=B zpX@7btw2>19OLc?=Me!yy3h()67tik z0=s6yTBk5G)(C~mzgwjW<`=p^4XVFk5hJp%?{w1(-@pw4a4;#HCt<}q(qAhDBye!@ z1}yXy#*%F_(Of*9twIe9!!X+kc$=Vb1$L`oz~{6uJI)zatHc>mWLD?}=biOJ~KQDBP(!z^Ou^{!im2V`RoS{C7K{&6dIL)oZ<7I>@*ra*ncI3v!G3>dgK zfMgFspy7+|RyhNmD+F3V3Fx+&Pn|qAU&1YdV44TRGAAE#Mh zRd*8d)4}RgflKfNCG<~-l>A;PumIdtxQo-_$u@$;t@yc4-~B zDv+fKO!6^Csd|=>F9b%}0w!Hd!z2SJ%Z`--7LX-aq|IQt@o*~^LDNzPaKS{~10ex8 zBczc0Aj}m8@)mH&H6;HuA>S9sI{^6^IK&T%_fRk^sKJ(npnthwmrZC!F(>5LgXRV} z+OyXG+nH+nOOmf_X^Ku9q^~Li-)A}UribNi<+e28y`piM$etpv9Inudto(MO`+N25 z#6E)VNtPq4Y4xx7Rne;T?it|jdq5wBWaLD*V0P2oI-Xa9)b}@3g2q&5A1zs!jRMxk z+d_S2o@6&o^b0=z8+twSU9CWUA0!Z40)|!plBP4cnwOCe}$)@thyWRC%O2p9>7_T`Qpx8nu%e-1a$)DHY9r#kzbph3)^7MEQPxHebYh67BnWvORLSq)Gy9m`60d z=H&hRKWD8l=v3%aX|a|9!|(7mqpswKI7t@gpjl{b6Iy+2%P)r$fBB+>;r$$rgTmHl~$`uA7~xk5;k#d3W~wIOTF? z*wh{;cGQ||zBeRo(0nR9wPkPhMlNc6hJ81Yx~#zo91p+|V>c1AahJK@#fS1$Vuj%| zqhDfqNiLHwOpj44m~M>>B^ZakY4OR}uOc3h>TI%2pVC2^at<{)I;woFORj?|JeAvC zfqFg}&obnI>dA;Pg(-1?^P}20+E=XnHS>_e-Rij1^WOd=ZOzF~bBPn`PK!KGs~P04 zI(}7KLotmH)fwTS(a>YE_jciruhso`&arjow(s)lbz-m4G>biLsaf(uPn|Gr*XF<~ zDtu&AolA-}M;xc^TGA*%nBlt9D1kNoH&)x#dNvz%S5JniULHEJmxoU5;T9q2M1MA0 z%{sI+qsFqzr{|wh-ulPB?AN_niZ9C~WZ-`HzW7m^HU?+keD(DC=&Hgr_sU ztItj>&~fRQVV-P0kF_rC_Yg2j^xI8WDde%M9-H`O6duXWg=Wr>Jjia%y*xrn>S@2z zf0k@kQe{<l4{MxN<>nx((9tZnT2qPVCm z@vM%}4C~NBXq}{n#&10!-HGuqAG*ko7CwF1U(5B+h3YtLDoXeqx?uYE8NN^wzEE<~ zrR?YnR#uL-)Ool1_gHwyPdTNnc5Zo1|LQ!UyCiJNqH43)tAbPXnX-lWumM@gnc8S_ zLF{Cp`P2^#9cr_OZ#@?l1Tyew!s5ZxcSLnBNSZHxH#oEy?GmXcQl#neozM2DlEt4O z$(qnqP0*PKIb2TLTim+LJf@P_Uf%zdbbHun#8Pf8_V{{*uPW?FelDy30i&kP&UX1& zpj=66Fml-O?Tm3UA5|6ht^cW2D_ z?*;9A{HZ6p$I$P-&n&rzDXx~k=8?xRds=RC+2;S+>B->fCkI@~rNnN=1io`2#*SI7 zy=Rk=4P>7bY0ORihNceI6XwPluOr`H+@XG5H~-+XFV+psq;84~u^R(A1NRIvb|<=} zpSm3XjrN+b|EUFX6~9Q@5tYc)u+!gzV1lMQhAa!^$r?yuE&79uNbde!$U>V<>{8 zw<5@rSCcAYbY=EqPw~eRvfJwij2_ckXbZRe{o5+=gOFdWty1!&B}t7ZPb9I^NA~+V z=lpC-Y81x86*4??nDK2K@%CekXfO>Y7!`t|pZgn84aXSeLYH(Ero_FdtlLy<)NP4s zNNqP+0j+2r`f*)vv+J1qi=2NIl=WO5Z--=*+-1T=84HptLDr&D49YRL9en=A)bJ-e zi~g9fB@@?_(eyv#yb)=eX)TM6P5cE_=t-!wtm&7(qDO1wg=$Vmt!)O?gS#wvRa{k1 zBVFCI?md#UZ{8ijp`5;uwwdHxrt-%}*_FN7pktf&U8eGZE);I+pbO+>Do=bAO6i+V z(8bGTsyEPuoX~2sOtX-~7}{s299na$IyzzeZOk? z`QvZPF~Ka_-&#>kx@aRczni`bZHtkmth4O8L-d|DLBM)229^0jhS}pdn|6m~Uxvk_ z2Rg}MU}{>PmXQ4`tfcMPWkSTHl~cRy6dJ!>Si5`xz2wy{V?ZyZwacHNm#o_5SI|pA z?Q$3N@}+i}0eZ3XD{$e-_eldeWIP@RqAm0&Q(|PjzXc>-i+f(sARqT|ShIX`$CQ=0LVZ>DU?iD5c3~AxcZeG$$U-TXP#(Z4QT92ceJw ztNkzM5|5$pJd`h-J|C5|vp5n@P^7J`&HS6Uv3opp`ZgD@*F(U0q}^bq`A1v-an)EO z>(-iJuHcUn4wH%qomIm^E=t_$J)Od^q>5vltAR$p9FuqPI|dsQR#o$5%VopO=7rY| z=RSf{x02IxFV4eaR3k$F`>m8IrS!*%Es0z&CVazBrlyk?{}}0FNx42j_SyCAtC~); zJIhG*OU@R~6D^rJ2WlGDZ zG_8-%0O2yK0w%D)1WNx^(L30OnJ~fQE(s0>>+d#D6yCat3PlWLD24hP*|pPTB0ukY zP3IE8Fd*#j)Y2Vo%XL)B~wSf(3$otYy3c1b~mezYzDA zCP94yYV-jL7Nd;hp;<~6*#VUGNR7W(C*dY47Jm}yq79mf6kR6V9F!?0UjQVb#Bk! z_R%sVAxMHl5|tZ}nCd5Z0$4Yp-Jir!egcnYy*2l{-}X`VuvTt^zSzfYw2enF;JL~5 zVWN~cN6-@^3S~WFHaVQyc`7Fou3uBM3`5-B>zEK8n`=%o;pJ*6KX`t!iPTJr*#}?~ zJi0sZD1ehpaGCqJAppe7y2R|gumPiulZ=14y3-K`DsuHzf~QZ3ABo^*@=IECJO8$e z`~qey{md#(9S*xTJTt-uZKtEAs7+|$sXSEQOX^H!N`m(uiGp3e;iZ^;Xjnql-GL_$ zTvIrftABrkOEKl^?ZAfUO7O~%8?x(w=-r`k@r0aYY*1Pu@WeFvrvD&l`c(6kKe@=8 z;^N7-k7@+fqchP5s8o)VnV}pD;k9JK)hmfrw^IRTn5I}wov3|4F&LGxA=_d|*anPB zf#+*N=P45kc#>C?nm_pf2`j+%#bx8-kTCas>fk2+XN(-qVLP!o;Qm-!wf6g z*gd-UIG>LBT*N&b*ZParIJeCS&DuU>Pux=DC;fTwf-$A?N!IUF*TJYsT{0Z>tz?y? zi;WBgJNbVW4wskdaWy^z+P*o(8C{uud#S6^5}RR`7dAO3&4t<=aqKCYNIdR$h^3R9 zyy_`9T%lk6rFJ8qqp$94akm^rUyoP*v|Zc}cC*dEEse1Zy=FK0~73fEmP0wnWFtPUwr%UNsTZ^18vs;nM{!oP6L1}#U z<~e51jhfb^APRSnr(pd&dr>uC^3klI=a>D#;W1sGk8$?-&+A1vXK1dPcbzI}Q#A)T zM2PuySg!<#8zzdB=AXX9Hqr3n!aUCKB?%MK$_r1a2ui(-8DweZQ0HOK$&PL_DlpPvm()sC{fW`0^^{VrN5b-!7>(b+wV81~YM>ikd`2X;*pW~|Ro zsq40JRhKuMsw7oPtkB@c?58tksCb&We+yWBCp1&AIFq_b;i!t=E{-3Lj_%Zksw)!$YUUO9@pO*Yppd1kqL9FA;GsjaFYnj@n znYKv-O~s!i&=cY;%=8P^cJo)$=|wL0f{%263zGM_7@awyGFz5)wVIu*NIt>C?EK4& zmMv++JvOnzO{KwhHC#t1?4Q>7Wn~#yJ`%P0y<4*Cz4Z+qE+_mahiX)_F?~u3dZMVZw_sEutJZ zB+UO%k`MY_y9^3Q{6=W~hf4PctylZV2FWho>-DdH3=jx*rzYkntKO>R?3mZf}fg?K~z>yC?M82M;LG_sK7uJu<&43OJe!0tI2#zAWSv@HY~s<0oX8t zwBjH$ew14^K(+>C96*i-EYMqJQ1ybu=MJEH9#B0rI*?^AU_AuYXO!O_o6fhy!L&Kh zX%3*1-+)f$2Px`7W<)5rGk``3%vgX~Bw#7PJwXMzG?AQB(ZFTi1N8+1@)N*Pf?2nT z$=AZCHhFjdQE61(qIcXv4?797-q4M1-@ZE#{$hT6FYFe2Le|gls{iZcEy|LgdhZPt z@vV#X>22$I27&@T{t8iu0Hq}tP|N@YdX^2Qr~!%%pco)1&=Z~zg$F@FxYz*-^dK8d z(Et=LK$$~O-T}%zK=DJkK+m{BiDdxFtty~c0E#ez@&Qm-5EO)q4WP^+D2Q6#07?sj z5&$SvfO3m)u>h171O-ux1EBaJD9~fhP%Xj;3c|$!P@sp`pjvJbwfI4l%=02|z`O=W z#u2!a(ZNxp5RTo;hI_9?1}?>~3h0soDLtV6Mg<)1?B{`h5qnY#_E1)M20vV%ZT*Oc8SiLpM|-H`#>;%>O8Mp@bD2yY?L61hf*a zaL=Hrl;H9|4cW53!LY+;uxa^uz>~D)4m`CDqT#8n0JbMaFq`9`{RS1~_8B~#{V+ic zSTto|(P)50V{`vB0}16e8N@IFHEuW(v003REno}U0%Xu`PQXgM0Ffvl@(~<4_YwAW zkel$UXWe%Yg;y32Exe>sKoY%RNj(HCS!hpcZ*3t21|W$VknR*%xppAZ9a_1`@BF-g z0SYhxh3$#M%5Ok?1C%r=+KnC{xPnMB5Sa$2viA~>JcE|C9?ALHV>p$UAchBy;eo60 zV}ei1pgn4a_*@LmO&H3b_k0Uh^aHLAU|YcZc{7~$&JPU^&v*rg@e1i1(SDd7JZoJzoy6lfe2&~CH<6Kuu(po|i@;s3s692?Kif$eDzY)|*VCWsC; z!2r3Bs>|bTh{5pJd`Se=b^A9m~OhD2{8kO zJ=fu?wgxDg%^D z1f>j6kOAc$p!i7xN*kb10m|)HKN*iUDN}K|#2n z0tyR)@(Q?g1BwBH0)1-&+L6Wqr3K-F11Js%3Zj-NK$$~ON&)2zK|#2n016eL+#+h} z1QcNer2wLwUfmR8-^Qd}L65=VN9Kq2TSjn+xBd7!8Rg=ymS0jgqH)-k1-8p}(|6Y(BT+iB=`hKd9m$WRZXBPX@6qB0 z^{oEolxMddF+X~K?P?K&(miT@Mt z$o>U?g@5haubx0{t>!n(vJ>>wvh$k)dU@PN(EXeZ{0(6YRI+SI_N2C|xm1O+zuQ4r z#k#`09F~R+a$U`7wBefcsbRT4`P`VdKW|>1OYmrKU9Fe*JxzLX&A&C0UxhK2gz+R< z&uZGAqJfgzX?bi+MwqW?`N-ngNuT}bM)PMCQ{BVVwo>aI3#P-$wx!}|hN1q8W_u4J z;x~)omozn69{yDWEE3IR@%sP9AJ3u4mR;#Y?|CZBMtm9Q%7 zG^UuLPP7gW4%nf{Vvj#H4|lMfZ5bSFvAva%S~J+!I2^Zf_`T!TwzoBT!?S44KI(p8 z*>V#t^GO($-pKEf+?QVlrZTRtxbtoqCJ6jwqwXw)_^s-l4mbNuM*hst^kFEPUy>v_F-s`&GGWc)upn{!VP`+iZUJs;~(`v(BoVXryYM_UD844m@o^qgXp?^GJLjUoka{gi~~(%iL5D{O)>Bxu>rQ| zQ(n(0^VNV0&YlQ#P8k z*A=mVgX)9(%0eaVVdj4w4@}AgI(^pN*0+;zzBtvXy zlAs%O&kBO_2~hBl`C#EjBwE&V&6j0-^%3L5kqqjw)TkYVpSj3#m%g{lz*QQXHJNYl z+Es+W86;*;vQp$Tse>|$Hn?ART7`|8eSGKCL7I#+;zVll8qT01UZ2A)wOUi>Jpr+X z+^Fr>h~bA@9|!I%g}R+27eT_FAOoLXv@J;Z-CZWu<_X1`t{3tqwlr{`agW*7Mhp|D z0Lp8(l+q>64s-Tjt-K~KI~`lRB^4j;bFt1&DA!={%iGw}!jwEKZc`|i5(&$92kqST zuP32gbV!U1Q!CQU1Kd+PCiLL}*v=d;hSGNjMew~X1&sdVujA8@)@eN4VL|2rZ&Itjf^Kp1 z?45P``PWPEs5JT9304xKB*-I%RaW&{i2!$M5S zum7?o8&|_)WjSis6EXPEMI7#u=H%CtY=4b~;rc3C?4P)YRr89#T|)kK#+xFC4L9Zy zS_cXG7Po$UFh#_`l}l}LX?9wMn81tZ zmu_#~Ch=>hV%VNnzAWp7qzXBU2u2v4{D5tC#2^8k47_STyOQObd~ff9XV)S@Z{7y6 zol_y8ye>0>D5=aaWz~xN6(r07R#%cI&JbJj;&Wsfg8g5TB(!L*&y-SFA6K}33XCrL zsnh)F0gImJgCa}|7S$ikBfkW`3~?FbSa}ckFmU-+&KHiOWsq7jxkXee6Si@DQD1*f z2>yQtFF|oQ{N7REYNNlugbP2C{=G*jha25EVW&{ucRS`u@%=UP>k)J}-&@Yt|KAP9& z+!H+cj_`QRfsdnKbbN7p)ND8@YC0_*G4_1GGP=`@TxUR8Y{Q9(;aisLS{V`Uy z>R{Sl*JGs9%&y{WXwelU&YS96$!45oXbfHGeMlap%cr$`U_Toh&G1GCg z!W~BmUnF7d`9D`kgslEWhbaFUB56!{W{PNJBh_|{p&5A=a@vX2P! z%d=37|JJ-$6&S7xeGmOC%|Yv^l5p?lD4tEdw1Gn3Z7!qW#jN&dDg}nb>UTmrc_#YC z-#$m*5?Ze8jJF~wYt&nUx6So&=9)OqPHN2OgUo4hN+eg68K4I>`Nn0tY2E*38(%tD zm++o3{c>`RlT$nOg}xwfHUB2*Tielp$~(vfT%>xX9vAbn@`=95Rr@H(Ok>uUWXxj5 zFW4vvsL^^z?rl`-g+h;J%POL*hD&kkd~3H3mqPuB?9yRUZ}-=@s$&U%#NT5HV`t2+ zB6;Z*o^$K;L9D$_jb<-&&w)icay^TXlb8RttgrDKutv8|a<`P9l%~fGr+T z5f^mN0kUD)s1Ap0Sb&Yjcb%?w>j({r-^ebVHuZL^#$26Szy@b$%muP}4Q%3l`Rg@z z4yv&Q4R78`HK^$opT5-yBxilom_OCQtnShXY=j2v?TCu_ga{s?_fSx6R5yi=l2ZX2 z1x}qss2T-OjYYlPAymy8u)*qm=vkq?B#Ug^ntBjtuhXPia!>_Vb1vC1s$aZ%t`6IH z=T8N(sJnOr8{YxjL8uyEP>t|L^$t{xFt9P;)VY9c41kS;XZSz2#)*mIg9e}{R>>!9 z?gHI)z)j?b?mCP_PLlfp7IfF)#Du%EvwUO;* zWgVpZoDr@(e%OW+qCcShihR@oeZL1~>cqIRpylaFttI+^D~8B5=gvDI1iGgM655@&wMg zqQd@xf8*+eI6Px)3un%$$^^NgaqOW=+2X$Lw25Q_l=x(v+k<2iMo{MKnl52|7h5K{ z%<4hg{m60hDH(VmcaD=Um#R8WL6PXaK{szpDstc=Ctj5$3G3TzKNrDHd~VvQnlOW9w`yEWYgOIsE5I^Wy=-N|E9 zVUYNZA)yBTSqLL420!wKGTEyUu4gM>-_ZOHTh$a(EuqGV5D9yc!)#2CYUO%I`2qWo zpFx$*6A#6!{qY`bI)abmJ#uu^{^N2Z(eUx}ll!eUPgno@HEEN#*n<5hQ$AKZr(ldT zU;{r|oE?3A$e<;I->gKcSj7CH;@;|8c6>~9F>~4C>vr<}6DtfU{6`$bAv7;$$$ac? zl_Ck>M4H`}$^}$KdKF_Lss9vINAi#R{^Rh-gK>otYoWyaO!KZouXCi?9@Cr*N%3r& zCIiQ{er&+eHj06&HHVl#jW$ zAtz5g7u^k1eQ*1V&a|{n$881Wrsfy&A)V>I#HDe6C3>U3Vs zN;g*9cwTY;`}d{D3#T3ubIX!HeTngr4tL!CA65!O#QjI8zX+u^t4}`k5=gyLytDWz zhfC+|r}-z7|L!6?{nDMOZYLc*-KWPSy50+7oh45g=!chLz{GdAtgN1ot&k%cj&Ha;xZ4!#OjL*ivAn&@$sw z|Mv@zXsi0ehhF>yX*g$DE}a%A=WdYmO1+()QROc}{8<0Di!wX$CFMzr&wx#py^cC$ z6As(ds#l&ovyHEnhr31>vLWP_od!1cBerRnDYW*$hG&ZlfBfK%NyRTFSkJiGoWm(B zuT~9CZaQyVlRSsPJ^`-ujU_h`^qU^P1oS6cyIws`2lQK~J&Cr6w^O8frBhgStp=dv zkH3W|yMS`flA8*mpaY7SXZUaEmqR1Crw=}wLw6+e-m1bBfxM|G@*F10ge=rwL<*MN zbkOhBbbz8#kMjp|v4UL=!rVVQhjqMF|44iveg`cl&tXdk6c$Tv7KlOwD6;i9JrKnV zP(sW(T*9i~f?68$#wVb}^g&_{mfSp0VmyGN;~CxuC1wW_i!iTrff56?KyRS?P-3&d zh02m!7;?D>C{mu`0}#aoP(GP+xQ6AOgIc`v#)+X{`GtUs!8(`Jcqw5hZ8HHppaxdl z;++X+XZ3Y*Baw{`*cAw^S+d1)GVwc|Ch7mpp^1P#pYaZXV$5o%b~w z9)CTzl$a$B2_9H$P_Ob4pODIN6buNSBu6h*inG9Z4eC@P^9jiw1BUE67ZsFB^PNC{ z-s}wXHYe}+bryJ@qpfq3KxMsqoaLkv$vXIp|3-dI&ERBIH zw^EfJ?-QNMhNs7$nTr_`om7tX`!;o7Qsa(#f5&c(YT2t_%sE>NTy~{zl{U2ZkCEm) z9J_mdQRSn=O7QCW0DpTOk_po$UPw(W_hoUn@ z4WEBMN4*M*nnf2jo1nl7$CKIWQIsc#y7D7jK@UES{m%ocztNI7`3bKoPwG%gs6SVV z)H9pzSG9DGLI1*!U;bjwi>LE*v?A%S?I*(K*4%6zD<@Z9igk5;a=j0@u0_wG?>wN) z#6I@1@LQ3RsIiW2ZW}03&)s8nEh5_B$DSdT|3BP)_dnKO`2T&I*?W_bO~@*;SID^S zk-ca1&RqzZMH*(=QTA3elvx@gvQtV+A*G_B)aN?K_wjjrAKyRW`^&kVb6wYYz3%IE zy`JZKUgse0{rgyl#>Klw!=gepz6c4-&059XH`(1``qJBjYnc-%bsBFl8(#Ow?v~4P zV18)mB%rnwaOAD=!&;kS!yg-Ud$&LNT~VHYaI^9BLDCdCWKZ^~3BD(5(X8(ja0uXc=4TJSqVCd{m-|kiNDdHtPZ9Sk)-89KXR?OqaVJK<%uxA%3J z8=*#T)a1-nGhzwFLjkqN)zp#nMu#T$6m#{;WDVQA3G)C2=O6paK6G{EPpH+5iD*y- zeq6o7zn}K}b@s4VAB{i$+hr%)@T#3RBYNY(ms+;s!XcR>@5|@5GwXI2b6Zsm9kBzaZ;>}_mFHhLyu<^GI8KL1Q>|2eMd(|oF*9pw7IGkd!1Q0dqp1K${G z5%m^7?9ngxc<%6M#xd>P4_$*!Hin*i5$?$s_HXR_2y6UgMP%0#K}(r{nI~r}Hg{MI z5cWQ$m^jI?3x0S;A?_QHsjX*6<8|ZR8Q;G9(~F;l%--e<-TGPSKHYO9`)I2>ch1|J zJ1u$yUHh|*9z=~FUz|BY9&s$!9&fWe3ZKWu+g29Jn)D9W_&%FEF+B3|y7u#{eSfai z98)iN`Tf6-eQM$PoK^Gbi>=0QTn@NaB)dc`;j^g^iYT5W zv(U0lyxfcal4o~zPXcv)LipbeqWz}kvx~=*-e#01Jox^;r8{8;w_PhEJ$edH6-Ol2 zlijZ92sS*T=4~H7rW*#ig`8f>os(la4>^|9_}WgSYRHwme-ZuPYRpT@Zx=Tnxi&v} z#r3EER+@L|JFzyGY`;qNqJv$pNc~?qpTF&l7&#O740|j!a8U$&r}K zU*B{Se%*5oKXElAe@=PQB+5}GaGyc;waBW+r|-jG+zdagDkbHt}mA2*(|AH1yivyNKEY{KAm;Ev!c(|7-pjm_DwPFMEI#pP?YtV&)M72MC) z$2~q2^Ycj6(VD-%pQXPEbfvR6sd)3KO2<8U*GKB#4=i4Oc3x*~c$hn8X}5=~f$`(3 z*1;8A8rGNE1v5*eTwL3YALq*MToHR8tRO>Z;LUo)cQL=a@QLY_wkEEq1fBE$o^0gr z)83d_)ZV@9n^r_E^jq=vgZ7n(8zs9)J1jB@-t=ys^=tv^N8}Pk9<`g3P7J6VE)S)o zatZJx_P6c{(EaF0)Ia~!Gg(=_OoMPcN-ryznNyT0GnBdipaiR5QHq50o!5ni<)I8z zE(;`NvY_h8s4a==`pi<$sn_gfY|iticIKtM8p5zJ-^um2Y`nzV!GI7n<&@ zF^$tDi^C;U{?1y5wN!7i`xkK-ncjI_#L@O7U;0^zxS;^|%MwP*7Ne&NoNQyQHx}&u z5+w#zYs}Cs*BElh+f)}y8SryYmn1Q^85J&A&<(amFUWr|3{K;D1(&=^z3tBHg2SyN zm2_8zZnEcje;JAyJvjz<9f$9l;-gA%vi#u+d;@GhvsLx0Z#t){$~WJn`fX7pGVUg; z&&NIDMiVb>ndPs*gT7C5uTHMy17#=dH79*xa}K}427H;&HU3>I(fT3Yg`xPHE~^&r zntY%-otbrFKyCL2wSfBU;DdSPjG2K4$HE@l?-+kBk8b_>rDx@JCf5oT(U*N*|FjW0 zH!bl^xVId#J7aP9B)+|xfN$0Og$oMU4+pzUtkjf;weeT#DjF^c@hkd`UH6+TpgH+K zo#nykiGkfLA?io#v%|NuBX4h?3SYI~@k~n$T}Z2b?rojPy%>x1J@SuZ+^)Z}J9GM5 zDr2~F+_%brZ#Dc+7i92-g6C*RYFCC;l-s?(3|}o8E)Vf5evdEoex2VCzMi5fdKQWy z>L=mrdEg6qOoehf>=?f-hMaf1{;7PuNp%eVMltT!z3tD0eLI0KR2}fG7A~|CUnsoG z#1_8MUi^)26%ALyH~N7u^kbcWKU_!{Ur2aK?ZRwxDfjtbrin`OXMZ_gt+0=m|CWJV z^sUZArEbG{K?OhC!^1ST>up0kc)|;vmY0`&i(2r6EouTLllN6$;t5|asb$um^Y7+B z54U?djMYK-(H{|X=YMLa1?zRr|1!fDa=9vsE|iHc)NqiacB5cnH@@?u!!)GzUBklo zLKizNFT#a-@P&Fh1hgmbtN+8#;@^^bO#Qj=zZ{}WCqp}bsS0RK-cz0XgRCsl4%*dh z6iAAoc(4yqkE%Zx+==hbA$GWA$+s{BeWPlVt4Vh8^5YKZ9b2rPzFntteo;Y>m;3(O zXxNOs@S`;xT(OJl!C)VY!!BM`Ko!2~emq(HdXdWHedSFm^iupSVk(50iTJMdx&kb~ zS0coI&d8zneBLx<`fJ!;PL}`Ap+3SM z!;*Q#+|CdDusY!%_5OzvM{q%8t7yoOnSd0RmH6q-wYJlOjklVQe>$6gHevRZT9l~c z|9uee&HWFdzgai~or!|S-ekRDR7|u>8gRKnup(rtTq0OWa0mJkOBAl{Njj{&=Z)qe z`0LW098yE)os~9A$Bzq!819$Ee`_be)&F7h+%ij9?1lW`x-^ULI|GiCap#6958L~; z;=i_R)%Nb?PnnyG6H-kBCK_@JDk=jTWbRP2<1S+S8P^s#i@JX0?YPy`)7>!|6qrV_ zTfu59sIp?$rU`2}^ZTVDyFV+TKcYW<+AryndG1j3;GJ)#{0Hf!P6s_J4&7*Z$NBqX ziJZdczXRM;KE6U_?bg*ZS&bJx4=Zo4%Pbgv=rxv}_TS*9%9o8A^&86`kab?&=~f(c zu!lWeY6wcbg=-x@dY103$%%)D|GsBI-G2J8$nPl&YSm^!mT=Q(^m{$tG)YcEy`Efq z<6)8029LN1^yOSd9|UWAsYmO6X&#&@m@Mk%jaa_9@^bg4WiiJqFRh~Hf-}4Q@9hsQ zWsBa7l6z4pfBQv7WbK<~alYVmz9;<`(#^BZU*Gqd6ij`rlH$TC^DM{qeX@}^YpH^- zXxk?3H<2)vd%EMPr+U4<>(lLZr-;E^$0|c;DrLT#sxg{2%$whZuM?mgTl#J~ z$CowLx^Jm3vAtT`)|#fW<70O0E|I42a}&@0QhXX@97}K9c1?rr-0brLtDC>hC!D0M z-svk*xU}kVyhCeu^~&zMZP)IKc`vvrTg805zOQ)mn1}byYgT4Ag_!PiN~Doh8JF|( zMxQ7(dfLkGyVI&~<|4>+=R_5Cq}0Mg%4fRNGFe@gziRz&!EX(IHk5m8!klvHW?`q{ z-sP#n4)~Kb`xM&}Rh7hd z^*{Xg=q<4GQVaKI$zA`hSF4v^Yag%M|2vn#zvYSJH69w5k?6cG+i^iR-ano#R$bSw zjW_JuXi-1G@$W*tdwqDAKdq?xbv+zvGU2muenrNwzrN+m=P8`PSWO3W!WDyw`SMVT#?W*BhYcJ8Gvp`#5r*~ zk(-S6IeKf4^mq*~xQ6A4c(!U9ofq+}W)-u@QncgEk$f;+x1B@k0Z+Yte3^)6rHOsH zh-dvab(<{38Aj(y5zmIg0t@|ak`1X=#IsJ)tzN{lkyq6*tL4ICk{gk;@2+;PTq4!8 zebLQ?92rq9C&I(LyfV4ODD#XFE#RIdX z7QIh{XEDjQ-HcuDzf!Xt@fqFXSJ?ykfovvp{-QHaB?94NTtng{`nXwDL+4*H9z%7= zz-1dbAtT1XB|VC0R!)M=aMJ?myfiPKCr0%C6_W#0g-CU+e)`>3*9|XG z|I(aGddU5jfh;BMmen%ho*1RyZGQC5YwBOFbCi#H-pUR~(#k|njf(8>0=51k83Ol#2TdqMTs)O31j z=LB>rUYr1l(~{6z=(N3{hS{cvXeD=zP zm$rYW9x9J6-x@oU@%guI(QrUaYZ2;-EE^;fPXs%BqBl zKTWy*<OqiVllBK%`(8O1X)$L3i@HuzgeVRf&>A=#6E!0Q zJG{vjCyF~c+2@EP)cOB7I3um!?KQ{dk{nkUE7DK(OL;xDlI|;cDJ_HJEyLsi3@AFa zdive=`@J}*e2nr4mKzc!qBAzY!Tk-9M{eEH_1hX;| z7xF&8q&7sUs#{z$fjz|R3HZ2@4e8pRS+jtlFd0R7QcWfpa?YGbZs&iK0q@0>a|;N% z&Y!T<+4j=sX*}QR+mxuTd-{^Xl?|%fm4Au2SJ4#!EGX|}z<}{zB6RpIQ!RB&okG~7 zzv_2-JbDAl`#UItpkpO>2|5gFe0#vMA-^@3W$c}+OF|A|(9Q7+hV4@y!HHw_R{)*O z8|c7s%1sK|fYI$IFl-lL*ba@suzd}~wp|qhlqog@D6Z2C;QfYmEdZRit`{ZES`SFP zihgFaK*wTfc!5d!a_WDqVRy!^rv8@|e0l5+`tVIwtq_cwO%=0}rmaxlsb(!ro2`DC zj&o4IeprSh4fGi6)WmQ2v&2)k7f5Scr0~u z+Szi6cW3X&L8nFA=4Ns(nWHFB>6mv4HH$R2kvPNl(clQ9_IY9{qv^GIVnxWVSIM+_ z^>!B(qV=j+Wj$6C9lgW4=ZOPL-ozBzyCJ>ejN3`|Y@EBI_3F1N_^u|ps+5bS&{7pI zrsWay9vF4yDkpM==9DQXMx8PPtk5jPxN_*145evZyk8BYNIpBlAXf>jxj#nCpO7&r zuL}^P_J|Uc>bWB-8AUn*j!F6x=%(n4v!!oW8GO?VV2(C1xb5}ZAVB=?qjq6G=ve&r zh0bymAqYAoS_BVRk2;DlXRTSVKjc|Zlv17SQLNmd3 ziPIY7ZC2~%&4jUK)f~6JzkN(CAA7V)m7Jwn1{U&50WXi#&q8OE5BMQ!epwuiVI@hIn= z^x`=t>Q9hRz7UPz`A8iGasM#@ajOfN;CKUfQRGx|)ki@0F$e5(_mxuU%&3*Y1MqQ| z!}3yEz;#%bb^zj&Qv#vmwY%SzhNbb&Z8|}fXuT`Nq8cf*sh!m9s?mD2zX~e*D9z{S zPw{JsOok^m_E9R&F*68giA)L2xA#%z%w=Q>Xq8X7m*4KAw4FOcFQ`>Msoi_GkMh5{ z%rnrLi7$H~s7D;$+&(C%m!mDBbC^K4UjB0k;@R-43T>7x%Q2C|1he(@RTvt-jFf$} z7b>9h^vw(CglNA?g3e^F2XtJu-(^E*di=#hL0HXFimO?Bc7JnOQ%#E=D7#}}mp;81 zGX$Md4}zs#I?s~v1azuA3_#+v=>Hr#O&v51lp-Lr`;CBF{jl?uDKebe1hw zq0{%`tHB__-0#JAt3iV8N1;WC)0(4I5X_}7I4&wDrp9_EfMAL8DF~`qy0VlL+czHU zg-+W!?QG@5yBkJWZpQ+lU8nQS1eBK#k3grdyZl$z`6HUq{uv7w@_MGP2vYs7Uwawq z!mJ$czVW$3p0==C^k>)kcje>PIgvPZqj>^}#p12M9ozXxzg}4Sc#FTrw(mQhAnm4v zOGsN}VniHi=WV1d{ct^>;@rdj*W=NDqszM?h+!o?Is&oU_jhY0wZki^B3?;*@Jjl3 zYbBk=E9pO2Nxi6+Uwt!xz#df8f%L^e6lE-2t48oDG>lQTnXk!^pxS z?X#L_zkgnthNX6rhhI5buQdV1ZidD2&)}~C8dC%+OnC@k_{DVqBh;LcZ$r{?oRbtm zsp$kxS=66%z!PYccn8m^$|PFEpJ1joCICZCRa$^jR07n+*;(C;SMLX{o=%PKyQhbs zMU`85hp0z&)h-qG*JM{3Rp`_nO5~&aB6jBFuxa{*5DJV#k6wdvXonz%9u6B&&M%@W z$!1lY`Z@#3u}$+B!y7+f4EK8l=v$qi3Yb#pcphcruErRnPkjI+AFIbpXVU`KUGhNb zc#|mdb4T?bH)7?4YZ(mrG_B-AXWG8Vt?wXh+8Z@4hKUK)B$t!Qj?$D}Q#-XCq$%^K zkg&*&6iKMNe@I>eXAyjHQBxN{&(m zW9n>)?0#v=rfVXn*$4HScfLcpioYDrRjMCavFpi(@7!xfsB1s73OUF4wJ}&zt)7{I zfInPO*Nh<3k>Uir$764-h#9O%xofcUjz4}4TBKXiC|T)f*avdAaT~Mb+<1=IlM1)I zFH`+WUOD@K{q3W6TEu_G%d%7<)jj6@n(CJU_2hfHug0?iT+$CN4E9RWf2D4~=}P?_ zKl-m}^hpNPzs%DP)g{NZEmgE7$93^*WyvLq6`0`I7Q-;Ef?Xb94vVLzF%In_BX|he zKG@@hIBy^50<-qnedvM6;=s;dLxC;#4*A$?rbs$aU!AWQBGfI{V2YI9Z{sfDQv$DH7BiPkKoSS3V-wLXwwv zQ*a?4oHhLlrz!g$AYTi~Xqf?<$irTIk^^2ex&Hw27xUqDl-MjgZB};l=B5@~|8gt0xr8x$2_|f}|PH1pe7`RB26>REB+&-oI zc;xcZJl>sTLv;3d0#j!Fm&~Kb@RE5B zFPU9<$^4OlmdrUtv?Q)4Vkk+$OQ!Z)yky?NOQyCMme=AX^IQyCGS_e5CDVF7K)h1% zb{xC*4pH~k8YLC>G5=V873fq4>OqGb%dG~T+V`x`F^=878#?toqtKx~#aHA|Fb|21C+yUT4>Rx=q zSxUSjbeeQnk$i)Mvy>gyC`-}#j?qC0sTC%z)OpNZ{u5>dY2UGovnCfpBW8UM0ss2k$^%E|jVBRpqRNop?{T@v9H=bdte;iZ&zg#FY z-xz_++@zsQ=Nzi2{HYb!|6}{8j0^K0BCe;H8x=rRMFHc9L%|-Xm`pBxqxvN_Sx!Oy z%a%NV@MM`Llk;upq)@I5lv`+}?Xz0!t#LucW7Ju{+oMYx1BwoYiJiEXGU0^WUw3g0 zpuz6=7l8FzBF@7pk!~gbTO8kB*zYGW`)A4r@8|I^VEPl;0^aXB4}3=YnL3<)Hc12& zfFmIoOsYhHzc}!x;fhMoC?HGeJpw>Rs4BNQ@SD1-K9H}w((Hy#{UKa&IkOL#5l;vO zhLlG>2vRyqFr-*)m926x|M`l6MQ$7BKhlW*sJb982T5Qr=i?{hI)J?_gK@p#6e5{T z3%H=NgbON7`nlpWO*xU>;bH-HHSTq11N90FE~v?164bOsf>yRjkgR?YiCMGBkWDHt zg|vLW2tG`gpHR`i6Pet|%P`Q`c8zFLNn&;lH_es-4T0=b`gi3M_qIq7-4+R2+9E+) zi{b)?l>?Z8hRa|Ql#fY}D(0R|*!i>fa6K!03(u|a0(%UTAR#SGf}Y?^rId6t`7)U! zHc)A=FCszL7{pvw6RmEEU4oQFRVZgCq`7lShy~4VB`e?c27o1nSYsOWJ(-$uJF8r} z8Lw9P#EbHDNOSpaobICxnKUq@VcF*R9@C)I+lU4+>_@rEByQEx5x}SoLThe}X;45k zfKjm8I8GC5rBHRn@++k8w!2tRmS_=xzfJUEFF(8G4Kr2({ZRP+V(%%Yk6m8-+J1PnX1YflxzPGFtF+MXam?eA zqus|pZQj1}`P-j88inxzkNH^Zmxm#HZ9k|4be4FF?YuH?EAuzW$RRHRCRW7qgGp3O zG>M&DxvIQ+OX{QvFGBq@qDu;~AmC0v4W-u{(Mo_(?}(JbL8ZhgLDCBl-y$WY5F0uHV!5cpWXu9lhjJRC=_ZCOz^GhPr( zzg|+-XJJ?Seoa28$UwXHJ!zbC$!vHZ4Arb@9fY93Ue=-O6NO=4M=0LB$-t9S>d zxg1Na0kcds%)>0b+y(f#O%FkM-}RV=Y<|zq3DkB~Ku(_&Yj=E*Ahv$~Qy$T1F`UDe zhPB}+R(+uc^@6@wYb@?2%1~~bqz!-v=_2$5={qYNA`Jg!STIeFvSyHHqP4J2w-Td-=x?!ad88b>UvItxb?3(yf9xjX!GTG zTLr#(hP8ST+WxUVOir-UHfMd3Oe`@MeVR-x9|Tw;Ru29er>2zdFdSf@X$?6y%)=-$ zMdViEB{b}i^j1o=mm=MTAbAX+L~wP7+6=L`vnWg1i@k9B9Cl%6C}2=YY!Ghip)HSH zgtjtv*@{muZv#CT=XEv6kl2<3jRpzHlb*=gYQ2eh#MF>-J{ijNDG^_IBJe*Y`RG<2 zDIH@Zj+oZcs&gvusMtQP^x$-Ati>bm0P%^#{LDq!B$kkvUKlc!>xH4qu54PMHM8wG z3^~dr!B7f+254D__|LHku6YUquy z$FP@rB_ns7e%Ov550e%5gn!g=U8SzE+;)Z9GjTRg%x#srZuogMLw9+*hUM*f2FC-W z1%_^sYZ5lS^9;_u((E*zS^WFicm1T8bhPJ7Q49*VGjF{3V7$yja_aNscbsBNVk zP{`^TcKHz!V2$2NE##2d{54Qvx0!vInn%1F5{OmZPXkc29+?Cs)0F_dL4twWi_;MQ zp+~W|wMjB5x!PPF=ls6ky~iji@{A!{rGO9;VKnMRQ5!E}mO@wgeZYuGvb?DGqFO;> zu&(`#7e!;nOnV=dU#{1o6uS2B_uqn8lfb#Bpm#~n?X?$0^TW{xeN;ZgE%eAjkl;d! zUm#F8R6t=Ssea<3Mxv<$A3}$;yg+6Vi%AoJ1!pxHe`XQC4vZb%l*+WM^(mGBFpbr` zIU0$P#zRnzxx3^w&iQ?L=k2l)qrP#@jf?>iXf*~zQ7e>OSUt)jODw7$wU(tTfL4aO zxO#M?e!G@s#l;zWsLUidGnEI^Z&p@URLiVgE@CbLrBIq9MFzU9hL)%tFyy@euf5Mn z?Af!U2s(u75Oipo<8ZY*I!L$_)lLWDI=Kt0-sgu(jF(Uia=+#a6wOOiD)5Y&IL-hF z^;(IU@ikstQVKY;@Gx~(igi}$Yt6t_x>`GTS|%MLx#)LgpHwCACH}bNCB_RbDb`A* zX6))esis^~gORo+$L^o0QyNq;Db}RY{cL-FrcTBfWu#a~4qwU?j5GKcx8>v{jJs(| z0L!(R6W~)4&+>?%UZuh=sC!j(+Q%#q`lAZj;7Lrq!)|se$ks>5tC5)Q&hSXE@t=?o-7tB6w2vxa+R&Dk!*q_2A!H#!-XVEZi8yIlKHo>> zxSKMEmSfKxMdo&kaV@gR+!*8tiQMp}D8KdQJ9yS?Zk?ifHEYL0JUA77%cvD=_ z2oPs2zrCQ4%f5~E>aBGtRuS7DAFM_6DnF@-B*DFoq*77b4Qc)kZEzVM9aZ|&rlbU` zNB|3Oj$UGd@|6j4vaj^v*E3sS$1pm+((UhFme5614B02 zEHKT;67^dca#Kuxudv2(>|y#4k#qER7zup!{nW+~k!r~SFM|}D;J1lT8t|KaiyZj7 zfSVuO>ec0qRjc_xJaqtzBZ?v1ox6NZ;X$l7Yk*+pm}o{67F>t&LMkw9wgn(nS97XPi4GQeF zTpZXVSha^21@>k=61#>W;8-ulF#Y)+ydqx5%WY|v0}Z2$l#l!P(r{#Lraj=ZAgu2e z3sNFZ=w?;+QQ7|UxkST3+Pr^JjW@9_kWMyCiRdV!9m6^4?U{BRxD zqzICQ^rlAG{yfBAg<4nR_(1|iNBv&_+z_=nK#j2_N${RyXaQCYMl0dE?j{H(TxmdH zA6g7v4{GwY0K01nmV;g$xBI^&WJ>Jm;(u_unvw4hAx!%RUy86&(`Ox@Rmy6nZR|9< zk+WH1UaOR~XPz%GBqX-)f^~(~zL-?akU+R5V{>Dk*0I>e4>}zhX6^H|wg*TOpw=Pb z-8xU};mZh_0^5+YFD!AbO?j}mSsajqI!nQ|Cs0w`6W##Tl%!cJax)>hy^9DL#w7DS zNY=gf76CJLK4S-2yxvMB6mGL;pQgiN8Omb^Gqt#*Jt1SR?IT`C?$9vMunL?rH2$U9c-8?$Rkq8GZtsJzO;MwMQ_0i%C@myb|R25>@vpfBu+a{ z!G6y~$|)kWhNteJtV5FuWgX5GyLVKSIk2n3&-V0c@Uy*kq=|ucV;z)i*KhN0`BxSD zcX1GsvuZxv8g_uMtxnc~ugjU8V2@cu$Q$w#19Igq@bZj}BzW0T1?L?5mO-iV>@G1U zLZ9YT9wd9qdtfJMqmRjMiv;~lnW1aWr9K|1`Gnj)&tfHYbAQJG= z&y+EsK*_q!r6vW6puMO{Owsi!)z4D;nKDtx$(Eu^DmBjA^)qGaX_RP+Zepn~j_AiY zVcTncY>@C;bw6sOx;MaGOB6U{)3B2>5x_JmsH5EO*4=avFWX|VKaS`NIHKLXQA8h+ zkoQ;e5?XMWFX$uqIT`*(L#gLZNypDfAn%k6R!W>8m)G_Y?58QO&`>JP5f}s*6UjUF zgewuATHd$;iRbQ=uQZgTxnz1lMlZ6Q(jg_nbok7JK7!A60l-~~qNjLmJBqR5lRcyv zdc#jpvN7k6*SYIohaj2W4ofC$<1r=#E}v9(940&|3PobIk<=kbqZ154+)RrhWBXl8 zyV{qFDhp~gn*ue&r5YqL#hrs{sFH{i~JeIl8b>30X!sXI0^>;u& z2p@%hAl^}Zbgl=OM!}06h@$N2vi{<+UpH~1cLnJz8WtgnGPy4gskWZWKorICA_-BH zavg~nurQ4`SqF>WjgnR1HuLLgfCSRXzs68{{88>51nl@Uj_QbZ6xA>5QB-r|OuAbI zWzrijuqrLiq=j)*>n@_GPEbcty)l5J+R47ztM}m00POYXWTGbmn9lA(v-^%_%qUs z%BGxPq#?-d7WMBHSMHiEM6la|i6I$hcVv6C2$IK8dQ6@wRZf&9?}7qK+foSZ$%##2 zZ#Ue+pm7rMLI-P{+QA=BFX6T&J01>*!bq!LS_ zB!WPcDS6nmcApwA<|?e1s~GBoK%dDF1X3M>7&cyE*f_r%SHb0Y;k-#=Q!ShU^5(BV zt*hBF;2f&9@y)QXTv-DD2j^i}mc_8#fML0*8lkqU`|)OiSjP!Acsx@@)qp1+|1Lk| zYCJ;P<7vm%v8RU4fy1JLDq!cJb06*PsUsIR1lpb$i!_IFTxZmLrFXwLypp#5e9$%FBhKbhN`S?3mwf{*uo6Z#WHWM-ferAB~V7 z>|gqD*`sC9;R6b2*)xcG*IU5ht=k50W{q}PQmeGrK1E8n{abyKg-%e7JwsvKsFe(y zaT`6m=mizoBUW~VT$WirV=rjUCXR~Y z$riiUwi@cx9_yXpzp6Ui(!4W+cTsf({5l?mz00@>KTlL(&69jt;)x`oW~kL3(lm(A zAyAMj=|DVba{?xEQ!&e-S`JiUba9JO_0F4T@VbBFF?(FnqVu$OvZ9jEdmT$)vTx{K zQ+Xz8_W761Gnh){P|1WWsPWhi`FI%fZ_Srjl>(y%14a!Vj2a3UH9GHN)Ub7K zEb>(z`^xS<-yhk6}aKotmC!Ew__DOW{LJ6qCFMr1!3o-Q^c& z$gr)W+qkSxmy%$+yIhQBv-TiW0OLmRTq+aa8s)90z@qaWJoiCBaHIiav-%2TYU3+Q zfX%f}F+%Uf2z?YI^zbgc1U|wDeGntGHeLdM6rrSUE)Xq&>O7Dx#J_r{1!vTbc>RF0 zChfkl1i%WR@sx6?e3WcA7&Z-}U03okG1yzVFH(hl)<*kOS@tON$6Zj%IO2HjGME6h zQQuKfI+6PTOj^q*Mofd=ueW3O#@xd`bHVOCjNSWd7SfKI_t<}mwWz$|p^8E{_90gF z$L@8S0OTgMETI_Y=0)X=t^ictSl1jrAl0PAdu8)K(RT-=;(M2wengb65vz93^^nJC z^InKWFITcCby@X(OQ2f&+0v9G#QgDqeDgJ;Mu4t4WUmXCo(=gWo1 z71NdUb*nu^gCS5dcO6PjAoYBCPq!hud6u4Y?eYd?vGfPp?^5!%5GaZk)#btyFUv{# zx^>4R>yi_k{~7pFZ{Ge3i(0RdQrG^|@S69U=cBaQAN%@0R7$eji)wN9$0nh*rKN;~ zxc)4L=TZv*hen_@usn8Rxaj0Zt|qIXO5GB3ah%sP^&~T|*dGLIouK!V9Ln&@+bTW) zj41|oBPIt5VaXVfjWJ|w!;oQ)A!7#oxhnsbimxdQtHEbcm{1@}w-?{b!QO*3r?bQ7)y*=Bt#gYR?1d5_;RKe=GH|6#U(n zCHXUH+?DfCvanv$in{eGWhFU?f?BuS^@6euXg@K^P8N1<+LtZ!lQ^*6`pp!2gLIHnmLesYkjq_KE4n&zsuy0cQ^40F0)AHixbY}rum zIg{eYK$AF2#{ujlB=B!kAHn<<9511CUO9zoqt^uFy_5)3(H8w)gt|F>wiF^PGbrJh z<=|K5C4?yg^B{>`y{-X(F{3jJfKe0Qfr@q!w)kY-?QF^x$fpI304U&wh zB#bQ&F?bMh!jW!cPr~nlikH?!T3(3GvQi@I%Rg%Lc*{tW8q}`z#+1;UNB&ioKSLU0c(Rg4ntN75K}ZpsZQD0o9yiALE*HH&*?I z9jy2P`5#sqf3(sduD$G!YtBwVFG7O{`tl@-T5P+4WAt+0I1U^`scYdckc-|m%|2iy zy}_abh@31jT}P~>a(6IdCH4_E*y4p`ELb>q8Dbt2d*Lk@imY#+L>9~O{Xl1urfF$V zMz>&yGrDtm2%?2?WkUy7Hsb41P;XeE%EsDFoI>;9@b|t}FOU&m3M z2^+n{Tf2I2S>yNiY z93YBqAu7~4+(h1X-ir$x-?5Y#LxvFE9Mt4Pdsk#Q_`cdy*Gr`w-DaFlt0uQ8Qww{!mWtT| z{ZM-@Nw4G8E(sNBO51;zhd4lc=cPS;w6#;!rqBr%%2Dd0EuX3yWRL3&L76S3+wvlu zL@0c;f!8>J50F*lsZYSkdFk*x>CV#saXEAUnJq24K}<0hB?9SD*}f))r;Z zYWGq>DWnlEhmN)4eGj|oB2FqC@V!j6*?Udjk8WdEc;+^aHQ!n09LW#w+qEUFMp;5= z|7z*$Rtni9B`4UwY0XGZ@Y>raM!ng1hCci^H?FnZS*{DRA5L}%s5*|0gx7+;@Cs>$_XamHL19)x8HXmT z`Y*4ZgZhG=R$NZ%Oeg$WxyuTOPM&^4s-!R7ch8Xr58FQ0bl+?*oBmbTX1^1UQKPeGU*Z(KXiV0)jf zioQFMtmWP~&)^}&3#o%x0mm7X(^=V~KrU@WoLkcvaqg&klt(P7qNHwY5x_;nJ`i)j z(qOa=n+D|L{JFDDFBsvS?s&4YEt) z@<_-oGl`4I3Fa4iUqcWmP`_u`$Z$Wwz`J&*Q!r2IgA|!s)@StGlDXHt@{3araOzCA zwP9<+N^JoaGoR@YRMBr9M`cj=7PMj2sgE|S$d~b6w^!3+;7xI$&`z z-s@fofH_>R;ti`$y~C!hO?3on<)fDZ#oH;1Qwp6F*BN#Bs#(`^_4(~>Q5&HrYKx!ZxuHH(1zu#qU@r?`5F*Wfx z@(&mWDK>2$F^o0Y0YpuLlb#`J@+4FhQIoo9nU_FKJQ%hZO2igJd9lS%x{NVHi7nn@ zC}%N4xgCmWM;T@)@tC2|Vur$k8HzAwC^}mV#Rsd_p`e}&oCR)DGcpOmPVy`O6mgCZ zhBKA@>s+#CqdgN}L&NgQg=coB%L6xwVDnB+u*eia4CN)9THP$~em}yoX1GD*l7>C3 z9qKkfW~7`e%P&rjz_0D;)_UqyBq!MRytbv@Y~?mY3?%`T-Herb1Q0fF;?mKE9X?WU z0i|?{5%{!#ZarkqmB;a6g1>N>pqH?Gzz0RM1700vv9I$55Jl<06eWbEIIeZWiBlZ@ zUpt&KYyY+czqdDPRmb56U{LiKe#>U1pc4+RwjW-CU)ux35C{W7-6uHYx^g=f&aJjz zUV`7+8+}~I69R(T7Z@@&;Mi*Wo23Rg@9VFyi3>p+%LtQcFf!A~0$LQ%1S8C#2}KO> z#0U7f@Sgw7Uk-T3t>#cc(&97w_jchi zTkWaInqoVV&2zG@bidoIBR@qr;Xe^(9YO-&j zY00Q$=e4iReExS_6HJU-o5i>pDiv!}UJd$Fg-_Hx%BH*)AMf2{`Jxk;EzDKW^+MFF441MQVo`0HrcVc0Cr{l95`}cQB*kwd&m36lU z4gK4jA9e6g-S7p0cfr1K^-~JA4k!JzY&`j1b6m5^?w@r^9p5anp6(o=*n30AmBX7# zz0=vdZ*cACfh_BpSY!I-ykE}W%nrP4Yqy;b{4Yh!q3yWjZh2eYAA$c}_DMPf9R)|! z$rVc@>f{z*i}x4#seRKWyM9JDx0pxf^lz1$#%;YfbaM}I%Rxt@+SEI7)Bzw zy*yZNpiTAdkGIXn^*;YBJ~>t@eHwZD6W`oXMSOGT#L_f=Tb$oKpMA|Ovprycu)~w0 zdwW$LMq0M#kDWa6V(o|P$;R^yQ6p96TM?vB(w|8) zVzg&JBFaYTkm_FR)~}b2^lK$Q8i>(^U`5w{1#uq{n81ip5ZYNY-U0*EF~U+!EHy_1 zck#d;Z=MiE?|D`{j;9x=Ls#X**Rw{777`x~gv1$DS4k!Egfz%;EP>NP0Ga=%EdQhhkv%i zKX2W@INdE04;^J7zNbL!kU%zce}NpReUHcAvmdEwW~X_)19>L^i{E204;J%aGaj}h z6$jaA6tD{wM3Jfjd|_y@nSvDhxmo0+!JGu6n;G(ln=x)JachX%{kYvXlNM{rd!r0J zk{e05&BiT$%r^@0&uOg;>v>9%a>&1t0=V6aTBTwvPQh(%U=K-Vs8_IT(_jzf(Jvo) z`uT1Y2llW&?$y@%ofb*+>D^PsRFz2Kkp$6_q?>qXVN2^G)}q8i+utIsRaUHZGUhwO zD@LvUtDf5e=WX!B=dek12{z%tCS_YDoYaMSdO+@#CTCt)Z=J(cq!oci z_sW51xrk@^v*k)BY?8S(bPwOlQ9N{fYhrkm@Yp=@EPuEB!h&ZxzGZSBOajV1>F}5> zw)Dr!gIM1F27TjEd@p*mSS*AEQLnL}5KXVgg9Ywef-Q?uEMUO`Z7f*ZvcPeqckvoy zUgxYL)q$*umWU)8!B6lEKRA^WPonVJ;0fw|g+hx+%^!IK0>;bh|ETa9&7_%2Ff!t| z4DoB}jo;n>a2p8_C+Y1KgWh>BYTO#*mI?)WD?1MNoK}YX{k+cjrQpSHR3pZz zMhs4kCg_c7w88-9j9&`pT=Z)E6vlIK<5nHF%oxJF-0>w;@z8eM>fn}$TTySGB@u70 z9aza1w;Z^&!>tN#4{w1OH~tpqam$MZ@^}s|+^WG$;@(~YSa1NhdvSXVx3sw32Q#_! z_wK^xZMp(#{Ip~xN{V@EV#ACts-tCK*^!MR|nrsH*Tr002UH(@BgkN z!Cbr*+$Ax3H{2mEt(2x3DA@2cjJgL{JftWB#f>_|?)8^Oy0_w?{pX zOI}`o_s2e-OfDDY&1l#Bb#dj0o9de@?+;riXfMC*J9Au`#FuGOEGL>(w4H_8pwCY> z-c+7{$zECfa}V1Y3EPgTf9A@LFTb|D)vXcD)2L~$JT~6Lc22_X3|Cm!n?dcAGB#B+hzD_K;#)M^p69R9uGN(WSb4~$>T)T~H>dQpvaCd3W&Jya zto|nHbi5fh_~}HX{G|Dl<@e}WDTa#U88q95@<)3({|ueoy}!Z&T}%4DPWzi-+n^eB zd+jH&)rWHQrK0X4iNS|TB#An)CAowp>r>*+-=yf>x6P>{KYiLRK%Fa-wjJG~fpvss z%ELSZMJCo8auwI_-|O=;uQ-PsF*+Uk%}aS;)S8y&Q^<$UZP`kNKD_106i0V5u1(n& zSjaGrp*yEJ7A9{|&3U4>yw{z!8jOmK-~%XHhL^BJ--(ouwf<+ypv~lSxUp_#MB^6ckwOYHUV# z(DWnbm0 z)+*#4rF#d)p`+x8C4&dv_*xc>rnPpU$ZI`wKj6L*z4rm+RPVhJXU=AD_J616jhyad z-d-%gA(JYEZ{m=L06&LJS}6{%Qf+k=Nn83`L5UEqw_-#6EGk)#*!3pfV!n4Q%ma0% zk-xvMPTeRl75!L;p6thWZ7#dA4Q3ADo46mE;v-ho+JbMd&-XCuTtuO#^d!^}I!ZWN zXI>uW@DUq`Ok`$!J{eg)O>@`il=l^6!@4>XS70h5h$D!qOI;9dhYJTu)%}1wM&=df z=rY@4LRH~z>TwYBpBqlg;52ALS7H4=(N$bc}E$Xtpq=X5<;zqX15i z3EOT_$@v;TAJG^5wBU_YcS>YKKT?zYPxAbG>i3C% zALs9YN4j8k*#4Siw0 zt9q0=wTPpnHn=;Cs#fDkQqfm?`GZaG#!sJT+v%F~%5;N;DnzW0Z_(OcHqVqw&KD?m zem&XhMnYIjWqfme?)iFIVBe?9?)^&{)Oc!g*0QJK{NYn)N|YN*?84vX`MxU&*ij?o z_!#~T%yDK7G&c z*q`t%;!RQI?aJepVvfR1A)1%g|3Ojf(8FI-Wb4pZ{S-U%Vn_Oosa>VNm8E4ew39w* zGhE;dswn*-@8(*b_Wi~Gu=kchSw(Hw=qrkVl#skAL;Nb!*?1&7+>7&c+ zxDCW{%I%N=(g4H<$PN$_N{TGAV*&vgKz@LC0a5|Pg_2^+>|TKY9Uuch5`ergLf^zv zRY8?dzz`i63Mi#Q)2Iys2+`0rG*SgsVgX4MASo6m;>0Jz{TOHEVdQ%~8P3zG{{9RYL4o#e$u{LmLIV9}Z%bTA^Ixo)AkJ{BH{V70M}qrNVC>n-RG43-!f!Y^ zEeYm@c!6XaRB>8_>A`S7&;cU(mRJHrG$1$uF$ajFTSX)wSOC#@OWZ2J8iWJ^aRmqr zpm^~OR}+pI2-WdepW z-ou+x*b0VJz)%6mQcniuiJ?vTMlk*tzN@|4)mh&1iGb(1<-u;fNB~3bw?k{Nq!jvS z1KN5_ux_hgU>4}34QP3ZV0n|bH(?4S9JdnaqYX&H1SG+?w;BTqtAecRRZticWLe)9 z?f`{7Kw;k7!ngO$bvp!BJQ)wFFoP;CV8x{*pvwO3(CzfMhlL*$-U5fk;P$Xw+!nq) zEcZa+iz<_}(J?RT#lW09xagIOcJND;iNwS;3*Wo94*}^8^s;b$e~pfH3T-o~`gi02 zct2@zT{0Dk(C>g}=Lw8YCEzZh432U%{Im!`4Gn5y4=J}Kgb4D%u_lHS(_-LGfeKDO z3RK2{2we#rcU1UkRRAqV1f)NP2OiRGNo*T4k_y4)sX-#>DBnQc4Um`zJ(rEa{`cYX z22f9c`d%_TN!%M)L@EVP4D>IqB$(j(1TX?%AV`%2NwQEsBnK!AmEg@Wr8fIa}j zp(YnmW`_e$WXB5d0YG|yU;%bKxBUwP?2rsVMu1iTNdam@T}SkHs~hMpxAX@$no3Pk_DW1TPgQ z=sKK_;NHUt#%mtBWRkNI*wDbQn++8}=rs@`Fa@+Lkh$WxWTvnZtlkDd?F#5qFmej2 zp2DZL__MM9Kvf7ql?LzxFWt6|67W2{2d%CZ2^225EqvQL zgusyPZ5HTzty-Y)Ja~flus~tg+rr=pUh)JI3LyD++xWzRMBr8eeX0npMIJ~#fZn|1 z2qb#9k_fN~YCzI-E4l3xwm`!82edIVP-PbkUEXe`IH)2BmjCazPq2V0UblVXc6V)W zhi>=f|JIvI3|Qa)r`}W|s{A9`iO_wu7)M16F%g191rnbNT3g2dEYv!!jW7rhCo^~r zD(;VW6h&~`DD>Fle^nP|Q&3ASl>KGsJe6Zzzp$`yOyanaRhNV5;-YzW7(ep4CP|f> z|1qZW@AT-e3iNniI*9XyzN(tZc`g4KPHy6-JMDdnMdlUH?bxmzz#hIBe6(PG`}HxR zc~P}P_q2aMQBM0^&a6=YGk?;cFJu|uQP*f^D zg(RHBSWIK~jhK;q8X0D#H`;&y?2!b`r~Q2O!ef-PV-gb(*TZ!^3rB;(3*s zN{r-z94E6!-n$wU@~6!T-}8r@mj#h5NQYv6EAE8fWtIE%Gn%$mc}d?Vp)5P6qMO>u?ZogR)}(g~K$iGI_^Wg@v_l8yx0 zE+@Qc6^`=6+k1qw1BZ{bh+qGrYFUpmE?6c%t5RE&zut=Qn04-tN=!YSpKSN!T}bd)J=gFaM}RWTzo&`LexRl_|whs%ogC z1^rv8YIt?Qm=_UJ7_EN8ES+y`WJxpL+z~-P^-J^X@op)UQl&b4C&&1eB@LOq6i1Ef zFj|f=x+P7ry;OCj>M(MSad1^cF&B+dQM6Or^Qmr4N!O%^qN3=dpU!4JDex}WEr-C{Dba1Z@zYeLouL()^CN|KHIw@iPaz<<*>&E+gIfpWL z`zo>j>pmCjyywvh6`ooa-PEI7gE0vXXzaYzS=q^c3HH``?^x1IbE-$3zA02VYFY3| z`5n6J`5$H$=4T;bO`;@asR-Wk}6VR*M&C@vfG)ul(;o!zhXYrgu^ z0V0LxGdXr9PfRZeihEbj?$Vp!K2U@H*I}gS@+-!u=)m!*U#-zT8&----LIXiy_dQR zHw&$F#ij-e0|s!?6xbBv#|hE0Zj7V~^hj#BybkK=u4^Yu>V~m8BUH)Deh7-X?)Y%8 zX--JE4e*^xMdXQak=uS4W>Hsr6oi~`eXMGhTG92ZCN)Se%H!m3mYFL(f*4zzvPI+x z7gG}B^JFaLN9IcHY~KTYrGe$INvSe~iIXC|b=D*s3(s?vYDKFid_<<7Rn{b5ia1@?v})k7 zC#KMI_G-mKTdRjsc~#Mdo@TxZQj-u-1Q94RQe{mwZ=RV17U69slK3f7LYccZP-X>` z=>cVqLYY@k=1Z;TaMCMr$X@&9{xE%eC z5Og#ljc}ft7PuNQa^@iHW$U1g;T~V*$<#?X%3@W0`v{HwYG-((xA6o+&+cYOYc(a_ z=^u3;mRrhHUI-1bxF}AGL_y^00H){g#W1>~yc9RzJBt)Em+Sz_aP_v~vMAM##tE-W zd6J~2UR$GMtT5gu6m8i=ar%_x7RRR?rpgFQ+p8&sSdUTVfDD$5gBMnpNy<5mRbH(Y zy~SanyPkVTybkgfolT*(*G4|0NAGhpJ^2X2v~F~T?Jg^;Lw6raE01U2;IAI$)VO)Q zz(Jdsuum1tC_3bw_`N|Q=&RW!8-?Gn<{Bn$)x)x47yR-zSpSkQ8t@b7B zy!GkA^fZnnLqdBIEy{Yfpf3R#O112yQ>OA?WYJ~K#O;(5QHK{WhE~0Q78#go5ub~+ zh9i8`ou8Zs-H%= zyL1ZZd@<+MP_Uf4%M1l6=d^dLe&XitvO_`mc?=Xp=I-)E>3*a06o8!-Xc~N#9IHze zp0!>)*w;_e$8*~(Oub3NvQs8`zj0}v&nhFu9! zJ!81rnTq``#}W|bsLekDQQB(QRS-2WrUX%@b?$}9%H3zhDVB864n74aGm=@_>#JQS zWwe%FY9So8fOL#lP(_rdA)4>bbzB$I|-ow_BTu(Bw*hyL1I5J51i6!8iOU zHAFeqDfdg3;>*q6uj&)+a!%1XhW4AChmCw_mZF&gqrZnE%7g_xZ2qpO$@Z%_er=m{ zR9LNTa!VP3_2bzr zrAF-Ghw3R#bAynp!lP_tbM6v`G+= znD`AMwryG;kV{s~`4R9%?AYPz?n%^-$bM;|dKa4b!dHA)$3_T~T+;Oi8YiS%ru_@) zN)k&U!qY}5EQ0WW&sB}0C?O>#qOd4T28{*@zwBL+6W@jF@dlybKZD}Xx_+-{7U-8| z?dxK2m&+u$rYZxuaSD^lds!m1m>SM5JG?HP-|U1Rl4hd}^@e+Dh88C35?Oqhr@Kfh z!d2rxv9xF$aTusunBvY-GwDY}A8#6r#EBLtHF4R<8FyOvI>@^{*>r6UZAnlVnOl&f zX^g?J5D{wGIMUk;RyY@Dzw%Zh@%AP!{p&4z)6yCBI-f(Eng4TNDb|m|l=4>s zF8q}0bl*La2Sk)nJ2`ZXi|+EV_V1tIKX;e{vGcHL6<@`WeVTON|AK4#)vHRXc*m?f z)wHk>lTJ8%yoTpNq8ZK5k(E{g5BrT^8vUKO164Hnp43;b&`B?7-m*0_iAwJTqe{3p z4O*0^NYf4-3AK#fdw6VUFm_MjNYQ8P-nS!%v@zpXdU9!q=uZV`Pd3I{^U=PWzwsF} zrh1pi7cuQ_TBu^Xt|z3<%xfXOj;?8K?-%yL?5M5opU9h+CEMdf z$9;{5pL!ZxcRd59_R!)F%g1L`{e||8jUJQdN@RMwYOcPi*`AN{T=4U_)>-vbr})PI zQ9N%$IHF@$DpvK+&n+n#ww+^*le^_}yA|?{HWc$!K{ z6@L8uZ0qsY!hue@-x9{2asqT>l$+=Wh!;2-dJzMD{E4<*qB^xNe;1%-e!>q|J-wthsT%>G_4hsxM=irH+Eq=zG{b7jadMkhuhC)Qeyy-`*i{`WNN3an-kM*fF%@OakDME6 zY4$Ya9OqP5#(2nY4z!P1=J}251s141DrzQBE1}dRB!tnMYO{nR{DIH-Lf1J%^SEFq zKycj*uA9NNH@Nl&*EdNMo8={yzr6@C=vwS#qiQZLBh+RW_d`WFM_ z$*@=OU6r_5PO4Y3%S^+R?aIdbw&{GbsuTsM<4&dGd40TXPW13VpEhq%)V0m()VnMU zyH_1@3?|mOUuJ675h{@V< z+}FexB&V?&@0)DaKe@AbaOgF_Z|>K&_Me!YSH12(O`a#2SZ#keUf?a7tGYR<%PIQ1 zS9x*3m#XndPI>%(zVOh|f`x4V!b-nmisri&L97eD(}r+@=6q*N@kCCpm3iD239YF= zoUaVtWiWa@!i}j8Y~R&s9ad#ZAGh*)n-x*5`KaoCM729WF@V`^nhfpU7}sm1`p$P8HkMKN9DZfgu`E5V)QMTP z3Ez8qyp;c1Ew>9wkdbxqn_1Ey8SP~p6J$1_WM=k-eN~?m zja~yJ)~9G$kLbkMJAXY^q}?QM5=07{_L=w)R7l)iDjhUy zGYyXe27fjo6F)mn@IizAIZW`mg8ZI4?00d|*#`S9@6+O&e{Y2Ro{(u0vPhA>h8;|# z5-`dDyA%>I@4Ny28_4DvE%`VXvK3O^rw7g%dSIo2>{XD#6POg)As-}U@MHp}8&CiX zU^Z~`Jc84|hnAvOMZS0l{ECL4a1v~i;_`!00whX8{vqAg*MaazE-*7@17i;+SPdI6 z_VC=AqwWLa&@+IK0YdIj$WR1qTXxh?(ldj_XFx#<2w=9d!vNR7B4tMk%u$QL(zFPC zN{b?}V38W2F+jXqb5tH!!8?EmfJ6Y}0ct?EALQp#0XD}G*oqv%^&z;1Xvl$j1|=2v z`JjU#bU+7z>mYC~4X&jjuP7(l-B{pQiUoVC2DU~GY=jyZSHlJFsA6CMEe0D}3=E*f zV9#v8D`i6sd7r2;X2Gj83p}>7z_d0COlz~i2sI0t*4(8Y#{qxnEU?th0;5$gsJ%l8 zzverT6VSLZJ#6@Y8#-Z&>i_Qyo%(kFZyP!(fceW4_`!~DEuhUzce9F5&|3(oG07GF zr?vAw!T+>&zWHC)PP_kQ?Nt1qDW4(Rv?AKwHt_JQ0KBzzAAo1>0l+}$$&+dQi3+*_ z4M3UF5rT(#+l?d5@JNtU`_ec4<2Nx7EwvE_7}s|{zHUK71Zu?#D79D|-&3BjLmxc?Lhiw~g%64nco}Yf7#GbaoCda!luxHnzr##8{W1%Xx)zLmy z7(6K-SfD{vmKt%ak%*4_pe!}~SmWd5K-W3r>n%cKPl6{W(&Yl^4=?aFQjx!0B@_-I z{qhnXH@jol?5tan^@or(C~2awVRH8tli_O$sA4>NJVg*(SP);Wg4NKQx!Ba?*R>EN z)O*kj&Gm7z9TevT#d$$-U%2?SBwYN4a=hh0EH%EaA~5pQ^4IM3 z9ycu9t$7$kq-e;LO{Of9R~2`n@X}=5kmq%KlvWS|6@R2(Q-&@#?gSbVZg(mr7(u4b z&ZvqjR(P3Q*zV*Th_GVH=2eyYw<=LUQg5%In4%8qGWmxp9slPkC*oPqAttxSpCyN zDQvRcc{4{wUg^2|eTfN$-O(cP^qikC?50wh*&%P|8ya*qg;vR`;3^bZ%3Uuw2@Nx)VjLauRaKMUmTLw@d|s?P@>et0`0q#^t7^}= z#kLY5I-Sz-*S+8)J)=@)RSMauoBnOppBvRkR$gN+4EmT_cQ~32e&Cm87yTy@J6r3{ zO$EOG;YFp^9m}Z)rDyEZMIWoIktZ)twp4%ez@m5aJOjB(l#fG=DVjPs#3^cBw}U*^ z$eV1&m-vZq6z&k-E5;(Xb}Q{$o9}Dc)F8JybaQpwJC8w``OrT{+TgR&!jWpriDGLG zr%d;?kbo2y$GzV%D6hOiIm`GaX*V4l_p%|ytix6;_j|jZ7W{Dim8jK)1CmeSdZKfI%O1>mF3g;2r#MT6lBxJ(^kka&7qXp=%gn6Sex-M)*jJ_%t9XCe= zkJVf4#gO;c_|3$*;jaa&8ImcCMV346S=Ccy+4 zqGgHq@#69yV~1Eb=n(uUfGhHU>k6sqF_Z^W5wg|qyJ&0`eL~J=K4~%KoM#U9bpH8M z`S(5Z56j!Flk&*uGCDFMv|RJdL6XD@`uT?5=6=iDYnA}efv2of_m{dA~q;p^X>x~mC=u> zLI(~Squ^FwoV=uFiEVEI(>yrhre+}&6}f{ZBRgt9A$;KQRs>9gaZU=!DT_be%cjNJ zA1Bp0G?U4Gh69Tz5oK?9y2>T;;M;V!?HiViX;+4Cb7-;503zbD;oHpiuuhOGe_^`* z(I+ohn4d#|PUCR^khC?jE755Xh?~RvNyX2h3wzy*w?ZXz5+0_J%NNl7GQh*I?6&(YuSbQ4RVU<5Ek1BVgR-6RMy|HQ@XF^C1j#2D&$7dUgGcKSH*Ba3Bg8!!XQQ zD4+q1Vu|dmB*AYJ9({fKWrr}#IVivfjFfHP9F(R4G!|i)^H9JJ7){$gIB*7xyDjDd zdrQRgKoUIYmHQP!p4foP7?{Wg??T@^F&t3=DyIb{= zx260&IB$IGWzXS20%rKOsvg0C2z(OxHtNoJT3X-BpkTA+C`}4z zwyTEVKnyUOWnFL}2Q$5=C zba1m=O(lZOpS~rOrp?I-%gz1bm*A5r`x&=ORRT*dslmF2Kebo%U|x|L`jTaHxyw%F znF8cB=eWv>iaoMG^~Y5yd#%DX#MqpEv0^JdKY)KSrD(81 z!=HHbp+J#=2{8lxSlQdq5#9E3Ju1d2{{eErR&z_Plb3E(zhZ4ai}qpV+15kE2;B1%H!l9h;V}l20*w1!WSk4H8&Ygr97{dqvSq# zUT-DPt?phCPViYfrI;5uHuCWZc8;AfoF3DK_qWeZq>Au(FE?FN51;XZA;H=b!LLr& zU7lBxnTISpoAQ*&-i~_SIEc%Di}Of{wPql>fh3tj+?9UtnAvlnWCh79fS-A(=N&W9 zzfL-pUcnKU`(PB=QfNrI^m$Uq=X@mgaQ$*;F^{VxyT0iF?7rw(uRP+r`tK6Fv(4w#4>-BI*ff^Y~vY)^N~7OL_jOC!|H&|GN1$ zj`|l}v6(@{!_-<`e@USaf7~I}DlTEK#73&;&8q|%e;gkLSy_fR^2OXW#<6P`D-Sjz zk9)g577CJ>H@Qy#i`E-%LNr%MBQ{@4O%#&+*!pzN{b=-ZfdOZ!`#BWwJ{}{M)5#Q;lAvr~P`ntK__Kms9kH zKEj<8MU(_wQI}m%(AG&&NJ&sjdgiF|3n?H{P*s%C&g~#4{|j>Q>njD7vqZPnu=iX% zG~aA?5w`KrSNy#M)oKCuj@MrMhdmDdMeBvzF@0U6oYZTz-TIaEI8rwqQL5HnCDLKi z*4N@kiL-}d#y-!&CIysboVTR7JEr-@Jl~`=U-i1WsyxG!7aJC&|Mnn> zRPZnm)2oNyGgG)z@NZpxF}j!~PFY^sYhgy!v5nH6O|khgkJhugfTE;h&joh!P?1kx zU)yPNX(;kER%U9kMx%BtKSg=@BqZT&=-A|C^tW7%ELrxEdy|D5>d>F7wXn{QfBMtZ zxx>OL{d37Hix}Itk>*W2$>G;wmvauOygZ(|L$(V(b@}6+fq@<>C=6{w2|^K%6`3rj z&EGhjrG^kBZuu+sXmV&;2@yi0Gv;NIS`t--Mj7q2rtz^u<=UzTxH30;>UL7!dGLxb zkS&G<8=@mz2Z+z+O|=;NRmyE*BKo<*6rG@-q=@;m)_gMDR~T(tQ^+Toi>X&+$<-=h zayHRbsPWR;=x+RO<4d{GpB;pgKU4apzAbMi7ho;GUj}p0fgk8OoYh@fH#i&ty24of zEPcl=HIOMNmp7^YrRXS`+}tEoX7y>b4Usd0Nr)}VCcRH{{p;|hxS2d(OC9OGliEW+0U`i4&aL^FFR(Z7BavYs^F7oUJJAuuy z$8l51hw?6Tir&D#Db?07$4x~y?+=TWTFkr~4DqqR*%q zk6LxjCc9p%IB*p<`81`#*u%{G?)Jf$fv}zCIcM2m<$K2X>w#`{K60sh^cz$~8+NT6 zg4FI<*QW72vrjoOWWC*&%RVc#O7;t}n03s4Q&#Qgvg8@R3fAqH8+WpztWP82E?BKg z{Z>Vrf#~044Y6v?>&mg!-Q3c0VBeM*Gm1aj78*A18R(-bM%?K}q)AYZ>pOP1wPM!>E^7MtjRJ=<@%l`g}YZub4$MdIZ1ss2Yx4C)2LJnK|p^>ic_dg**QSVttim?A)624P)G=vpl|E(&R z{0Y$;OCtUvmTW>3b67qQ z-&oyoP5Fwi!t>Vn5dBe6Iz3%rA&bNpeE+0pMJ%n zMX~&C6uP2aQ=N$LAzqIJ0ZkPOIg?agdx^bO=aTn-HfJ3-$?k_un1&+aS2%ErE%B%1 zNS%MtG=?_ntM5EjA|o$9TKeau;fj&?XY;o=-9@IPk&zymyU2ReY$S1ccY`$aBf{eC zqnnX`719q1Sdo}UrbiVYOt3b}GMU&hy@CR)35VQ6_c9xldzx5|x-46oSgtUJ+5vRZ zh5i%!#MeD<`#1e{dSup)TZ>nqKb&irv4Y^!b07Pvzsb@l$%}FAwHqXT+8u2lJU95} zon)#Vy)vQs`BwzP=YJ96WEUn^Bk!#l@g4X6#WQ4eOovdv7em;)+(l1$>)tTOETl-Dwf0 z0y)DK63wUF(J8X$jRSc{q{F+Oa#?E;Ub~L;{9#8PsY(dO+o4E!sPQ8h@`p+!NwH8~ z&DRiRPjShgd<&-AU=W7>Fwod|u_WfJiF)(jpT5>PurMEF-)|X;#dD+bU0jzAYH)j7 zZkodXQkq=d_B_^sLOqr3uzIn1AoO_`zMaM$>`}<|SogQ=`w_OS7hauKIWvLu*nQH% z)eOZCb-eAe18?uH=q}0G{P;bi|2RvnUTNclBvtfc!7Q51u0Gk*=+Oe5a_0uYaH&1^ zoqMianF4VVKJJrM%pU6J0b?BfqD$+#YfdtqBuuC7gbqVjC-(_8efmzs2wC@&PiP4( z!mUqCIhB|APY4Jt(lAd{Ik&srT*;sggoy6xyUmA+q!B+(n^S3_81rN$zn zx%1^uDg@s#l!`G~B4J3lhxdKh+( zLAa_+LWL?*JN2UE#@RY&pJXo4r?5r|8HBt-Ax31!@b#cfPvv7M>d&FkPEhi8>K&q443x zzg#{x>sTXq!=C!dnU?GE&SGgQIDLspFvD$PGeQT;=Y8SRIf8N;vVZ1h-dUciGn{I} zo>+pJysJ}BhK^KIl|4n5alVR_j*(!}Qs|K6&n<3LID{o`mYy7hM6l#Fem**#D95xt zaAS|ANb&3}sYB^^TrZJN+5OgiWd9X`!2YoLHuq;0KJHDTx`)}$+fyy8M;k-`gpsP2 z%=?C2Ihk}EM=RI4QV@SmID4K|3h0+9by{jtR8GG5%U*=7u|;x_Fdh(8FrkQ66ovHXl_ zZP0D6YFY%i4p12?sr{ot8&uAM{VnGf_Q&+;&UYZ;4fFeu!sY`@&tw>NBw)i!(;I-2 z07U`Hj_Vaw#T2CsC76jiZ6Ce2E*%T`?CZX8)Z>@Ns*FZEin z#1)+*VnKTCj6NO~_Yev#bHaU5FoY2eq7Vi)h(nmrAPM2;25AUm8f00& zXp79#b*#C)pwXE47nqz6Ii1mv3t~O(mcQ5CP@9EryNVUp@0K&0R*=8W$Dqw`9nz?@t82Qwun;P!VYb(wnU{-O4s*xD!}hNrdtzz7((O6aAG!L=ws|{ zuZx`a-LCz5L$yFQx59}@e;nJ^{a;Dn+H2prRa=+8#cH-m1x{rZ;>*)j14&%;n*})t z_QWPPcv-#fXnv>=$=wqVpErhhgYFQOpHiwM+bVcxpU|7bGtPr zkESFw2*_E;%jqsaNk>ELYR20>e~($pPhKC~$J6lOIB4qb+>GXbl7bX)(3U<${eNr^eVh{Cl z=chP@L1q-{?3X?{95+^Nv-sF;pSk(=x_f;zO3J?aeNqzc8Y&8%TFjH4sNGE+s_S5k zJ&v8`C$>OkYyaEFE0*BBM$d$JWXs1NZ=tO<^uc*3OF(ywi^FzicCMRbzPdq9rRAs@ zA6@PderKbV+69=>5y;pLCNjwrD`wiy^4F#0h+eK9NR z;9QiN#c)w%DjSex$*VkEynp&3E(O!-IBHCbjzZ%Ae) z!nRRT6bEQe+^q!lR+jkGr26DT$Hv98*#tfjB*rjhpMUJ0;AyVfJJ)`h$n!&yelucC zvWiB{$9hYlP{6okt=auJ&%;4}ma(Vlhl!U{0*7mQmrJZ3;;!4ZB35zOcxE&ko507o zi)zHiOqknwbu&vB*(hnXe*uFOE0I=xeJ*w6%im+pH1WY@#mr1y##SpE8xbPnSe!=HrkA_)z}@{L3iK)LN`)_zSl`>I+OKa{35@55mN`GkY0k}mHdI75e*w${cx`+& zw%SkRGkzCXPwxVgXcsVveuUpv`MNI zXpC*@Vck6T4>_%!et(qZG8*Ejs&2i~;c!e#CJ@zd6jG@HwJ7MXSvKsyiKJnub>zSq zmCLdP6}3EzaASzZt^^$eq}z%MPz3m z6N5MNOQx)mI;AMJHBTGCbINzG9*;{rlH`pt2*V4nYHg0 zTOF>B+q|8QN5?-)+v}Buv$_uQ%{_uEtazh~YElxpOvH+A?|8q*V&&Hb*FMj&qtays z&UGCIesX7z`Kn=D1wc_1 zh64Xw5;*Xy--d$r+{7Iy_*B0F1zEWyaPYZ)4hmLs6Stwjr+y3yqH{^$z`wrl+Iy$} zZvWSEt>rFL62?Z?dw1|j=uhTkCfF1tV6VkSv~ zzswWANU%`z@>Xo~m=2b&=Bbngh?-=t&S`qiaf25+!K@W!+-#Ovgm39K)Nr@>S*Gy7Hd=(IH3oHzG@{GC3ns z{jZ)1CqxU*W{PeY{l??BU34*D@RGMWMLdd47_up^owK`+K<8;nWU^tM{plLiUgS^m z&!(z2&F=1kHP(gv61VY(8s05Iyah6>3+#5+oVIJ>{W+7In+IM~$Ycw1F6Z*!cFB3K z=sI0XlCN?9{unU0Nh=P!AUmN5+`SWU74XMn(BS4dEirR%q(3WnUOSFbA7U}>$|hy+ zl3_rG&6nTUF=Na+UdpI^Sif@ogwyKYv53^SM~4BFdGZqL-1~89Yim0*!t#Ytb60lb z-;T8RTZ5gLlL=G>PG9Wt8TMuTlN~(dv*^o^n95#r>rD_3uazA*tYr_Q^h``yL$f3o z#o^>1h#cpOHc!bZbju&)lh-;_&Tva9TSa_YbsJB}VMtixwoD;r8#o;2n;Ya~Q9pDN zKV&RlMfj|`4JG8{91C?h5~U=?=CvETbNx8Ue0gZ2Ro|BL)^R(w++vM?FyacY7ww=N z=~obvo9G?I&q!`6cm4?bG-UthxwsFb>PO}8uXR}#^WPRa5}+K2-BH72=uAY`W-okV zi*Gkp`ib%RV!i>g+mDY0V*89|GAX`VKKH3&f-g2(5lL%SDZe{;)-Wl&SMp3#T+82o z&}`(PP0rr>!4NB&>uI}E9*ANbQNCNEt-4Ptqj=&Q-9u0AD%tH->!7ijqq$r7A%`j? zj^JeCUAS_Qgk0cjqr*3@0^V!s-|Ke7r(A8e1#QlW*JrM6M<^yw>RWn$Z+|bILiML> zy_|fMO&D?}Ih2vN_m;RwbuIM8QsbHEPzKsrmbb={xzLN|^52Y( zlD1yksJQcq3wZnq-}KIFM8jzB9r9Yrq)NLVdWgsE&0nUi5BXgVdo#MT6}|L~HGU!P zq@OMDqEUrseu^Q1B=z6=?ge?C*AT{!(bewtz=RB53l2`>`G~UgOu>9n2UTMdLW;>O zgCED5z0Tg{b+PWrGIQZmT~wOiU#h%3_Q6ExEFv%ixeXJmdH$S)HBT3JYaf{<8iw`a z^?8vk9jIZqALXW;`z48g&Bh(Ct4QzJ30ZY-Hb(ZHat~nM~p`6=1 zEoSY}nE3?3df_{LlCSV)bYTnI;+!o0Q)V-+Q@-JSzX!)*e|Ygl>Idd{VffZ&G@b z=?yc(!4Hm80mA|qh9;$#nQi>{lJn!tvV@Ka7V@49vwo68PCF0WRc>#I^LOL0soo{a z#iVogejRkLjoWoumh(exM*=#nJV!>18GpHQ)s1?C=Xu%oSn89&z)L(`Mo|;5KvqUk z6|V;rG3nFgEO;}4UC-*(PmlxC3rzIBKeJ%G5PE5EXY<)mdz^bcitMZ{jdslU!{4b1 zPCnxjvS!Y^&J|}ep8DA?yNqhG9HJz`+*4`coZ}BXhp##eR$1rJFIi3e5pO3aXc(ji zkeVNA7`Wq~M4Nf`^>#X12xJg>29ds?$~pzB|!E$Fe*9q>0^fK5}VWpLDK+Up{y zxtlbmtMeU0gj370f&fKQpf-F_~<(H`Y^7!cfCX@Bi*IxAnkSNh6vOi13ib{ zG)6P8u9pF2q*oBp?|>9X>Ugi`jlM%~IOCd6*Gn}6ZUUK5?!XnN7u>7nF~Y5X;|j`? z@M$|p+Z>E1Cz8zQ%x8pcR+%ulttx(ea9lL%D~O-^J*}PL^<<#UQ|n{@!P@z#9IoIe%efJpb|cZ(?)Z&7u9i zU>}WI4R^Kgfq5aezb`kDC^xcRF&`p?M1HnY+YU1kTZ|#pxX8kt&2p^GAfxV(j3Clm z_wwiQ0M^yC_WOpu)}UAZ734{;b_u#}6bNQ6cdpImoez^&11+aXXQufSk7IJfy(pxg z#CK}J|*ITRaQQ=JXHi<*X~=LtA$sjK)n5iz>t6z;pv#ou3(+A!DB)R{!2S&P~v7@KQF z&d?G~bNu}+`MH{@&KVjOw@EQJpNX8IBbvtg%lQfSpzt#tRY>?~!0La<#x}#2y&Dh; zuLeUo)KcU-mq!>vlmFtmZ>3LgOj}Wu)D6mM^z5*23lhC(73)<>nb-N#lf)@WVOX}% z-)^)$`&^X`?;T#-bk?iFZgW-w%$|^m;$)vQLwAK>iyFCr0#7j+3@cYNof59Qs%+!r z{q-p%mhw3|1DMsZ8O3Ya=cyybYK$^R{UmSGIt+{4bTi5Hw5JZb_PtBk^qO7AIg_u{ z=Ct&}*o-f@D20QknnF7ZcXiA=PaH)|JvW7ftDC7b z*faC!#;rt|r6sp){LLeY*QXPfbtFVMT4ChP+p%T>R>dDO+xrs|6n-rf`nSdB-t&kL zh;s4@!el>i64%(u2+tW|tRCnb8RJ>!omF{cH|WY$|J}E#Z3uyNjwP;URL>!o4`X%2@~AU^O_vl2yX_D4$>Q`g6}1ZFk?K9mj_X!}XF+>3Z&HEozzFOmQu%vNhZGa(rh;Hm491jHbf09!&K%|BjkZUkRtARN>6ZN>f+9_C4-r zO3m?>l4ixRVleO$l^HuY50s_$L+XE~@NvQ#sh?5db^Oe|UM7W)15iY-@Vaj1UXsrD zj}L0lxB>?K8*q^NX`G%uy0iAE{@a(2hiEzyB0rJ+n5iijg@g!k9=!+~g#L>AJ#CS7 zAxflGTsS8P9;|Dk$c)g>p}u(cVcm1wg(liumUPPfOG6<($K%6)&@d#Xzppt z!gY$D!ZS{Q{7sO54D#;_5$1n;Xh#JEU*XcTGH|{P$gctUGpIVbib6lPfdC6kKnL=J zKt8Cy^VBJg9_`L45L|!>u0Z}BIDhX6od5pIpnpEiJw7l2IhY^}@PI41Xrv&-nHX5K=*m00_!89dcnhB6; z2r_v7mjsa;AKEn)GqO z4c1*R!n%KvfM5Yc^DVIih*&@fLPXrhN8~X79~QX!Ya$pwhQajrB!Hg)MgR;1m;ewR zNv1_~`eY~K>M3Lij-10op^F1L!?8^3)O=5C2wg)dOZ14Sbb?jjStUgurh zy=Elj$zFJIKVIMAID}5h$#aE|eel8YM90&A1#kHOk&+4;71k5@c%y(5>I+V23pm#g z;d5>GEDic?L{zR|_(YS+!H+{I$QOt6|04*WdM@a=f51UvgYy-n;S?mez!UKBIDt{| zb)gj;qz(9~d3_hwpn|?A3Fmzehim(x>EsFty~c&fFYq(=ALzjqxhDc1G-J5PLn@~< zDYQHG@bx#a2GBrW_``W@pidA$oi5_xpcK4@Y;Z#vK>re+N1qrhHU=~(89Ml;JHRTI zK@J97_XTJZNw3$1bg1tofg3OdIgwyvx z>j{7OA{Jg@66ihswD7!ZpoutwOgBH~QCT7A*A-y_X#aLk;R)iPJ)=Zo2E7M*|H%E} z_kaBs0p)<%W1)r#^`}^{5e#6t(V!+hd}DU(aLwA!pg+|@djP$^fC-AhMsR`!k$?rs zLQg>L$IL|VgxG*5q&6BpY>OP=u+0Dh`oDglQ&xN1fS3XCxC4j) zKu`eULoXoE0FeWT)LWt-5XgXt1%%!$aXSYlAZh@ya7*0IaTgF_fRF}@_WA?A1pnf} zE)ar6>j5GL=q`VQnRtPY0_eOCz?%wa*L$3R5Cp`{Ede#qd$=!#+hE}$=&8?^;W_p| z!6>kY%3w#7f#83z_tsHa1>yRrgfs|9DW!shgmef)v(O`u#I|_Pp=&yzk7OnUB5M-}60#?ayGlGrT6t z@B>R3G7Lr_nWcjS-d6gRF><2@xnN;Qt?s$sQ4@x@w}El3vqBHoo9{BxSS)UpzHa)d zdL2KoRlB#iGGLy@fdwbSA`gp=DL_Bvj(nwbe%GzNHL*98UEr&4ZK(KyIfsIqmF1`X zA@NTR`|pXQZ{+=BsZ>zo`cA=_NH@jmZCet@pV#q$GP{_XQ13V9iUnHs9pg4){3-gg zjknnkW716h@QDpt-e|vY_vv@sTmALs=GOvgfncMtZ_NZByhVC@IUKM0SN=TXQp0e5 zhD|Y)PqSNnR*Vev9p3G?Dly7H*ZMc3BFO zjGTRqTgYzee(K`IyOyCj_^pBV>O4LhmC`n;Tqu8`;}@=5Gk;sQUy6MpB6HV2o}ttd zpeZ|4XQsL~;gyBcsk)cSKVWBYi_AKdlE^oO27CG3bJ%V+?&PG+!Jj|X)||58b>GrT z%&@+`k^Hh22I+ff4#kjvZoG~;OQEN(5z8>pd;qMn8U|tU( zu;;}T!SvUe79aTfYs_)biKAwl&#Ry1xp<*f`O>3bV`URgcN}dd*9D1cT&VV_)?aJ> zKwKFFmIW!MJPADeZ}ykVVH7DHY~+#^Ds(t4(&e_D^a^+``sl<1MV8|)$-N^9gDQDi zHbegB=6X+fmP_{vGolL>re`o>urGG3UXLg^*b%h*4ixTprrGFO=8oU8Q8zV|c}1dl zhh(s&APxVA$32^fM=h2yf08YORRz6O$Ar)X8N5yys6wk1e1j{+Oiq(!>{#PYCT&X= zdFL6atJQn%nU~<(o!>0(;ePdwCdQ8pJIKki=J;*ku-oeDS(~m^Rv}H1^+l#T+@i*uEvv8XALCmS zPAnJ}wYm53<`azX-1O2#*`h&;H9G|fKN6qVnLPh6N_TeqJV-fP-(bb6+K%14oweqq zQZ})=hqhb#x~gOyQVto{L6jza~(@U(@y!O^kVV9!ur@_7SS~t)AR0uI!4$mg*0E#?P~apHEbMy(m0thqdh&l z*I!qB=0j>RJ>b(6TE4jjxHt6(91(KN2MD=;^8P2RwXcBaLeCKkVWN>kn1Z8`0CPwH zPjuM)7-{z5@>MHoj0>)0H?N?k#k%?;*Hb5Au-Jk?cP}AfKc7`SO}&_&ju1 z!DG{v(V(6}HYl7=e+qK z`Rz>^kNDg#8mW>_o=-;J0Ku}%l*(8K|JmD zOjCQ*&*myzGGd>!<9abHUBY4nakLjQO;ho-H!@8lU#T}RCHzhwy)UpSc&T_6pEx;3% zvly3=i1?m>Lr?1yxA;@0jOOlE8Q%9_>%Z$tEmwDmIoYfah6;p4_lmc_QBU`YS!liN zOx#3$v72nk>npx zob|{l3JqJ|OQD#4Ddf#4?N*x7cs)z!7x2_*mk9O_&ZuuQnl)NxcNupJZHOJcQCCpa-mLZa_eB>zIjzo*?3)`WNd7PvxE!JQ2Gpq+|!E}VJBE;8k!>- zwsdz3d~>9{*Qj%N_KVB%4G8jmE2YkG#LjG3S2a*q4Qy1JaFj0|gq@7~o&3-l*+R|t z^_My;@;l+z9w|l{Y3j=K;TJngVq0~?9BFFL^tmQ>ro*;+SW(pEnreb)S76S<_)Tfr zdsyVu{#oUB&Y($K4Aiq&#`%2lu&ZbLMr^6qGx;iA+wklE@tg5G+Y^FkG!IFY1@c!F?)iiK`ZZl{XONBgpCkV+ecfEGQWD3IkL7{ zil_;^H(rcFUt4J@CAt2ZUUNXxP|$OU2!E_R(B!t~T5U@yVZ;8*InB_c*LJ(TSI{e% z>wM)_X`K@Eb@|rbn@LJ1B z_Um7=?-*|Re^5go>mfi#FV4p*B&Wf`(pMwWye~pX_$BvFiT=x5w=@gE(dX7JcReY? zhAZM?e}h7sJ+WW={Zb%(wSNa4<*Uv;)HO3K)Yo^xF%TT90pSxObo4ERkPZuLMvZ81 zp21y7YA`A3mp7?6t^Mn3&(OVVu^&Do+WXCLBr7$Tmh{Vn^y?M-*GkXO(SSjX2ydR@ zNM4F#Jf@kSTk`Gxy^pygO47vIljXXP3>y7bqpYKo$7>7HyuD_Ai}d@>%J0?o?Q4su z);h>6RFSujSm$DX+iJ+Wn#Xq3qq~fo6i8-{W7eSkrS^854`ne;m=y|L^kCTm?`USq{xkn{@#sz*3!dp5a{G1;;DI!jyScnrN z;&gEbahgS#+C*=hi3X(l=Usdlbo#q@LF7r0>_d7D@oGSt@6+uizYu7MLW~PYL-8$u z^}dTZd_ouv6qW@^9Z%R1+m;*>=q3`=jSg{hL#l_j_LAiUyp>=biR|qFtGAJ=0jz=` z_XNCsk@_`+|4a;4VVZ`pdV4R~THs6>))DG6N2D4Bon?_~vBa{V-mkqZBqz~CB;8NM zo&>2rcu1z5uu7G&HS~cw20VI4i=;Yb5;s!$~!j=Stu$~Yh)IbQgI%3nZWMAfF&ZaPm zVm@lZRPrHsc_7P|UER}|=q z=CR`>wucD;*C2ql1p$c0AploOtdx(OG`BK52xx;?o!BQTU*f6u}Fjl!c5|I%O zjuNCBfMpsSqBKY?`VJxWy$R`@A;k?y!3`;#U}*s<{sVjogBQe?2EtxK*i{I_g@9cc znH<8Fc9Blqhmr69Lb`eX4^kSyESfGa)D1}V0uqrzA{I!b0V#?h*Z@Xuf}`N8XR$Yv z3A(o;`h#57fg92|;k(MU7v^5aI3%Fs;B1`*RM`EDh)vzzzY_?#p z&=7B5=>5Mo{pnwOqR3`*PL4#ofE%wFq>4ZiZ@TWO=q7MR3tM1Ud||e5=e+P} zvc*h37nK-zH5|2rgr0eVw1dx%ufwNE;s)TFip=eiA|%B~cyF+6fo&g2YBmrFqX(uI z$BJl{HJqj387i1G;2Ab3MPOY7)*E2G0oJ`?-5b`=VEqi%(O~^@6Y__3f7mVw>yohE z3hS+~P6z9Bu>J{d7BX;x%fL0Fv4E_LD7Y0wUDn~wQ4E*A!R2;|fvglCVOT1_^`Z^e z3wVAFIRZV-Tc4uGBg|F0hcV|%GvTzhmv%Sn_H z*weHecV5M(o+RZDQH_{P5JwgW{N69^>7X)v&tVmazLuFGKjcF#m9$qvwB32#Q&ll% z#_V+9c(WsVQ7(ezo{P2ByMnJ)iahQ=FGAii=we08lRp(!P`%A#HpLSyVfk{3NBTC; z!W7Stgyp>&D+Y22)h>nWECIQpNeo5l+Y)CCDp>gSv-G$bMu$nvfrBNd3Qo6q)_sPb zBFz>i# zeS%2NeYLRkfaNhPufj4AmR}?+3(q?0c_g{>{TT>xdD~Tmhf2t-!j}jmgqC-<>%Rz$ z$va0kjFyyTagBDEvVFB;^BkNlv$&)A?s}bg_HauBi3% zpy1S(qYo!5BTd*RYpvSC8teXt#o(>V!&FmtkJ5&iM!|%bPp)y{3?@S*1-amjsJ-=; z;mC3DbLw%NlS#PuOEhX;KFa;Ox~Rej-;mk6RgGUFN;I4)-umsvij{_l@6_ZEhqJQU zla|7wwU~0@x&3F9Dk3rZ%?fAU1ExGQIIHLBLsRF)^oI9W@W$38#-9lJvpL;fH%s|? zqKoBK+nQS0NM!W7p~Yw*v{`?p#6rrj_{Dhnof3`76|LeY>?JnqdxbiN#g)V5_OBZH z6$k3B9(V?eu)KIR{R?q+a7LW@1=qFOoh}G&j5kh{%>9)+#gFnf`i`&DpLXy%VapUMfae)?Ru$lH^x)@x1It~l_yE~bn$vlo}=LxkuNt-eS3Mg zv{lOg+Y?=a`Ax;!+Kz;W&N!T-p5}|Ac#nz;XFc;D7V$2{eHJ_`dR+c+FR^Fl(~PPn zHTP5B=14TMt`}*ZO+?`fKKuIU6g_CGE^-t-{;Rxr6g`rw#|jiZt$}(nW3zvx%7mYe zyR>!hSQ`BxV(Bpft%a;nk*3h^~oV zKcYKc1HT^dKws&wN|cCq9vl4EzKi3FHfn2nJY5z=(2s9H8Fyyhp4b#rwa!1Kz!Vex zqUfeY|McSXv&p##VhRi~{x4Pz6ooqH7hgZL>*R0{`1xo`@Dt>mxoo>W#zRl1o4Ngk zOYRu=_w*&&VmEA9?)QcN{qVylh7?z(|DsHA#2x%-4~EdAH=AWl3-`mKE^XK^a2TBC zYD%advIRcBve#-cC`duh-?ns@lh7~n2vrdO_k7S%8A%7q;57sBB_rJ_LW2)&Vpkr_ zQ?5S>57U{S{7!)_rt}gsCG7e0Coc_%(NLD((7qk!WVe4q`^1Rq%2^4?16qWmfF1*N zkVup+&lGSp#kB}rIhoT~K1e^vcwr>O%JRzSigT;O__TPDUGOXf{>60mdTTQ|Hvos= zU*I(LpP#Nr^)QtSKYq;Gs@vymA+N4DxA_8?z1^FkRM7u(ABv4Y`)e=kgyP;cb6lzW z8Vqqv_mSR7UWJqyW#~aDgZOHj5Aw%+tgtI2U6{ks(rN2z*0U2eC7mJZqlkKfPa(XI zs^OSAyG>Z}mIf`W!2YG$3l%Yp5jV)0&|eW5nlxh^YtznDf|uf?Zfy{7?6JUbz8_Mw zuiLyqfrCl0T;y+KjL(@5d*H9<`a+@bc2FELn8x{&kwqbuZ6$Cp@!Td>cuU_?Tn3A_ z7it8-KE-v&Uhy=JTk9_l;cZ_gzJVjAQMg(~XKSp$nad-MI(Xeg&oxw`@NUOD$jDnw zZF1cvWb_G=V`)&2Vj18+ilM*~lPO#&YPB`SFI9)V9&??r;wuf(%!Aiwt!_;$NmEju z2~Gx2cA+7LF~T)?#f{ObsjUEINDe2lU+VavS>De!ZR0FRX}ezJZwDwJLrOlEi7r4n zUI;0Z>en0rrL79i?<>o}Y|}1vpY5{Ie;R#)*VT5TEX(fcMu`GMR=ND>;wx|+FM=0n zvVL7N>6y^FGDK2OyXGo_!2WlOVvLWoZvs;QbIH`je#;la_(2v+ZYs6a03*QSqjX@krM}2c{|$+k+&HU)u5J z<+JqTk(Cn;#J0nB2TACY&w-~48`W0&tgZt#*BAWit`FJz5bIg&@Aoh7=D zlA$S_Hx=VJP``M7R8cz>!qV*_A`&~~&Xj-ZFYRSLzD8#c)!BQT#fF=I4u4zhT);>km! zsJ6{0Vbsu((?dSujelT;S(nk|2M{=@B=DE|b0ry$e~W_>YnTYLq>qm;e_ z?Fa4s+O_0#XRj~1aKtopU6qyVMD*E0www1mZ8jgUfB<1nAZ1+-0WP4Vyrdkq%ex9F zKVMQlpLm5()Ls>9S5%A#)2tD7mIR2{3s-BF*$ElV{gR%BprW3^HFjh3+ML4$?;$oV*g(im# zH0PihBSzq)i89O|qkf|%-O&q=84j58hZHi9uMrGJv02pmx}}dZ6LyVG&-JNtji5T{ z8JK)bZqy_otD(CbH*01zN6qrk1Cva^FO7rM+EKUh1~7)RKt^kJq1#MTG@m{oIhx?R zQ4<2#_9blCEDsI9KEqxYZWOh?0uuU)*x^Ag4(_X5SwqDpJgeaDXEVy0NW_AW&%<~= zs=;l=jwZlG1Ml^IOixa&G@tOgpbXj$91AZmVwl?HN_F z8fStmzCO>#&VL1-m4XY3jc0Y3#p{i=wNsv2O$)E6)8alRVO_0oT(xL*N$u9Ai{?nY zCAKz+vU4{)|89hvc~Gt|Sp?A&Z?Q?*Zia-?m8(e+58eD3`{*f6qem((Y@4wtIh8!@ z1PZ)FM#c4TKNdg6i3>@|d?Xny&D0%~lJQJBw$zeBh@H{}<9FDKI8#?g3c-_4Gz64= z%JB;8u0@r;Pt$F!tDTNj_{wK%|8XQuuIu{5u&uil@rG}8;Pnm?#K+zAT^&}vpxUeU z-e0_BcbKrfxK3FgA6->(NWCn=uj*(jBhHq7RU%RJ=J4-rQ~5)gK7%jZinSxYLlL+? z_{gWNrBu@LEO3NUWkt4*erKG#Av?&vxE5Si$s3xd+-i4{C{(CR4;KiAL${ly2xN{ja-EDiu+8<)O1;?gzz`%Lkj`MZNgWr_Rz#PH5AO z1gDDI<6@7h(^?x_2RGn9Uoqi7UthVN^s~6AQJLm#wJj4=4Z9gT2am4^an?yvA5brT z6zE0%<4WK*?nY5ZM|F_$dUF78dYRxs)?E@jg;D==(jM^*+&hBt2C0W%%d-ya2f{tF z`zq77b_*Z!T1B74bLMzA6mJml=FPid(*E_HzD?sKSgy&#GC(^Xg&w z&c4WIjq~%7@QlfNIT75Q-cf!^X^sWH#rB~D#=hlBNyjZ5r-C|Eb(>Ejdf(G#ssc8* zZ)npA={2a*#5j ztrist4yC_zWU8~|a!_eMXf_U0?9v%Id6mAL+2;|aJ^PPbui~zQ${OWaW?0oCo3*#9 zf%8xSu-w-p*V|kEBK4WPK*Yj4^kALori1*V{icY~u-;;EqiO%+#n4WY{bU2(4J#>; zpX3^+5}O)nB5~hTUbHw8QItVKEoq7XEnmnQ~O?S;EPQir7x>x zJ!3W^&$*onoXRoMy-tGviL+&}HMMzGT;QHY$)k%ckz!=KN8Y*epo!yFdn+l*;MG7B z=F}Q2KXz6;*=-8xD?G)(V2g_~D3yZhVOCUj9Eh@QU`9@k(dPS(jS26~#XTKO3c?FD z*T+U;V;Tt#5*YaoW4D{s+2$Si!gZ6YKlqgHjc=SLK4-7=NZpJU#ytA|i8W{}-q)g| zu;Y-u=IjT#OcJiX`pDiL>dplz1>Wz^byY?x=%_p2Nhyef6SWa%dg{(mDFuZShJ^|7 z5x)Br4zfX%!(MN~-&2LRuTAr==TryBa~73)sCvod&R`9rOpa`v?Zh&%OwSB>E*&3{ z@`hD${rK|Ulg}@1^T8@J%G0{Ff~BjnEB5KBRJU^KqdkLwfnn7O^=VyF!4eKIWTbNZ zefi#EKWC#O?_psM|6}?+O?h03kbw7nZr_VeH3nz}pYw9hes2Hl@x5hAed-PqTkl5u z=TLB>GR4Kr)|=A)ISHJoO-ZZ!c#M+BnQsy=5_I8m!N|K4`kC*U^u z#io{jU|RdMk^etmkei!~Ww$(fzB$9lmw-EC@|*_Tx>z;s+lc0mJ-5Vfb1iPSqOz(w zW$mArEuVIHPArqSfr5FK``3=E3X>Y#fNb2xJPR`R8b@wkXi6s>^k3P`sU)2-d_9Qo z^NBU|nlf*CTp}_DZdiV_#3J`O2XX#BlBFUW>9d6s-69^TMBqDPL)|$ zR3Evs=@ofn>xS21_(G#_FnUrY*{4v^^%9j|)i;t7SsvOHXKt;_w^u&6$7flZ-sD|x z@IZi*|C@ad-b5^>9@j6wA3vxa7~K08*H3X?e`VPhYb@_$EZ#YKzuj;?*{r+i@!px@ zULCpSccc7eveN8U<)MaeF$9uQhr~}F;E_)Eu&!`Cb1p7{hHhxM2@S>&_d^T8%@{ro z&dBtNy-OVwy2%C&cOlN9Ji9f{E+LqGe+ApuiD~GUQW|Mbf~$x}OP6Txy3bEG^Ex+M z#rh&ylYY-*@#b$I@Vs{}W_+70j=$&iy_>1jvKkeB_mlry5`TX00rl+P);InJoEn}3 z=7S1ash!#8Y-9@4u}i-4i6VOm*zZQ`MI6|V9v(mAqMpS3quS+cOBi?4?2G;k$LcWCzCbp*Wuu4f{Lu>jPxG z3LA^ZL%n<6WU5W1qASI?Im#_3B-0&94?@k4zG9#q3jDM57cVWSu?))LqadLS4KqLL z!tgidem;aJI%%l$iS9^X{Jeqr?nWk+@E1eG)ln7SmU>kYv;!M-TOpIoK7oA z(Q8>a(ds~{Ui7EM&e8o|&8E-I_xN~1{Wsl&oL4nA`}))Omyg1wMX373j}{_YMH3q5 zjJaEAwVJ9|_pTjRdg^T~w8#A`kBz}uW6%9#kP`Pyz=iYf#b$PPOMDpfu@d85(ucb8 zUA{uh1trtQa_2uDKMw36Q+W}d2Oz3!x!KjRF`?CDq^f0wNaZ@I>UZGMuJb08S!)JV zCWAm_2x$ofl?kN9A5=z>me-&%{rK@(H43R(*%QXQUfb{1e?IP-d3o370rNy~v1zrU z+`$6NL_=)M*^%7Aa<-{&V~mIpv!GwGX|bXl!5@~1`q&tMU|PxkW4I<&pR^lL%IX^+ zn^*ehk9z9-{>8KMfw{*{D~(#$2pY#OWZd(0SmU>((xiB&-vpSR*p}?F zJS#Oxcy0e?n1!U7Z)AcL=N9GSGR{>$d^hJn)Mjac1_@H3-=}8d>by!F2?w1?ZZs)n z=N6^B#WTh_+{?0IW)(Cm*S7hy*|EHH^zZ^baYc^rk%ifAGSHfpqA%I+43XhFZ!#E+ zYNdHCbae`>Ig!7Oav57g;liU?MOL7)yTBtH%K@_k@F33jvT4~HO<_s&a$Du-EF-?w~f zxNCwGP93&qM-JE6bqqVkTg|6hh!Q+og;p0lBs~Ju)%3~oP7DpOnJn8eY&lUP3I+LH&^?BFXra1Jr zpMTgtT~FB^KIkugD+ct+m6I)RzZ#dhnj!F80=2XlN8@yx#$ToKi(qAvyi<-@Kl_sfB3B!RUsfKx&2Du5g>4qM17tQ2ylYY=Q#j@ zE&+Di93Xg1P5g!qArPV`ltBnQWN-Zg?Z-64Z?Zu9by0f4M1aG1gPy4lct{_i5-9_I z>}WA`HNwzXNqWLMV15tG;LGs>dXG?5ia}WZJFhH(o8qmrcnb@+^sjI3{$|-)e^~jV zF9nrLRP);kmXi4t*0}98oT49VNz}tPDEDxkGD9%-1D>h4 zP_nJwGfxTqNLiKtDPH^DNBdYQz4m`9DlT+nE~K%Kq(*sJSMM$Ahkc~1%(pp{Ro9*F zA_J;JEuo(%%R$30HQnhNDZMp|&-1GctgG6h`lK5CRw_SELO#~isUi)JNHwY_GK=<| zRG+)(APx6G!zgGNR+$Lx+AB<0%QY?Wj^G~{AtYi4yz zx!&*lWSY_^>W2>dpU2aTYH*FRNT-y{_V$VLmG^ynkd(M@gu+IKCspA{_DpI@mf_~h zRGNe+r342}8#U2@!LR)l_&PI%o!2u98OLeI-w<7=8Na@9t*{9D+B)m&NHyWc?_X1& zz3gn!RAN}xq*z~{7b5HM#1Zej$MA63aEWBLlw(X4`vDn-m-aR_u8BxWx`|OWhXris zM%sm{k0RC9-L;~NxT=2t{;d!c?Q>fNhp$NL^>zT!(C)PDh1&uxubU6o2%b0DKHUS% zKNBNLYgBKSltpWt#8RJ};SHd8(Cq&f#{6?UqI5v@mRwo%kCT|b?Ae#C2-91qZepuO z4UePf|E(#+zr}aaJ~WfT@M@?GyBsa#M+S@z);Fs`4})HJ<&5Se^zc*ps*XK-Kx9#A}J@b>Rx4P!G!OVciP52 z(e3dpw(k?IwXDyCbKZk^R^`t=!MskobXV^s>jx%)>Q!CkcPd!3d;g%nY=pr>?hJI) zzYkw>%Umv^Tbs$wE3aVTYua#!$cuk*odjui>|Q3%mwvvnvcI<}OUc>S*Pdcdms^`t z<8Rx>Q%&X;6cN8zH6L00`Q6fhNx7ctsdjlQm{cZiJbaob=u;LS@OQP!YWV4Md zU=t;5{klgTCfkm}pB0+2ZyeEiUgJiy%!{XQmT8_N&jMt?(}AE(PUNL*uc^y7w;AD^ z+p(@Eis75g$ot!e72simF6jV#&QOlLBTNJ}2D`?5Z={+uZl*Z`~h95fA@%N9b1QF&Xh&@(n+xTy0q~{W7%7 zc(dCm9uov_=AThue`9eKBk61dhDx+d0e)%JokVKFcJRwSZ`*-^u?HBcfx#LWf`DOy zoA@n1pd!eM_WNRn`RMtB2z1jBV0g|;{I(hx`iswEF|*ZeKJtcFm9N%v=Hv}%F4P}k z;9?|*&y?~jX!G44;L`9Ow>$`ze1##RvAbYmF9Sl>X|}KB`)4t7;3bns_VepnWksc8iae9w>Y2u>rAU|z zCZtLmIWxtMe?{(3xg`N|h3bWr-d4vxmCi-Mrd;2)J7ZnUsA>!i=dy zq+ji10d7McoVXld_&o#+Wxx;v4CTO(4-5wDnVOinD(U~M$=e_BMWC7`=*8V$XKI>| zy3rlEQ?D0iw9e!^E_I_nawktOjtHCpOIPGhwO*XsxXO8H7*{CufVqt5xD z7Z5cq8z~0TU&U6M&x+A%o*}Kixnb5#Ve6ukI-=vSIhtzfa3)jeupMFZh@l!IL?BjwH)5JcV%_NlBEV= z7$*3jwHUOzgJT*vCd%Qp)3DtPuZ*JzJ=5Z$uwmgO@hZ3E7*jE3IxrhDEd11_yxx`h zH9j32J2Ss(DurZ>he`RDHUh$HfDjE3T?0gq!1007Rkmble3>fKhgaBvnHent(ABI69jkmY9i?}YlO+Jlw> z%wA3>TcfS!sHHC9ys+2WtEzaPha4V;h*U2QZ5YrT&A(qX*3nKb-HJXZ^p&(G*;_ci zp352A!t5POH^yBZ^bHzQ zpRn}lVV~KeWL3-y*YO^o**d=i--FY!s})|8TRP-}o4*Sk0ynJ>T*j&;DozF0bZ-AV zO988O0|h{jTm|0tIuKQ0B7qJJkw7#skR%ewivkIB4FtNnfpX(#BXxz<-~$ojZ;!Xq zgsSGE4=tjGd$VQ6lbG1o-ZRIMj?wbR82N%PN$hF%vp3c1T#!x8f3&#STN$aV(z8}z zJ$ProfKz#$CX;DxKvkWyuu*=3MoWP(bRoNMz&n5S@BO0MlUq);S?Y10>`$i||Ama@ zZx)18lrpgOYG|xw+cysyKcDs-ovV|dE_DC*)3NNV&y7eV-p5Kt*aF3LQz(q=;q#Tv zrX*%-J9gnO@0AK@tojPJ1GoO(Pi-oTs+Dfm$KQ&Pk9er{(RrGdvw{Ct;f&hZr+&)D zHeJT?g0xd%UVQ0C4*S9T%$}OH*hQAa4XVY`u_G?4t(Gw-iXvnR-wm6T3cd3zW8R)U zG-60FZBmMVd~@RvoBQ#&Pa4yVt~TrASi}-CzIEN4xYZ|(Blgk8VaWVKX?u)()huH# zJ?E)+i#%~PQpG;?Hf|uQw~Wb#WX1?tA|wktdssTdY{2vQ6SP<(mPi1{i3#+`Ww(y4 ztTY0z{k3%ECg&}bAB255IkKsbpMCS-Aigkff&FW|`s~3xUOP3<;{_`Z7M9H}{eJEf zl+VoCA8vk2&MY6R*-LYZ5}4K98!yb9-h032+F;5wla48ZzIDWsXkTaYV1MmAG)Sob zc(7php9atLc7L$q8F91moVhc`l8fYzK4*E%<+|(1*QnFi6rCSBcNgvIy?;eHz5RGj z*;}&3K}5rCY^!*kXJfbR%zRvnZ)tV2dxScX7duJTo0}~yH!`^LXYye~nuxz*;QSjg{_4elW82+kmF&KEUho%sB^J+b$ls@yeqLQGQvP|=9Q)DuD^e1M#mPpP zQy(}oH@7#q!z4Nq52i9TbEr-WGxG!2Pi)IFr1gE5NTk@zN0!L=$0gXk^`DPi)v7pr zN;yLLCu62r-rMK-EE}b}=jzH~Y~=@x7Y53#ZcPhz#urb52+muK=e%Sh94D`5ib@rA zN@9~7e=+X*^tG9s6jzrN?*=E;)<0tpug{kFtViuq*POlO!+yDw590HXy)+`4M}b8-pY@kozP`9HZG?s zs*?Y0SCICRB%-w5840joH7hdq*s-5Kc^$< z|LVQeXykSw>}|)r`I+xW@U_hfWgMQo!Op{L^`}vRN(s2r=DUR7?He z%e|9Bl$)uq;{2^sXim9`!{n6YSC2#T3pwDDC~xwi9Fj1lx7eX>0#SnE0Kfl1CI;xe z0R0v-V$}aZCI-mL&}ZNt)1wPR^@LQYo-hE#3M`;lffJNC@Q@(C_kr*)Dxz_q2{m=} z=@FfU`%sbL1N3AGV1IV|_AfO=4dE}8g3yE_HTqBh!2xpe1Dyq+f}?|w8e$`C?n#JL z!WXFWFavcKwt&vUy8ypKNQw!=OF~W}#Q!KB@qY=Vdq#;-A3{JHOkx1~lSBU}(4RB| z*Cm?pFBE1t0>TUc2E{WP>5$ZCp^gJBkmdOl;71F=PazB{WE>?R{{KLjJE%T)oilD? zqg*NkIlusJ&=V6T1Qjj*f#I8`NB;*UY0jY}%>~rQxBx;C63qhF5ZAxNb;@qoC}s#n zGZcsDM&gP=X`6gFplU#@LQ+Bu=DZA}*Fl<_NWj4eBq?V`=ZsWhR8KgdsR&m(Il{gS zW1qn0Mj$!>Byj$>JWR6R|10t^P|D)`QXc10_TeFveK>_G4(pc&QK$z2zGwy1hcKam z3hHP$azMjvXb8SEKxqj_0cZftJLt_xO6GC+f4oH~^$zma~F|2R*qq~Q7leb)@zl(Dza&t>7 z{Yny&m+F5sq}Tq39**{ZHoSxCH~)i7%p-K55|hD&{XfaX+(A_Y3nMMSPYW(QdSo3q zav}3Q9?o|~xYnG&GS-!7E`UBzC&v+rQwczgo8-sHGF}9$FEGHb94fa=Ku;>j#*VNF z0KqVzA)~Y`@s1dk9jf1u!6FO!A?5~!YiQs)7J+Np6ROJWUBWJvWT2W*IxPhFLcrxdg$4l_5P$~(6fh14 z6caL}fE$z}1YB-Y;LBJ*6H6WLCKONyhXbme8LB}iPMC%Xbn1Ytg|LSu4M~!@gfbOaXspmcINosnu}JTY4%#vbIaiKMGm}ANC*pTX5>*W&HVR z#hXFZ$x)`St|S$UC%cm;V>HOAXPUz|B|7?N&f*KopDar{ysGwwGPNUHTx2%;!7g^8 zGz09eMQ+W78~Q(ODr(22wWbH@5{pQcmZKll(F*G;{V?T;KXI_TK=+#%XAjSukTv96 zq3Xb;O;Ffq(ToaTO2X^SCy4)9^8RFC-^k8-wM90&xxz2HERd?OZ??eQIJPsA&%~|@ z^;0b66{fyLoSW<8wi)Tn{@-m2(znH}s-6zUNm^B@4?ffM9TiT_xG^g}Tv(aS5&mA8 zBW@9!{`$Eek%C^$`LhgV*26?m!<`QndM{V#xySgle!ToYUtO}=O(wA_rwP3pfm+1R z_uUSc5&RsdW3;`7K*7FCw{)HNT=v)x4$2h*vTS{g{gueTSe*S8MOgL+#%dp0c^u-c zXmVSX7u|j8rf4yF!TmhRWqDV3x>} z+oCbW*^r^D$fI1nLGbEV5zaL70@x~oDVi~w)f)Erw6pO|woQV$G2H;y^3~hLYn1yF z0ZS2SFQ;efZ`LPbQ za=sQ2yZxx!6IGfkM)SOZaDM=9YjYSIuA8n;9tBs?~mFYA#zF;~#GO=T0DhttVD zO`yaZxg;PYtmi1)IXSly`a8iWI1i(fdze6ppK1Wx)xGYwyJAJ_Fj^;f4}p@>T3&S+ zx3HFtc~6=a_!3vXjJl_@i0_}nD80Yyt``YbiuZnX)%_g4d$w}^$mZGM5gvGC>`|ur zt^2@9kg0z{QSkERIGkOQ&Q?L@8wKDOV4NaN`VVT^NtOx}1wZ*~uX6j5f46dF{Mg36 zKTJ*Zx_FnHO5FJV4tEMZ{Q*we8XmEiN7@3`_nFEKFJ^y1uC*h1)`oQ=_$|x9GnFjC z{3X`nWZ#oTr^fZOQ!MV43BGHl=kM|?W62&*hs&@0!&^JHI7sB>P(BQ+T^3A9G1@2b zArx8L*b6nm&L-|>Q+_?F;(Qx>iInNX?;UWgQd-S)lcd@A-%eJ%!MAFk6p=8iuKh~68mX#o8zwMmObp!hY@q?JR z0Xkpo4+`uk|FbxQ^LHvz4VL~a;Uwm1Xmy39Y9tq$; zgpAN#$Y}>tA%LDA2BYh`WZl6<0Rfbd9zVQ=_|w9%kAh?02@=wiZefIARS3R;fRB<9 z)JqUXg1C|1Ih%%yxDjS&a2*Ne0KwG|B?M6-8Fc$`(SN~J0bqDhSnndiL}7Aiup9S< zk7dWO2P=qu7P@34Ah{q*)R2572-Lah?zdq*(zDNV6hoMnf}@W(Bwi zcLWEdSpg16vm*HeX;xt9yEMQ^K$;aX0BKfW0QcSi0i;(r}6JhX^3e3J?v@0Pek!{`13rfO~Jye{k;&`T_2}5reM< z@fWEDIuyE8bpq0SA1BU`8)QBA3-#`JFNiFV{huyidKQNVw8EJ@ z2WK)CGLs$YktzHaPV+1*>H>M`*V4!;utuh^gdegj(2?qEMWl5Vi@J-EE+Z9b=7B4g z5P`?T4e2I?#1BSyo6+;Yb%2E!IgpSNaR@{n?hu?3G9TYY6EY&}1sloXEnL^C(2pB| zSb|+s?gsW}Bu%4xNQ*!sf~S&1lE{VJCfL*ka?&l%uoG0!2d32v7dedQ$?6ZIrL$^+@q)<&t{(ZqN-f=o1Lph@lTN;sb8GqwBy<4|gP8xFZ$8 z@zH?Y{scLBLDG`aEtL@b0D{4e1i-J5RHoqeYJbN$JC*DI{$m1s0R6|O1ej)A^DByQ z0@lL`xCy6hO)xSu=k%fB^wI#Qth*mHfCn^Sz6C=A4Me!Zg*2xE4V{;UO9Wg(C`v&ZhtwUfe{+gE)AF4xF9r;LxaJk z0q&oFd7*(H8fGsImoY@3;TklELIW$@@Qy-Y(iSjj12_u*k9=U<{Qu|!!v=eym5W$? z?d>4AYrD6`rb3r`V$=LadO!YB{osw+liFYHKIE=?;3t+?b7pavA1ZyI!rk%w7?Dr& zxJT~4svn?hp1O6cy3nrq^=tM_bv`KJR!=+C#1vfD2(hs#Y4v$$NIhR-a91<CYj zq#L9gDQOT1=}rMDi9>huF3bCV|HJpob?-Iz+%dB=bLQ-xvx{wSFK?jf+8qZKHG=*( z1UhO6T@e9RlR?lQ9igVh3>_-n0d zsvdw>NA1NH2?$_CZg<_Q`5t$=PQ|kIR3u%ncT8$n>;<%Gq4x%gAKv37I~@E(>Nfcy zzZPt!`O_7d>f8v4O7o4E-b5JWo&2lAo(p6uxT`gU5KQf>yzMO%qa!pCevI?}D8moq zA>UfAco3f(bnKR~yTGJo~f6WH0$`)pxKeqgX z&HvqI#7wZZ=GE;8e%sK&Q2l)mnQc(^AtlF~*gNUH8Gae*e|ZbZpA2UQa!q~2>#!sD zg#ARV>xGAG7p#dF-H(v{$~fz6w#Vr#%IuHE=`G5R{*E)W5u2Bx>y>)#F(LUa5sy%& zHuZ8J9SWQ!Ce6yY*IVL7dom6?lys1;RmWPE;x~qx{!og&v5rp8EaQE8IG8(&6yDM$6 z**_fia=nD=@f_|$Ix3C^YNjL0XS1q*Yvj z_w8?6^l$PG@-2_h7VqjA`Z6Gov0f43Fjn?^TBNT_d`hSSsdFz2v+wf!7h}Cz!eFfY z_TCe{E`cqfa;45iE6DCYAxzxY1#nD}WzZ6D3ZZM0uLOBJ&!ShBj8tk z8o6FcmV7&xLac9UuT|5~1bUO^y&L!KTWsq!MhU@5t!i&Q|3mj#h@Ft&pjLG&w4U?x zaW%!6Yi}sN*Ev*Lb3rfbE!*jpDnqI z?*>xQm)^^^J4Scyhab)V}?*Cp?!*6?&_y`Gt8Z)G_(h~+MCGW z1GuoqP($8{yiU^jPu%C6a7$8X52)R4-$ngIYew95>|Zsi5Zq?0Z|)?bEdAIY@l$bm zN}Lw#duR}^nOP-}X1}(+(4;Tewt-K3>I+biUELaLA1-nJe(365><(9ip760pn|y6< z&vh%C2D?Z_O%`UuB|YM|S3ef=)GjS01XYDz*1ROOg7fq{b5^PG_m!QYpX?gFrtNQ2 zLw4!keZ3Gj!Y-;)lb!J>a#oeqJC@xpOKn+C8&zSM`I|PX!Q$G(rk88H7h~R{*gFk7 z#;(vijXCBLA5n^vZP^h~%9*`u{7!|KZwls}iUHr0$U7B5z9|aYqDPM+88unhW7(9_ zRD|_3MhzC!pKN-0#&|ZrH~9s7*lDd7KFavCRp^*z*3jvpPA~{Js;UiD3Pyd~qic<7 z@(?G3>YT+9_227Y+<#uyxR8Ert5p07qlz5!QX{+i&|2TP!qDd5czw4>$$0-h0Tm=P ztWtHJD`)`~8h{F#K!p*Y0!PYPAz-bZpmaVwFi$n#?GN^sHMzx5e)8Sy{hAENcXz6?d}jnS;}FL@=cR6$LW z`(FulL`2}c<)yuo#Nh{LZ??Jx^K7Y(r@5z#GwU^hqp?4AW22*^pWP^CZ^WTy)ie?D zpfwG8dAeV9-Qvy0i$TrKXqsaIMg2U9KoP<$%}1zN&e|A4n3|3d*U>lr7q%5aAy5@Z zhFRorhI&D+Ez>0kAs6BI^GarnXGMgL>F?FGaZFHI zLQVmP-_;dGoqSvB^zF1uM{ey6y7z0<-t986dr`7C?8f=pl9fqV8t>^&gd~yDSwA?F zX-`wXvHx3#g)$uxYV1eOl=^|PvCuGIUvnZ_2!->}eb;#N3@d7SG!|iMs24{S=kUCf zy0O@h`8k3O!3lDZm|o*%whpF@<#_r9p6lYK_B!ZT8obj0nK<*Q1sR z4M+!xHi(NL@_^U^q8Cs}Cp6#|BnTjef+!ARABdDdC5h00B9MFn@gIoTASQ#T4ph@1+g}Wx#8D`)F3?Q80cK`w zFcdZz#0IqB1}z*xd=8k00=o_K9FP(WI|}w&Ci-)z)K|~=LrAtG4u7PJoaIKu1A#IU zcxMHhLtg4KMNLyl44z^bYLQ5w7&6MAtg4El%w6|cY$xgfs5e)eHl23og(_!g{+0%AVsPZkW9 ztN9!VxLNa@vvlusHmQuyA-X8QTDr6#c`;-JP5wH8m8;%>t&x5q7$C6%$tSQm%rc;7 zYcRVX>L7u<5Pgu~zYrymWV{e9km$S+HIOWUB$WZo;{Z(R4=G5pUI+z9mO(Q7(#1qz z9*1C88diZFa0T{^!%L5%hd+1taW1Gq2Q|kvAc+Mv%nD#=iI@Ih0t1+U0r*}z2lIu{ zfEpMuTJ}p9SiX>#JhVW94faQkBp;9Xn6*@X(ItiBuMCAEGa&@u(g z#-or2)=mOAThLNNws?Pmw=A*M{49bVeI90X|5q^hzXjEc>|JTkV~zt{$qYHb@$CwZ zZ+viMbAr>(9$XPtfH|baiqZ!AJeoB@^uT$Z7so{46l4IA&=6-Z*~pL|bmarOLI6=5 zL`o15U)C~o&^s~c{R24b1i*P}1I|+$_d#;7U#2ZA=pUCFoGv7w2?A)s{1G(C15Hps6T=^1 zNU|4`mx&tx67prin0O&%ptD+#M7>O5F3@uf4!ESjfkYk)Tv6*mpC&KOlmcUZ1!pCf z7)VrJh#W|!UdT&p*+7B|_GXtB7%lT6IL=g|;OLZg?KHwf1<_gCRut3_)OXRn}Ocx~nL5`g^cqhIC$=q3VT4 zQXCWRlT2QE0nUT*FE(^^-}LF$U+l6A-TvJJ3V{jjiE)MK<##^F3zD^Ec-eevb29v% z6OzIS`$t#qK2D>L4+Z;CuNQ1IqUY^f=cyf%I33_lhUk0aGY#x$vO~yxLkc}U#9SvO zuXA&)YiLDmuZJ7h(&)oVd@d^Vkn{51O@DKwOhYsq7$B*2ghspaGdwRuRe`)@GmVr8 z@8LnIxc&3BB8IU#{6_|jp+VyJu*@*}6u5VF-Jdn0`9_%Q|I__$?J@8jl|i=GDO$#m zqvHO3OWEyzQYhx5ZFdo)oOe>8)^eTsHoeuXI(cl(kg~yvj2u9g4^Av)u{GlZ96u9~ z0M|)pYtDGqrvma>pUl>*^Q=z-WclC>2DQ76TJs{z)+ddmax%rk%Q7cd_`zi*wW@5P zW?rBI4z;_6S~CL7)?pRxT-@X5LaNQh^c+EBcLRk25Pf}u5)Ejuy8GzPRBsK392o|5=FYHP@no2ZR^{`?>uu*@Q?57 z!XB){i3icvnh|}a(CP5@no&ig&?#SEPmiX5z@}$rSXeD3?C&!;baaz6goJG=BBH)Q zRPr$xA|kJ9*e%b9u&_tq&unMx=;#kL$cfwUiHL4ZaH+@Y`1sDZ*%h-x0Ex)0m@NiK zDt^W6Z4Zx~*uY%ANKX&ku?SmCz5`m%Hh8nhc>#uWoQf7rUisr`8IPmV9W(DzKwsXdu?STDZ8C5i-0ew zT}FBvaU8{((YRbCM?8eHiu;`sc(YfTXys*ws1R+QGTy8**DO)>UsifYE}C!4FMNu7 z1}kQ5++iBN-HeziWfyt=Y{C2T(RBtBt?x~OM~+j@{m->dU-45r=4COwKB7)ETek@Q zcsk)rWO2pBXcw$L2q5JEIV7Q&h`vJ|r4gS?O+2ZD%S0)xB#{4&SzjeE-=+wV+JX6> zWhIQ-e!__@h)CoKmUrjd6n+~g-ZWGa$on>)a|+034sE0)@D1STMoNtnN;~MWHPks% zN;?Y4HPi;lbHPO?ncG|19`Zp5%TmOk$ zYP!yxm)=OT52VKPNZceuCv2#ki%bw0)N)&G?n2v>Zv2?|FEU6=EW!Zwy|k-@ACV3L z|5<{9n;ccV+dQu$T*-YyrKkjVCB|Tuoby9M4fdB#A8Nld!yW1QVoNFO|6(6hJLi5h z;cdn5t)^DREJ`hX`ctK?t%;h%U(}+9`fW|JtJv$aw&RVUNa1}WkF-0F(qTmmD_s_K zXL$@OFCY|Z86B&$^=M`(7`G0wAQ&m9VbADoGRdci>dUS6`1Y5FiThKka2q)qmsY&sjls8M zAJ_z4o=PxL?~MKYeZKH~Tr%L-j+WGn^-@c7K`bjC8bRJ!fk|^fq!HEVa95yQCXTU+ zsh#=#elbVhTAq5@01d!DtKhNV2kX&jckX-Z&VO%qAM5m-JsjHgF0IkxM-NK=ebfh@ z?vXj0sn}u@#zBR}*l#&9vHSg#&OXIesTCK7LG{)3Muhe$Q7zTz(FFHXKMPR;dx||m z+6+nFe3`Nmk|(UAS5A5{VnY8`gAzW%{Vm3OpUGB)?VDbO${77}D`7+J@1++e0t-z- zg4v0sS_jVBjpcR$*vc{{opF}5-gkj2aoRHi5u`!WRhO2??+fG`&{YRWTyLy{9aE=C zCHWum-XbgKbc+89WdB?Jww46-S<^K~DoOUNnM?&WYtI_FXU)zcsU#by$$Zw-gEkD$ znl~$?l60UZ9n^p}wt(iX{NFbPgnrTC@Rnl+WX8fg$8)btbS!&gu&0`5VZ>quD``mm z7L0c11+P5sg((uwg)U5IqmXefJLe?wT{k~NABXmKXNw}%|JEQ?kmp+OSrCIfQWWwi z>HBhoKfO^9COOReJQCxPM&Ng(9Mhw(2yJ*E>j|H1SD{DE^m8)$f_V^9<6?4wSL)&EFDk5Fp-hW41=m*|cKicLb z2bD5gKQ(HiNIH@brSD8MNKPtWebo`)amIE>ic{`)v_nict%WW%&hQcA`=;e69Q1^( zx9Ij!RQbe1Ud&IVHsyDwGR9OLS}1#>e>QsyG9Le}*J6#zY#U-V^~!8x5Uq%l zl*->p#LMFIMkdA?%oUZ^E`@#~cfPSk5pdfq4N6JMeP>Q(pqSvWhsK(jZVD zL-Df(b@QNmVIu^&3YaLdC&yL{vPsELQhJF^JV#X{~}iY${IlqHoT>W?M!OpJa<&MHxUi8)9+S) zc|&}BDQODRAZ!cYFv!yFS~$HP0DKsj^KG}9 z-1sUp|26f5iZYJ)N&&+hAwo3-XNVzg^{iT3Ga}Fq+iXq_3loTi*=mjfq#q!&0cj7&06-c5G9Hi$fcyeT zK|rPfk_nI@fFuTF5+Kn5866gOQu(JHyWCKmU2s+9Qi(9KiDOLncH)qJ_0O49>cZb6 zzwU86M86y4P&dTu37BHWQ?bvrq)d3SUSqezkTC;-$L&}X$=}UI-PGQ7 zn{G3x{erqge#)PG>EYgN3c&ngK;HDd4IgJBk&Hv!A^Z6wK|#j9z6$Q7G-B*4aXF-n zsWT_*xVppgN`flx4Z0Ii!EL{BQ;-HamRNmUZ((zdeC|{W>Sml1!2aB$bs^nY(bb>J+}J+6#ybI;{W1L8iDFmY zf$4%sc7G3w`4>&sM#%qQ7FEi)_5>IzPVh@hk*qtV zeCA?zUW1v%O&}m&y(7501(wgv&;1QdLQ{3Gc z0vP@qX!ZNK=1muf;~)Z!6?s~)dA9vL{P(xmp`Z?!N+lSQ3dCX%%|ZMCHp!WnFUll= ziqeB8t?@x#Bd~0p=8344N>KBWmEp_&xuAkd>}@5d)Md!79>EE;o5m#K{QIyrqteDR zO%1J&EwUQ_OzS#-)4B`r!NEBJ6I_J~b<-~$@ zTOTm&5x24HDv@sN{#7DD+Z&Zq5rh-}I-~ZA?=OcB3bWjfkwU^HckU zFx72n16q{)IfJ#?t1JsDh}PSz9p2e}0KI1)g5}SB0tXV?RV#K*xsWE)s59I*pp^{Y@aKzJJnsCAs+ReK0~5u$xx}! z3F#?S65}jNv8Ps847>bOsPkdu`u7zy%_VG3DugjIh-*U8SRzt`?loPDF}a`rT62@Z zPR-g6UeSVoL{p8lDwBzvv*EC$6c)D(+v4>lO28vwYdeF#g;L>4{vpmFx}}P@$j+nF z5880%jKlWbY>ZQ>5RYPaImUcqA}!dpypg$1drHZreLfHyPwMjc98!N=o=OKj(QO}C z1@{rTGqM@u4dK447sZc4gW)>@eWX*ueRnU4fhLEpwIq_&Zed{!nDyTKFwiCkwDJ4W zjDcIO6iZH!8t5DpfNM45Kd}A5;;QrHytPj1xKj?@xAB`U^!Zcm>^8C^{P@$Hb`Dd= zJE12*YoCt4>f5(Iy3?zj$G4D;qQ}Qxh`EyA)A~hSX{Vn!;@#5vxZSVuZ~A1}%IcTI zlq{cTApzC$wigV)<4mmdN5Tbun|*a34k%2HGt+Fb-*T;$ z5TTV3iO!ge;iel=OIeujj5RKMDWPLjB5l*nQU6qR`3kQ*Ya@x%hJWl4%Sxmlpd{;CDm3gQpD&kRhVh|-m9 zS?N~2ecClM58{W_yV$tER}$&??iYew%@b1nR&Wx>Eb}h3Xw+SLnYse;Kd}g+yKh8# zk+;YWHxKeR`03X^5&Geg22kAhW{7HzH?Tk%j%B>0<$m^89FsVQ8F|NhL%McxK+V z?ITq4;(IkO^RJ_MoMy&2D9vrWJ>*AMn z-pg~;L`L`zo&}Kw){5Ma1fSZ?DmR(n5Tp1HhYz%zL_ecz#Bxc#e!;PVJKw&q9#Wo( z0SxE9@->sILq@{#KXWc)g&-ooG&0!l`1e~eI~1;0bOgdfmIoR<#>s!?s+~UkRZd@@ z5rQ3se}WUdH$=W>A-|V3cQ5Gv(l2n>h-Pb;tO9$1?s|D@54-l$U;|4aWkUcC)u(df z?Ny)X)Qw&K`0*Tf)fHD;v=&r-0EEy5|3(9X8na`jU&hJvUy5Va%BD>Pg?<4iZ@Htl zhQ(|rw)yL`#C$%vx&c4$$1gc{d_IwPOc*!V(7Of9rcJLUsX|Cw<%D=>P!?=nijct~ zQLrcrW>U&%;1DBD{q`KqB~@`_GbFz#xBFU!2O?`DE8Q~dX-O+Qno**$h}_4*%SE49EhmA9P~>3*f8P_y>6TQRf`5jB0LT7ohDHY8q(i+C)X5q zL~2B|Ug58eWIII_gyuuTEdXJcVMt>)d7|)kexxiUYCIXIA^7)pN*&-8AY`d$LJ5`TklRV%J}F7onMbUVk3Q4x}J&55`b`9H2G4z9FWFDSF!R=GQqaWr3WY2s0 z;U+-V3D6JABcK3}Ut%712l&dRB1}=SCzX~IO3(CCzIc9TymgF>c?f4?TbE#X!7Y(Z zT^>o79!X?=6<_2h9k<0|8^ZsPOapwY%AZy|$p`E(CCR4Ze|!)6Sd}ioVekb3bplIJ zk;Z8VZU4)sc~Rmo^RegHWdcBFbr zQ;BBZ%v)1Nb{fOTZ?pzZF|n4JM6k1RcYNP{pN12=%7}xfq;6Rap{Em`IC%Fx6;7;4 zVE_XIYuT3+SwhhTF_<1lc!Ch?yChIIEUu80x+M(E>Ewt zP6P7qGzLUst<3_f+AZlE0x(|nW`{&XB*sZv+p^!27p-g1!l!zNgJRlK=4Oyh#Wy zEC^hYr-kmXKU@CrKUs$lE)sXPPJDU(on{4G zP#Doq&oN8?T8<(<%YjeUBA%mhBeRL8iKH2oTCXqqQr`h8g}jxTdF=v4drcb#l@d<+ zM)k~#f5{FE_5Uh3-`m)7LF5p0bVj|tcF!_~c=fbkFBU&nB~*T{8bdRUZ(^1bey2Jd({VK4m!#1T;EF>gPnS*O4o-sI`*#dK?= zn~yzR{PtcYfsS=(++TcBh>;Cbiuo~mV<7bGQR+G;D^#yQQ|3ePzw1@QPo7-;0Ko1q#I5XJ>tHS{o|Zg`kC`oo#KBOY0nZ+K1e%+~`x z-TMdIAs&H&Zh$z^TFq|A4?$Nn6oG`Rw|te_7x8E%6c@YS2uLR7J^XGguCS-01UDi8)Sy6#a`5bPvKX?KAy^XYmHi-qcmQt(M$WR0^ zk#t0+#VyD5F^$-X;=&y;cdo$mJ1+*#-Lj#tPzcSIo0?xv@iO^u(Yg4Dz zm>nWgdjRw_9u4j3@(dwB9ed<}Hovv*b9WN<3GxKxurhq#x6uX8VxaKm-=!KRjr z%%D~T@A=-=_dkwoIJS@5E#{KkGxgSG!dz9@EYoq0B_nfRLVZpuF^0=gUsL7agw<}~ zyy`dLkJ0(LgLS;lENz#eKbT_u^Bbf`et?k|!Y^X9NR&E&* z55tjakFCAX07)V1B;X6iO8@DpW+V4%h7;9gI)!|qdiCd1<3m$UBK77u>+f|ubOaOy zE^RDE6mp+ zVvFHP`hIIT-KoQQY_eXYOduQ9DquuLqKI>`*7ba}jMS~_Rval9k{t-xY-(x`RhG{%($tyEf3e>?|+57@wF`BPb zmWor#)iizT=7@^DrE`f~B?;5k(gdoOdmI#KRy=-k%@eO5Fdox?2DK!179Hn)I-bKK znl=M!{t)TpyGX}CbQOE9x;Hp&9Z~D%P&o5bT=B~TfMS|wjmc~e3ertA;q^j-K>px?f`@d1FyM+o!I-oGe&;9eX zGe7IzjNG?ID5M#f^{=7+MXU&bwucimL`CtyyoR*zf!&_uUd6}8qhj>{IBqEJ#o*@F=4LQs{wc~#yq{I42HMsA02epN>9EUmc0&l zjXU;W5`p5yVj{Q`?=qhj;WwR4i^aINe+DGOn@X`XL|0%aOn=cWDxL;PX^fRal4A{K zA8VMT9-1>X6k>z*aU#*wFCA2U`^dAAOlN&6v#&~!HCFYvw)T9A%t{`J=*=@mcu zm3dbjbGA}$*d}xh>F;Q)Uyrv>ij?S|ex{Pl{T6jdiFteH{)BFJ>VSZP zX#Huwh>Z!e53X6BCr+O zr>-~>jo&aeq&H8^2Yg8{>K;9wCnnA;b5=vixbjV{;jMySy-EMfzB7ZavGb~^%p~*p zQr-py>e58Aq$IKyC}xiZvj|sx#ZjDlX8Ob7!opRF6h9)R-z(EHne~;B%nd3}yB4C* zB$>Tup&m#&W&Jm)9Evqam&Qyv;QF1w)s{x|wV9YW%4?^>ieI|=gK;8SFWFS*+pWPIZAX(U63g3vQC3gwPn&9E4RXHp zo^1mK{Ux%3pY| z#KF!q7TSS^Q-k!Z64@~2-R;3};qJ;r-@|hrRlqjk<$Nz#x|IQ8D5$^=bee(~nrUN6 zN6X@3Zt|3-=~K}SiOV^qO%H$e*DRf03_M=jh59Qt zI5;O++vSyuMAPbDLe5&cMLma<14Gu!HL)e`DpDV?K6ibgPdZ_qY?#RIOGv`0gL_jT zWHA_WH`6VQYAR2)#S|P1M!Rlqtc22q*5Fuhk*WLk74WnCGOCYVcsbM1LMF+;PVg#P zsQv9iok#|bzXA=ftaPAVyIIhpfw~kvlludvJc&}PU=Qu4=u=Tn<;mUx%Lg#A{n>dL zfp)RJ%v^-RC9P*a-QXZ%B_D~AE)vZ{83Bi%(XOj9&@NLCa6yTZtTRafx{~ZApMi58 z3c!z(Dxmx(9rY{jypkZnxRCqXmKg`l8Ghh`UkW=P6|slY z!te#%z#8`=J0Am`-)EG*R~|`*`(p@adK{wCZN<=-PX|@(dw8o9eLN+=#Y{0IH zYx4`%$Dk0FTt47>iMhdYn0x12BAHVHoo-R$uXW%R^Q2vAMYUnt^6kT{2Irg++K zTxtSxCG6#@G!cDO*!*u=wG$FMu6;)JyzlhnXbJm^H+?DcrWe`$p_g?O-MGE}gZ87A zI=rH@_w-wCj4AkY^3G|Y>iIt2n^W)4(Czoej=fLB2)#%suW!|m#2o(%`VTq8m_6t} z{19W5p#Km<*2xjX7~6kOODfj0C{c@frhke)x$R=(Ik+WrV*29v{aYj)$_AE%1`=*x zX$&JKbJP@p9+e?(F>i}v7xSotTcK`B*N*O&wYel^g?)2i&oQ=vP8%OiRS~SpHiEAc z+gv);eT9?2ZhpG_OV^pfZV=w=>}}m(#zB?l?aj7xEU8-GcSf0}@|e7vhuSY_&fg(# zw&-UIzl1q`fSmpkepxo31SAGo2#yAnawvvKNlWW7Taieq!E?L=|r=cPqORmN3Lw zgsXGbaDj7+mt*F=l9Vtc$}n_0OpWPctU{>x6o7FmL(kGngrgm@wXh*V$6U?NSbuw} z){}&Zbgin@Te#>iQeN>HU(v#Bs|h+pT?KxIV=CWb{8ez!N#w%HSd)4Y*3)AvjdDdJ?@S+6h#-Z?&_SpgqV z^PQaMA;lXj?LlXz0L5OKv359-B(7&OI@f1MAC@Qn$dJra#Qf7oshL5l=}R)~o{v?& zD45f=&%PLoUar1;68^4dWo)f+gV`2A)M`X0JVk40xA1|asoYMJPJKhhbKf&hwDJ8P z8}5?_iByY}6Lg&g1UlKqp_?#<4t^BOgVz!>l$X*!CZ!s_h_wzXHGDB^U6g8I8TXaX zb*;GXe!f!JQ!98l11t8HVe<>Fl@i8IP%nSc5fMiqT$UwFB|aKlP{g5qTgflQyb9SEuiqYJe5lN3fed#S$KB4QuW)i)LA2R7>6TKB zOfcVI4Z8ACN2S;cQO}*_j&s5a=l$sl5?Or%7ve;Q{@ObcJ1r#K z9D-O#`FgODkGero(QZSyG&+zq1F;b8_22;?wX2fi;a}m>us|m&bZH-~#8wYQyxiPB zBSDjK9XJ%L#!S-8f0>y1JiAM@mnXuT@B|;aGwb^B$tMU#^-|wu2+D197kv~xLA3c{JZOs#jAgPS?)mz(3GD0FBhYzLK z;g(Ps)&9oDsC2%PpP3(M>pY<2|2dLPAmhB*Rk9=Znt=IlWLrERhn{58}#l|PbENr`m~mucSbs^7}BNVMr)L2l{hD)(iL z`E1iC&CjN*MBB~F_E;!UM$fY=%lcE1xTbV8)nXkZ-HVz^%Cg73JgdrxOgu-@R@TeB zqBz*iy~Z?VOz0E2r@Zq31;=pON~GEaE^w{yJXv+dq{13dlmd#A!L*f0z~UXPxz`X7 zAUQ8{w_R5)wsv+?_9&^$>m0tY;%h|=j)aeyj83he4OXIf6!}&R4&iL=O2lHpsZ&RB z;l3kM`@f=wdPNdJgBkv^)f{qHmnKvQGNqSP>ARv7p9>SgZXHcuv>`^wu-XsJiB=1^|dtzy^OyW!jvqkJ}!QD3qCUH@SQwDfo-ol8WDvr@UAC` z;AX6jllWhi&2{5kl9a4K8O#OcdSQOnLJ!##NnMc512yEttRD8Vl z1tk+`v`@D*aCCVB5GPO?oZK18sg`f>j8HbbBpyIEQp21I{%If1ZM|#=lQ_#V+M&Xq3{z1iQeIQ$s>d{ z!h0G2tNJQrZ7d#HmhI1JDd#7r(3{nCeH}zT0sPK6IJY+;q)D~(1Fp+Rc)}!c%7}%? zp3l$HD?^cLox*I_N13GSI*t{^*71Tzg@nl*r_e4wYYt&axP4mE96Tgk_0DsSxvQ0% zrcT$S$&O|A4*4 z{(4c>8=4)?IeRg}b=25)@K`%!upqtud1T>;F2CRF&BNpPxA*N^olDkhHw|+)lnHyQ z4g%;|DT_wTqfc_pddCOdCTZeV9LqG_G?`7ZrtT3=n}cALDG zLBC7HTC()otk8Pw|F7yal5}7=7LoLNG`%ZY;<%kd7@Me@(K^tEFK~I9$8fkw_?2(& zEHpwlkrkogn|sMh*gn*~UN~Vy6=zh4lD*at-RgmS5o%}a-8nSy_5mFVmnW)i#C0K0 zUpHS`w8U+kZHWzlxcUkJgmXJ=6Cm!s%4mt^)n^+{xqNq-Iccz43rF{V38=@Qw~M!h zJkfXrMGyzi!p@vsa{2st1Z4q|a)#*&5MDubfW)5FxoYt;#N4Ru%a2Clg(gRR-;Thq zR_-V{rN{-&XS>|sQz}(OdHg`0P=e|Tt7z>*3I@K(zt=spt4Y8?GeP)B79d$*!x`u( zKJ=BMlQixp&hMO2Q#TUuWazBBE(&r|e8_~xcw87xyq7wi0JIv!`>{SvS) z+m}-=zp6L12Yz{54DVexy~ocmpAmH7e($YSFvYs0Z z$~DzA48hwb6q1?`KWYa%R02QFz4K!pN+#xQ3MRq`!vr3ferJ3mE%0)D#SZU$9CMbeH3 zE5!eHR}L3y&!Paw0II|!Zp9foH#_)T8yV`tw4g~7s-&2ty&gu0|J^R(JE%QN$?5_q zMFj~jSa^Rggh^y7sA;zN6(;E17%{IbIDaqf$t5zV>AHA*Y`{y<`70kzsz>{do&*3U>Q4f37z~$f=>BkoRjiotm=r7x#b=6uqKEv;?E6zK6XouZx+ro(que_Nm z(g?8>E*)n7GCSM;7EEL>9OcPAUaujy*&Zy+n=bt$PSi{^!CL#h+u`psFdCTE=Ty&5AoP3d@7t|d`qTR?8MtaAFc zs@pRU^A-0EH4!AuEX>BaseTC1%uh)*s3Hm3@8%Dd2CX)`X`rq|t!j~}ARWoMk{QFU zL~RSUBj)kq%c03vG_;=Ap8voUwtzB97K>p5$62noL^El zH{O9jau6s2n)L*6$4_Qqj^y}?1>2E8ASVdq01b+RxO)(X^vp+7l^K%)^idQZ>fC!G zDB=$?h@b!wnti4^%8@}gAY|kjG{QJIXoR`Xps|UfKye1oR-zn~UH;&M5PQ%FFNm-M zokIg@6kw2?88a6S3Sg>7=7tC84=Jcb095i8Oct>F8;Ssig+#%n z9uf56DNSM^!U&|oAO%KhK_fEg8ibRAX#fTcNJbWTO$mA>j-O;Uh&&VQ{wE>*AB`+h z*3dQ~weVj9l@Bcn7eThCCQeCkR{sqs{LD zAs8U!6%z=d1tBCLWJVT*l!6e*6XYq+>`#yI=n3)ygtUT?<|oJ}&zi4luMtmh&)n(5Y7N-y637x$*PAH(KGH~e% zqC)4rGXz|@MBrR+2>8SVEO||E!EAx^djwqaYT$CqMusjiB8-)&#u7myu&4>5fJ%5k zCHSC{3J^UHEP0@)m4R^J{1ITiWrJpk(4a~L(LmgPiW(UR6a?vekamDdP(XSPsKQ{z zoB|873K)SgP0fX`BY@VP0ab{7s2_|)iW;hc3JjYGtTMr1Qb>S4v_n#0&Ex`$bUqj- z4O9ah_%VTva3tqZBAAW{b&d(FH_2eBPy%hugEZ|KSj>z;SJHtY0^&di6C(sB6cx-x z3gC4Q{{Qmv0(?aMzfTvw_|1){qIC&|@>Hz^V4-#M4e0(VkSh`;7iTn3y&kCE3GDk7 zq~AfeJfSs6#k^A+oOWH{v}}JWCBP1TVAZZZm6A^&Gx1c*#K8%BOb9M}7?7a=sv=PG zsGk@DkO2;70qVxiQ^_j_*Tp$lSKh0D)<&KfX^>$A8H1;aqYYXUeX4)FPs~&OlLmDX zJn75^bw)j@F$L8Sf)Tve1R3D07a)S}r~0P_B2%A`jUck_sQ?>;ou7l9tHC(TQ=a6J zV71N!nW`rE%(KMpNQRrBwBpcL zi4tCl4geFCR-F1Ou@_*X7;eJSieq0T`g$Cc+~ zAc`WUiMfS}-_8@ss56VBzkly`vcR2bJgKA&PdUi9LmioqrN9@KjxiI2HY8 z=}f#75yKhwhn0CWAc~%*iBdqacIk=PGK-No$FOJV#Jm(kBN>D~rdg-IN;K`J`z)7q zu|rP`=*Qw5Q<$am^HPk(SDlMX+h&@jy9XEoRi1#fZK7E^IDjchw9ZSUve#DJ)PA1F zsICu79j8B^Vvajqn9<@eeR7R7##{a|?D$`8u&GE>E=erBl|Mg28N66#Edz58S82`T z75Q>PWRTEv#+OGpEPBt2Bo}q_Mo9TAD}UBkGTOgs-$+y4-BF?93;Sc=`Pe+CbK$JQ zbu}U*Ugf7q`UC5@V|z7;G$B()wRitOLMwQLH##h==QC2WogfyLUmh0IG%|3u!5d1A z+yvk(12KtwQTek!GoB9tXJkX4W!4|zzPJI0AovktGfi^?9X?6si;h4$zz3d1Z~iPe zL4*Az1Z=VE5kXGgeGh1&pw`I61NP{Ngh+a+Z37($VSf=%e*V0|x4_ds|Gk^@;8mVF@w=Zw~k#Q8xn0DkDB!-8kC#i>= zYjb0~ct>%{&OBd~Q6w)g@GN`N7ZLG`Tje=1a5jTIC@6ap`~(H1puk|4mrEnJDSNt4 z(rfCSI2_zBp^+PO^klniQ2ZVgyX8Q|41#%q9S3ypjdaeokyFqF#d{)^S#FBDifhP+tuFQZz9FMiNN=|wMLYEfQ=OOJBFo^h@er= zs|*-bFCCq?W1u=C)Y{(1!@<6ZVmiCY1&cL3#@aD$$9*ZIN`1D{7_6+%- zq{Qy#7h05t*c8jBLjrtT@$T%z<0Q&u6ZPE1+b@<5r#Z*Ov+&tB@H{?cVvBWaH3MfF z=5BrrC}24B9#CT1r{4_guzTe8+K)t2IDNK@_KB1|RR5G^EnssD`dSQ9clYO>@EUSi z=b#p;%1w_BVScpAt*?DS^GgV>)&W-rdlVJe_|m-%M~zl0JN*6!lC)kju%Ts$64{Um z*dfCziOs_fwBwT4z+s-%oe)a+#tLvJjJJ|C(XuTaJx{dbJh%}i8o(Pc^aw~T<+R)T zD5qd=<=)Ru6PDNAyZZU#x|8e%|4a{lcdqo?yzkGp{AK*6YN~L%_YLiO-ak=hU1Mt9 z@otMTQa5a5W~q6F?HA3jUgt89ln0YCK~I|)@KU-#Vk+K8hJ)nz2k3-wOB(v&isq&z<4subVu(~rhvrhpY{yGsfQ5! zE}cGOywKO70UZqJUu|G_GP$hN(9#_T;!UW{Yf)t0m4E_WP@oSACh@tJgQ>IVL2(Qy zZlT%9%)+()%{um_^}Qo?T`fr^WA*d9#A`2q-#PKe3rZuh7iT6T9oVh>)L$1xElvrE zD0*v?wNj?XB)oiBz>tjbgB32Q}(XCJ6V$|i~lI#iuz6wxs^w~SI30&Qa0I{OOL{~h28J^6Yu+F zG$)0YER_~L?b9loNlKZ&wrCc^wbhY+Zj+VBNG;a0TRT%(0tIsE_@9O#kN@BQzjT@} zY8I8!!c%){jQ0008135RRKxyr2!`2JKqaHbe`h@P zT~oQABbN9eclrm-iJ|`(klLpRJl@QAKkp;GagXX~P}l$0fMmOvCo1r;xqJSBh-VKa zabI(4O89eO%q~Jvr3dL_=f&11Kh$%DhMVjY+W~@W#`BNfiA%LEgqK9TUgQ;*M7u?2 zP7AcVFk<}4gGpzpe)s<-*WgB*9BEEOxyry5|3>8{Il|lhRw)7>FG#qh_c4sQS(J1pmG7V%vx?JhSAdOl9 z1Af6zpi`3cw2NtdFMTjc#=0s&h4yB2MuaOSKeQJQj?}CVySU%&WJb z9;1i_rYedOX{NLIsi9kRxu-w)%SUn=u<*40718pY)kux1yU3J8hb_BSj?Vt&{Oi>`g;RaOy2nUn zr^8}|#X`x!8D+81L_(F!V_z*h=i|}D^InEusabluSvdY{R>`4OCKFZ9L&m2Vhit|5jC>3C)0W}Xuf+Ieregt8bIG8*iTR(hknZCYjos5M+FFW8ZFvZehf>VX}Dr^5-m(UM|KA*G@Yr1!&Ak3FhcZjm|0JXt%mv)LYbuJTv9$=AnnTrntME zr=J)m4vcL4uZ{4^?Adu3-oke`q?+c#|MwdlTpdfN&Nie*>6m<9EOYp9m)sZe?&4^0 zYDOo{?BhymuJdkgtmwwQr$S;Pv9>eS4(P?>Nh>(gHs%%4T1~yiyD$`Huf1GRh~8#O z1@ixS#=XWF1naa7W7(~Xi12L?Zg8dT8R`WL7WP&<8q-XesAM$Wt9(hy(`VdgOaS2g z88}cDsPpKce-d)d4+@yO4JAnpWaVi>8Aar3ha57jui;&gaoC2C|s1V2)C%_ z;_#@=a8P=|*XN6jzegHygUvM4_UxQmBR>bEC(m|d@+H^dCc-2G-@$+sy#4^H`watC zcfaQ=p3KJw;~u;}={_`~>1)({WUfD?e8A#pllS4P)mPS+Q$8uycPOth)bW2#Q&oA@ zva-{lE&TnEn;*BT``556s@G)Ut+hbnHsMs;EwDMX(#zY|(_RyzmG5YjP^+DSkj2eh97 zc>>S^`UVq$7SI=*3_F1C%56cEP;z3}S8s{eI+=OB@++@4Q+A+T2&*I6sM}X{P6hWR z_ltA0PnVQhY*FVMW1>+V7J}F;7w@fj@3%d#zVo;A%=&C*YZmLY+Q&PlJ~lLt8LF_1 zMsf$tOgAifTJ7%|9okv!FV`tEaZdr}@kZ9Wq%s2rLX_NUWt+r(U2sgmV8{2x2>wD0O{XDV+xrqOPqH0Fglq4hZ-KD8UcrzHli9o zhZ--U8YYLD8=@KqhZC^F5gx@H4bhzxA@p_ zw{ik^9SBhlHR}$T^*;8qaO(H`WiQ)~(@!;#c5SgTu@ofwZJ0)Y`2uN)J|t*1!Grmy zxx1x_v>;KAVHzg+7Gcz{G=(EAw2>lFR&k1I1}FLT4_`uKvU1<9B+KqwX1@ETNDdz& zSZ##t{XoSeyX-){rxjMR~O_z`%qbtLYA7i))y!)SXsxgI< zj(=KPjApp2GdfC76~{R@l5MMWrX{6N+0A_-XM?rDP*TW}fo+i-4L>mrzf5n$%4gIx zZqfAW9Xm8pj1(`Onrq%v_m2J;(8g8#f~NL0E%v)E2LdK)|0BIVCMmA!9=7Vt8*hlE zY}B9G+lCnjd<5SHGX`-(e*#0bT-<~{zJQ^Wm&FGkP|V?eKbKhI6B_++YE^*IYVyy( zTIMx@1i`XK*U+@VgFdc#>0VEx=q(FM_4l_K{x>NmO8UUj@PeM9=j2#F9s_RF0*?Lrd>N&$CCqzfXYR4m-=e!e!tIEl zK)d9i|9EV?ep#KW=ZoLK#@Thih|@dq(%8rIF~cn0z0CQ|_b3L4s+kDORsUg*wBDig9VTFPLH2_6Z^+CUbl1yLuy<2SsB>8zov%?^Tmb& zw|VJA5XCNkC_46DCrOuOeVDw&|E$rC5N0Yn@~}o2&g88*w7!htIQ0Ca;z#Xm!YjJ! zP+w!tTJoUW1e$VE(hHSx9Gh+l4|HJy2U)qGTwU^Vkx7S(BYde@#|yG@oagsdlt_Gq zg;FEurYdj7_`Kgl=I`+d!vLKh52k}iG-va70ZF5yyCqcM4YLp)`LL+|kwg=5uNnRo z-uc}e@LxPe|8)=fdZx#s+(Um_A;zrKIZ}p)d`95!rR;}0AXWHNlJ^#%DJN|hbbkjp>jBz{wStK2`&GRFW|3WD{4gT8 z*>bz8mrIwUUzIAIC2hl0BN?En*h(qN&UQ0ezi?Nn1}a=;c*Wf6~w5Bh5{LQ?c^cZ6BOz6(uVZCdr4$%?kGiRP9_U(?w(eL zj}?G0jvIFXk~1W$&Wk(XjuI6?;XoI>uSI|-_FVya9vx^mf!2nN!Fw(NyL8-8<)V+4 zT1CG;ohT!VCcW00n{U9bGjeEwC~x0^KpW4uG=r_Q^sh>jfy(5cj9LqBz7f05)S(5~ zynSH;ZDrrmLqnCCKN)Y#xm!wkI^MPkzSnBiT zN-=-JmZmaVRe{V2N!1ah+-6sWu(+r9pC88LW_m!QMQ-*EXfiGDx%t0+JpGYsd2ew# zsn+mN|M!hLlpb$XNVIhyZmH$oCXIR$s^2SacV(45(49>x0^-^@AFXN$wjLjCDD7Zg zqTIS)7mgyMtRq<1^r=Nxy&h&L`bpO<;zrrKSG?O9|Nc6I-(!*E4#sB4Y<#isUztwC zRRuA|^H9rZ!S~nShpdpCKQ@S&XT{`rqYPc;oAAdbYjCxPz5d*gWZJ($(TXye18btHwbLhFy*RB~ksiqw1>e^g3hx>OC_2AWFT zuCp#m#e?@yKcdsf>KQ+CXYe_Zf34i6zHbA~gBG(8_Rqr@ZOqpsE05e-`}E@Uo=#Cb zRpHe!%7`u7Ja>ClKhwm7ersvHt+0{U|J3P(j>i=R&DjA(n9&BeMWcaV| zssxx@vb8H|-hRgakWf}-^HzcO^kjh{BF7`y<+SJFjn?asijWqi+xc7t4PMbN14~UiAVYVB(WxX(85l!*DFu0b=05O3VhB?uDlWo2L ziw%r~xlz0DL6#972#oK4y< z6;3U%`7Eb8N0DLv>ZXu%JH)$pqkCqxCaZRQD6O;bdRKv1G{}fJHh6*3wsTa4zLJ#B zZ?|Cye#zXHbL|MdHBepns5JPW7a-oTk5{K(+x+ic@8#$QC;SAVq8yRZuCs{EHOP;d=Zq@Nu*XDU!x$w8$|tp&9k>@51vt2upfH9No7s9jJdx zhj4Yi%A<8_ehxPiJ$+nYYj^9bKiUZEC{pNGmsBQ1Khz#QLnyjMZw~ISZ-q&9xe`HP z(MEQuAOXJR^4y{;_Y59}_nW6vnS}d!_mAnMS9xw6-y|Hl35E~?)Aerj(=7d&RXU4% zeXeqQJ=fY6p<|!50T#-xuPL8;e#T~HuFJCc zjSIz&vvb6pG2*NDkepRg^d|mGwOVF=DIEJ!L@W<~Rq?B}i2ydsC7x!4=p>3GU_~F zeVi#s&6fIf_=DLqPuzMJ2GXeES-CB1?vM)S#`22AYK zDGxh34l>##4h0vu6&F}#S}!x_xX?;UisyQ>m43fc`pll3nxORP!qQU498<61ouNT; zw5fBTtVtsKFSm3sxikJw3aLvd<#skX)R4)ECZ$m@#d|&(@gH}IAv4nZv|7w*+7*PV_VFQewpta4Wm;I7TK;Gyaf&6G*-B#eN^oq+t?^1N zf+@FvlP{SP%&bX`v$XA>soDpJ%)Qg9z$}~liC+>JtYx86arn7d%S5f@7*g_+Kq)R> z=~6I7crF>yfJsb|WpP*MKvMhQZ9#K@jzeF?LPjZMRC=FTtAe^ri!pOf60M|6vE)Uz zQW)Sn0FYtf+tE3Y)+TvfaKTow5UgE6s%oDeGAFH7!Ca=LpE;+2Mt`<=v|*dA#Hf`V zimm^Kt90Q9RZ6BCOH3&=IgyD+xcSBGX9lB44= zS>X-~YNjvNB2_CXdZl#Fo;*s+6!hJdg^8qR$^tZ z6vURy!I&cK%tEfHNupxhA;(?vdCbZ@NW_&TrkEL{O~X4(=U}h`0;G9D+8zT4SleDu z)xJDruB%v!P_4uQQbJ9jbdsPH=E8ze!i>?XVWiCB@k@sUh}pWJIacRjxB`+69V2_O ziiI3)du&zvfRMSn;<=yMN^tg2FZtt@!~|2O3YaixUvT1UA9x{DEF@{$lYxVoQap!~ ztzCHJhQaA# zBExdIr6ZhH3K^8%H`1z*D4V+h2UQ?m2~IGDVJ`WF0n-l!7L08j;g~{5GLaa2>B1qK zmOXaaTm_`0pFqhjNhwGuWh$Q;qe(+JOowEk!d)1QUQo-PsccRWQUXJuw53>Lk*#C} zrhJM%CDe^22aFyPs6*0U;m!kQ+^cv_L9L_#Qi4OEl%!Zf3up!N+ZnGT9I4H$ph+Ud z6k?_1C!C-p@5b_c7V4S@LrUyVoii}_ORALEUpiXgO!iJxDiTaN1FqSVV}biyI%hz< zhD?_`j7S@$PgTUIf}X z=*-6K+aUQ~6eo#E{EbaNJ&NuMi_hH6Qd8BvnUebNS*eWnw44+_WbfQB{L1p(30KOB z{1FM0-z548-y*q4?K5catI`L`4E{F?{x83 zDzfEBqEkil8=PX{*?P{N{#-96c*Nmxv>pZb$A(6#2`Q$2xB% z|LJZ1nxeYp8o9>pEQa?UpAZ7WN!Zj|D)zO{Q(n!~r+r2p*shDM(7RbL7e~=RSd{vO zXeBXkYs`+UnJ-*O@{8RVb`HO5Q5I_v!GfjPL={;>%4acHQpdU}6FXk|T~$PGJo-TK z*IEYn^7>B>(o~raO_@Yrm!99vPcmO2RMw`Y=1E1v|5Nmu_whBUOZO<#vXTGzMtEkW zT*+GOP!kTFcAzhR{koqE9TD;VCk#66m%e-n`Tz?REA#CQb9`Pd*L}Q&5w_H#?h>WF znJs19e$^xaN{@vToW%S=S&gQDadKa#UED;)VD{3C4!asI%3ea>GnrY|wDzTO-q&awdvn6OXAsH{URt;7ql(x)4=H~aO5B6fcf zr`kfHAo}BQ7jWSt3fWKr+Aaym1{=_N!9X_nu3+|g5nuH=G6x*Hw@21BVTJoVH+xHo zea+I-FHUu=>s#a}xmxv?;VvM$O3;$~BwTTrLeesh(tFNvk1}d_C&tyOuCd_6cD|eT z}5!VDo0`W|TKiKlhj^QaD&W^gGo zZS+K`pE7@B+JrquE8OUzW;))44JZ8=kWUkZ4BOakKi8aOFYG4bwmTv8Ck(k+$jtv{ zXDuVk$2K!%JR;cm7tIblfyz7*skgp05#Kb$=&D;64KW6NlQ{kD{deBfyd=-_AKvL* z!~*&56BdfU2V_3){;Lsr>^2$L$)&v*V&E}y)h$i8<<>Cx-Z^M`EIJ73oL9t`B!o zOg`*4xKS)Lt&aPMU{hA#y+4854B`v9Mx+uqxISOI`HbYqa>6d*TTij^X*mpQDX3fE z=1;$O`1LWxiH8t>8AIZ)gF$xIub#4I>yBf!dX&0qOT1ze{2|+I(>mYe{iig1K42&R zst#$mRGuOc*a(o5-$PTI&mP!6arsucBlpjO+30SS<~O^6cES)3mb&?S7EFQ7{TLjd z23(0bA{Pq1O?gtIUa4a+{1bUPm;i+N;A>TNyc&r}MxC z)23Z}%!tO|v@2;`LAaeWl;&;mQ^?=|g#w@w(@vtHG#>(gSaHVk78o8;&{F449&_Vv z5`GnXA^k6rFU~|1&--iU2nTMj<)js1gjoyJUY!e|$Toht1FHKisC6CG*E)oj7JoQPVp~Z`Q1t_JGMYcw06`!uo6Wz>JI3^JjN`xang^>Y{z(&G5F}W6@|U z@~M5%0%;A_S6 z_&h+M&lbhpyEoRevF6^7aHxD-LttFrv$!y zzYnBZs~bYXy|2hqo_02;OAn5HA`w|8BL_vHSYa%2y;j-uihe`he}5nh4PMRoBr(`BdR= zsNjplcuz!Bq@pd-Iu1M3+kU(TD7vv46g3%In}QEkYJZH{IbX zm9ITHL04%*B>&VhEjxbtCqeZdkzDLxvW{~B@6uK@m^Oyc>EG~l79xJ0kn`lIrQfW0 zCehK4yi8U-GXl1G5%^t`EQ`6-?w+5jS=w-t+0?Xic}Gj?TXF z&Q}-PX7}(YN=+`ZOek}ks#Bo64>d~^r*rJ3^UPUrNxVh9)M2`O&MlN{ZeYBTtsns# zk)GY|s?O$7en=YtcU06HYCaQLOfpugk-D3|M3&lE8k;*qOq!|LfReN~PO=O+vB zX#!h{C3+RE(oyW5MW~pI2}N%eG=-@Mg=s^Pv_y6mMU0l2>CEr9GapO%T zKw;ZVA4VoAcz%$nQsEfLBTCg$*u=7}CX&fe;~FT(BAAF57L2*j@dRF4b8VyIVyK2{ zKs6TRD=R=CLb zfL5bVK&fUdld5Hyo!NFrP3SXnMcjL+c6Vr}CzgUbFcthGS57L?AGFdWd2Oc|zx^6E zqEFZr^XQ5VHSu4PG+ljaHd?nx)JKNhgi-jVq;rclJI$GGGcX$1nR`Qgx{i2Bn)=v( zr0;wP5EMBIu~Dk&34@NO3#rEF;c){!wzZ7!WB0A5O%(ruAc;{D3hq}l@lb89#$s_q z5ERfpRb#0=?=G|W{MsT@BJQYj@ulNdd)gaF)k zASvj}3nRMC( z9js%r(2?RnF$|-FRXi?$raj4pPk|u!f ze5R-Z)G>;IMWP7F#4r@-OodpRBp}mesDXn1MSMUY4+^YCg=ugU&ICgg%-OwQUy9Jd zs^)@eQKvo(1@z8?155n6CLS5$1*T;}av3Q?GI{q^Fs$PjmDf)3$g*DG{Ot~?M#Bwc zXaYld{hA$$NPx!J9b63u2spt+>O1pE0)gm4134pUJeG$~>;~Oh>s$O6E}19*y7h8Y zm=bV{AL>>{P|a_gK!y`=T6K(eQsBJeiG$AG?x?DLoItu090mBLgqu-e3IHJvMch2o z|4a+3C{7n2-axzdk~hM=7WkPi1qZSeOS&C(KN~&#Dz&V2kIQC}OHE%L!Vs5FLmA#a zi_1|818b^WyG`zt( zv9xUbGE6RHKOK342>^y$=GDI7fPgJ>4S-ofFKD6ucv6Bcz3v@cpAYY7Mqi9<_3z-Y z>XG0gj7D0tHsrQRzWuTJ`?uCv8NZSDjg2DO-OWAkB@-$)5A5|rh%mwphf3p&{~C9> zr5;B4P3ujxQR_F<;}g;z#HA|e=~zF%^ZgZya;KVE&UpoA)quq_)akHpcsaC)Hy%J! zx!cFxAp=jcL%DnhYX(@$`8r=O? zfVa<|R2BP@jreU2WO_5blZoMOQg{CL6&oj16+Hx(m(Mq3D_BqG2q01z2p^T%de_#x zcC%aik>ULV0<++!^*lM4MTq2LTxrQ@(CkN>gzskMK+=U=8@FlY^rXuUu2%6Yu3U|2 zswNh4ft~S_JVP;EGyATciIR?dTU=!Q2);7<1G5)F2U#2E_;xYufL}jksgl&4kKld- zC3$RD=qm6XKhEg(Jo%ku7YPgtI@)YJ8tU&iBysbI7#EP35&J+y@2ugiW(l}+lAmL7 z%2GH6xq&?leS&Y)KH!;?Etlq_aK(zuS2sx2vk)sPG$6MNgs8&1uI3anzzQ9!yWj;z zlb>BqKJ%FK-%GizuP{n&x!TbcUg zo`Of|g0&yxBMl*{xT)dk zTI(oNHxk;OoxZ&Ewx3$}#hD)_Hns6N{6dm#SdJhV1iS^fattsU4zWyEb1gO#Trr@uo|RDf1(fIBNLd06GZS>ozRG>t?m@ zdSRFNVO+5==WeyCsHg1`40HpADVVHZ->+GT*dDTye|i7UETdw<#O*g*TADoi9d4UC zlNgt1&tF8p#fSWBXP(}q50m#F0m82Ed-qw$ zOj<9fur*{52iCeH0%+v56yO&UiULknWhE1f6lGx@#;8_E1#sfGi9iV3o*w{lB@2|4 z#2`lZnP-5FL@$U(E~k}|I{7LqnXrWd59=_B5+5bU);8v8l3;<43*)gZJF`fGn+QC= z;c6%Y&u?5b)WGu_AON1vT^|1#6T9*p`+3Yg(&$Wmb= zms9@&RpI7CcE_Lwjr3gE5TJTN0dCuCx&flI$HQFRf@{Ro|2* zpp-MVQ5`w~P6>kfV6DA+0iXCU4eHfuXmu}Oy)6l9tcYUe64hitZwT2RIxJdEf!=aIc333lAB7A>MwJg#3rTwJ_Aa7yQe# zqPs*X}n086i>JXIr&tc;~<4DeXvGPr$^Uv7=SMYN80WB5UUBm-HC?{-9xMN{uYWj%caZ%{ zeN>66y5{EEuq(&;1u>q`GCehgz7| z^BdbOJA_md!gxe8)=OD^+foCsxdKlC3JDwozBcN-oF_gzkAi_Dt!^25T!%36g1smjYoBfTOaX9S+2G(9>l`1@=7?b7`OP=l2sbS zFNX#`;$Ec5Cl;FdAzZ!<;`18WdPvW|lQO$;+mQG4>oqd-;oZU#7SQgp@^g|azfz8@ z#(c|XmZt0UVIM<&qSLae=NrLr-bEo9t%odX2;M`o7K~Ix1d3CC4sY1h1Zi_oRL_Q4 zGy>K%{%Tc^Ia|dbO<^zaXrve5X(F~;URK2)yPWpzOFNmTWT{TrtyYKjYRlf`)`;J{ zUqsIw|FF`C9ZSn>F%!H8T6@=0u1M_#b3s4P=sO>`@K2lm-?Mm+p08WHjjh-BE&C+Y zZ+dESwe!qp$n!hN`8leqUv80tuFK_2B=EL0S4Y;Ltx#m>d&>>dNqytLad$3xZwOb- z;S%cH590fgaW}iY-W7lOi#a7mjvrLMTm>u4U#B}@! zO?~GN@ZEfct$fVGXSupE4<22nNt;fJ>F3^WgKXY5&y*k@ z{(My+Lc*3@6mo1mXMG+E{K8b2jAw> S3Ddm$_?t%ZPkIIGv;P4hJo(K4 diff --git a/core/src/main/resources/bedrock/block_palette.1_20_70.nbt b/core/src/main/resources/bedrock/block_palette.1_20_70.nbt deleted file mode 100644 index 8f4957b95013dd748bac4ed50c3e370729664453..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 176502 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

bkIWg`I^~cgV&?1^)kY?)Q07(A8SpTQ2lKpk z8Uu#LX=={SF=ui+Ky6-4xXoS3uH832uC4ln(D`}&FK#jQyycG&lmF`ulp zrK5Qw$bw{;hy8oTz`uYEZ|}WR3*&po4|D~}#ARk)kW&v&opnjjp4Uy{GeJnD3=RD~ zB^1X_Jm1{IRWKOI)uP}|ld~^ihi#N+26ZRngZ}MJo0fCz$r#M*9U{^%VPHC~Q$CN4 zP*50)EwRO^>|ojtC!?IBfSgYjGv3VxF$kBP?sU|?#=Ey8_C9%}S8INkKv-mdJ(-BU z`hxhbl~}$3BVZd<)Y)p1hnWE4({+CoQiS4@K0esq>+bx)Q`W)$J42)a`2WlEF_>f+ zQYHW5To%Yx|uW5er zB8MDE>(r(9fNQ!o0k^|#4wc2T>v?^H`zZzJ^4O{>srczV6r8u9bT<^-6%qeB8>H)$ z7_{;RguFbIY4Bnh36ksoLWvR$!glrGP)Y{KeQ&MM$MEM|Y&ugdpE(7tuJD%-GnJ@SKRSAUmT=Jd}VVE{OxNYyyqa3J+mCMV$5 z`WQ@68g;G&6f?%rpG;^+FrUzaWsz zXbOG`gHh|IXaBN*5?Qz-+IA13iv`zl`LT9JF$On)P5%p?)3t20 z@(}Y^`rr_>PQ6Jv122_Z)V~8h(JI_>Z$JN#0H?}a*jnAz$0!hl_9rLZ#e#%D5^$0} zZvE*SAlk(O7k;w}@>qZLf9%__s!U*0$4_XpEmqQ|M+9ZPlp+m_!M)#eRt;7M!g;}B ztKm`=iZC@T%{=|m)f^aBFi-Wv=j=mDXxqubN`wRtrt-|McK(e6T~cP?&fLtv4G?^Q zoA{v)?NcKUyoZlOB*2z+?9IUh?1CTlcaPCqf7Lob6}Iy}&4ilzzSw9Qw4ptma&0bZ zLCBStt0!Nkkz)X>wEVJdl?B-5QKd-<+deab3zu|#^&Ql2n;DZtn~NiZfK4zFcnLBr zI4F2b3>*vqI9Icm+3%?aL>#sCcMXyp|OE>VrP)HRkcW}YMCwsf>D!?sl zf>&SK!+#Yve#PaNap^@5#3$>`ERPNK308Z;xm9GS{vxRhH7>SL5#>9N&42*q)o*9U z+9orWe}mC93&Wbr@11~f&1Xn&u3A$T5zYm82D}oqc{pWuL&Maw9{Vyt+c8^Xv;5tSUQJZIIc7nI~6!cXxs;6ZL zUVkNsSxx+}MoLzZx=?!^ki|fU06Ysnwjf4wH3wJqWBjD!|B(J6MVts-;V=n0s6e~n zF0%N4K>5i zHTTO(JDod;qwiM;Y&YI)E%%(K1+>z(9B1vpw(GETyX80rHLvnkosj(-O=#}CZan+! z)G7>m8nb`W^#nI9CsKm{o6}=qWsaWZV&HK5x;-}37sDTp9ibUb_BYp|ju+a}1jfE; zaL)~<>+dE;lnq?e;Dg(k>{ZnIJ>c=%GVxa$whU;$@@QYmgIMqXIWUaYI_Tg2tIbmd zHcgnu6AxR1|5Z5i*py8zQ3OhHV7|}hzpDy|o8j7eDAac~1lp0Hy@z+laAn09K(9iT zZm-qpD~CEQ;g+DPFEIS#q5m!LFcH|T)@;2=pj}j8>JD2B3P6oSeVYnwJE=$e4^dWI zWMIpfdp%DV3ZS_q(d5)@|CjDD)vO29ciL`8SG3;~By;rPCJ0>rlT5SP>Nt-n zn!19v;<4sDgZ~;;)XpUzq#$6gHUONSa{OQm$Dn&l1GvTPVW|2)uWNW0JA0Ji)rU|! zwUKApJ8B@9Z!PK5#6FJlWGt<=*PE448dub1TYH2(KX{HR&N)S`Y9Z$S@%Roo*j?M- z(30%vuy>q4ZbcrGfi>U%QpOJt)m%-}q46Em%-WXNK10*_`$8dx7#j$E(cSSM90+5< zkWc@YY{XCMa)@WQ|EZi9Qr+2^N@+GF<+ zj$xTRQBX|Yd@d+yE_-gBlgFsVUH{uDH_CO^z-eQ=GRWw{3Zcxd75IOS`w;TF+zLoo z9=;LlRsGj??L!}+RGD`y*8gj4UvB5>p~Tv`Q=EvvGETvo7&Y+9K&^Iduc?F;WD+x# zHvgCHi(Bo+_iNzwT=v+jOK^6;c{+}L{og{mWq@^RgtEnRZU4*(s@|kA6-)ou?DyIn z>Hf2J*V?%HEDYL&EdQvaxr{uUdKY)D`(K0pdq}KJ9FWXG4a@Mb9MfpOT7)R`WSKbk z3Ca-bT|NSsjlEyPc&wEjbcx}8U$q9DZ{is~&)G4(ZLv6?Frdp-qMHNWzLvMk%xhC4 zTvRWU9VPv%=NBomQlvjx@2%ry5zFUv&v6NN((9M6fHSY;Cc->mSlF zaTs5i3P z*B9j6ta(0>K{0)~5cYwbgq$>LI%XTp5}sJG%U*I2H0t6Su$=q_eudoNBdq*m!xvjt z4mTfDY*sLltGx$*q_K)ev#rJ)Ay+qViWXNXVEEjgb|_>*v(y*6R$^&=z(!m`F~|9z z>gp}djLv4>r=l6QR^?Z@Y{A`?`uI3&ckw@Zf?>M)Ys#N=HN&~LRaQt$!-Ze%=Tzb2 zh}0;VqJG+w^^OIeO582#ekv`_{mHTX600)JkD>YcthO^CR0b z*+k;@dT_{gM3U~3Z-V+@9-J$A+^_L1m55MeOTI+7J3}+wG;0{K|aOD4$Xt>Uwdz{^#f&>mV;>@~6^}h;u>QaGFrD{VD*N&#S z_r$?U)y^=@#%j~faVfPZ>UmH7@-&=QcokQwo`-$arhiB)G_a5+o)-@GvXcR%#vC3li^>!5_~xPH8RhY z_B}k)Lb<5U8fE;=#+_=(e29%usPTQdQ9GVV$QWBHHN)fBPo}(uwZ_j@FxK3D0ec8S34V%yi)TQ_^8XQ?;sc^#R>iqRy<)FaOt>2>)T z?CP1{vvD>08zvWLz8pN{F+3UwsOXkDtN(pT6m1mkJl|i(yn+-?Rj|ZrJBG#c>R5`W z*wG`hzY>*~(}uBrCzxmmd1X*wIfHT=s|fQ|#BeSf$dsPLrC*R!<`$}iBOUνeHj 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ⅇf_;0AHH<-@xezNx8u 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 D9);gD diff --git a/core/src/main/resources/bedrock/block_palette.1_21_0.nbt b/core/src/main/resources/bedrock/block_palette.1_21_0.nbt new file mode 100644 index 0000000000000000000000000000000000000000..57366fc57f4456dd195497c435f5e5c7b397075d GIT binary patch literal 177397 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�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

<8kA1=h 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 literal 0 HcmV?d00001 diff --git a/core/src/main/resources/bedrock/creative_items.1_20_40.json b/core/src/main/resources/bedrock/creative_items.1_20_40.json deleted file mode 100644 index b2c0bfe04..000000000 --- a/core/src/main/resources/bedrock/creative_items.1_20_40.json +++ /dev/null @@ -1,5787 +0,0 @@ -{ - "items": [ - { - "id": "minecraft:planks", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OnBsYW5rcwQJAG5hbWVfaGFzaA+7EGxL5oikAwoAbmV0d29ya19pZE/NqzcKBgBzdGF0ZXMICQB3b29kX3R5cGUDAG9hawADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:planks", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OnBsYW5rcwQJAG5hbWVfaGFzaA+7EGxL5oikAwoAbmV0d29ya19pZHl/r2YKBgBzdGF0ZXMICQB3b29kX3R5cGUGAHNwcnVjZQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:planks", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OnBsYW5rcwQJAG5hbWVfaGFzaA+7EGxL5oikAwoAbmV0d29ya19pZL6SoXYKBgBzdGF0ZXMICQB3b29kX3R5cGUFAGJpcmNoAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:planks", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OnBsYW5rcwQJAG5hbWVfaGFzaA+7EGxL5oikAwoAbmV0d29ya19pZKYD6L0KBgBzdGF0ZXMICQB3b29kX3R5cGUGAGp1bmdsZQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:planks", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OnBsYW5rcwQJAG5hbWVfaGFzaA+7EGxL5oikAwoAbmV0d29ya19pZJ0zTHYKBgBzdGF0ZXMICQB3b29kX3R5cGUGAGFjYWNpYQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:planks", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OnBsYW5rcwQJAG5hbWVfaGFzaA+7EGxL5oikAwoAbmV0d29ya19pZOf6hVkKBgBzdGF0ZXMICQB3b29kX3R5cGUIAGRhcmtfb2FrAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:mangrove_planks", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX3BsYW5rcwQJAG5hbWVfaGFzaPvLtcEA0F8xAwoAbmV0d29ya19pZEvnlCYKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:cherry_planks", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9wbGFua3MECQBuYW1lX2hhc2hNIvVh/lVW7gMKAG5ldHdvcmtfaWQTXpRoCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:bamboo_planks", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19wbGFua3MECQBuYW1lX2hhc2gYnjNz7SCCjgMKAG5ldHdvcmtfaWTi8ySSCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:bamboo_mosaic", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19tb3NhaWMECQBuYW1lX2hhc2izSEgiMKOp/AMKAG5ldHdvcmtfaWQZ/p8xCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:crimson_planks", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fcGxhbmtzBAkAbmFtZV9oYXNoJc5IKqNXJnwDCgBuZXR3b3JrX2lkwtJDdQoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:warped_planks", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9wbGFua3MECQBuYW1lX2hhc2g3yGXEWhe6LgMKAG5ldHdvcmtfaWStTABvCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWSE4JosCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCwBjb2JibGVzdG9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWTUvV6XCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlEQBtb3NzeV9jb2JibGVzdG9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWT4opb2CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlBwBncmFuaXRlCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQAMQTVCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlBwBkaW9yaXRlCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQIbDOcCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCABhbmRlc2l0ZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWSZKhusCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCQBzYW5kc3RvbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWSp4zgCCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlDQByZWRfc2FuZHN0b25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRbqVHTCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCwBzdG9uZV9icmljawgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRr0ZT/CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlEQBtb3NzeV9zdG9uZV9icmljawgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRnLis3CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlBQBicmljawgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQNLzfSCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlDABuZXRoZXJfYnJpY2sIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQ5h0xwCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlEAByZWRfbmV0aGVyX2JyaWNrCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWS9J0B2CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCQBlbmRfYnJpY2sIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRPbkJeCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCgBwcmlzbWFyaW5lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:blackstone_wall", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmJsYWNrc3RvbmVfd2FsbAQJAG5hbWVfaGFzaMP8XppUSU1RAwoAbmV0d29ya19pZMbeBBsKBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:polished_blackstone_wall", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfd2FsbAQJAG5hbWVfaGFzaP6SwV08YwzAAwoAbmV0d29ya19pZAJLsz8KBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:polished_blackstone_brick_wall", - "block_state_b64": "CgAACAQAbmFtZSgAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tfd2FsbAQJAG5hbWVfaGFzaBBIDZbHxiEzAwoAbmV0d29ya19pZEbLV8cKBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:cobbled_deepslate_wall", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlX3dhbGwECQBuYW1lX2hhc2iECY5oKxeT+gMKAG5ldHdvcmtfaWRCnPrFCgYAc3RhdGVzCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:deepslate_tile_wall", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlX3dhbGwECQBuYW1lX2hhc2jz7N+PeuEXgQMKAG5ldHdvcmtfaWTqw4s4CgYAc3RhdGVzCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:polished_deepslate_wall", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZV93YWxsBAkAbmFtZV9oYXNoHxjTdj9pevMDCgBuZXR3b3JrX2lkIvBYYwoGAHN0YXRlcwgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:deepslate_brick_wall", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja193YWxsBAkAbmFtZV9oYXNoEs3EQrjroyEDCgBuZXR3b3JrX2lkwlrCGwoGAHN0YXRlcwgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:mud_brick_wall", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0Om11ZF9icmlja193YWxsBAkAbmFtZV9oYXNov9b98ATpUSwDCgBuZXR3b3JrX2lkH/1WZQoGAHN0YXRlcwgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:oak_fence", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0Om9ha19mZW5jZQQJAG5hbWVfaGFzaGEmid7AaCWRAwoAbmV0d29ya19pZDvPEXcKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:spruce_fence", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnNwcnVjZV9mZW5jZQQJAG5hbWVfaGFzaPQCm+aX1ZQeAwoAbmV0d29ya19pZD1QUEoKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:birch_fence", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmJpcmNoX2ZlbmNlBAkAbmFtZV9oYXNo6CJ2ATpANfgDCgBuZXR3b3JrX2lkmCUV2QoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:jungle_fence", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0Omp1bmdsZV9mZW5jZQQJAG5hbWVfaGFzaOX4cD9uAmsdAwoAbmV0d29ya19pZHz1VxkKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:acacia_fence", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmFjYWNpYV9mZW5jZQQJAG5hbWVfaGFzaGjn+RlKVDH6AwoAbmV0d29ya19pZNVGubwKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:dark_oak_fence", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmRhcmtfb2FrX2ZlbmNlBAkAbmFtZV9oYXNoGPj0gCgM0c0DCgBuZXR3b3JrX2lk2w+gEwoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:mangrove_fence", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0Om1hbmdyb3ZlX2ZlbmNlBAkAbmFtZV9oYXNowwAd7tPu9bsDCgBuZXR3b3JrX2lkKEcd0goGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:cherry_fence", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmNoZXJyeV9mZW5jZQQJAG5hbWVfaGFzaFmtUfHfTxcxAwoAbmV0d29ya19pZPCBxAIKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:bamboo_fence", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmJhbWJvb19mZW5jZQQJAG5hbWVfaGFzaCKRbxfXsfkiAwoAbmV0d29ya19pZJNXKFcKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:nether_brick_fence", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0Om5ldGhlcl9icmlja19mZW5jZQQJAG5hbWVfaGFzaA6030ngawxcAwoAbmV0d29ya19pZLnjLF4KBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:crimson_fence", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmNyaW1zb25fZmVuY2UECQBuYW1lX2hhc2jhUhKv1HGj9AMKAG5ldHdvcmtfaWR3OH3OCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:warped_fence", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OndhcnBlZF9mZW5jZQQJAG5hbWVfaGFzaJfb3/YuKmOWAwoAbmV0d29ya19pZCpaGC8KBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:fence_gate", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmZlbmNlX2dhdGUECQBuYW1lX2hhc2hTxpjEDmRzAwMKAG5ldHdvcmtfaWR+T9kTCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:spruce_fence_gate", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnNwcnVjZV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoanTVB84HRbkDCgBuZXR3b3JrX2lkEnw5egoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:birch_fence_gate", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmJpcmNoX2ZlbmNlX2dhdGUECQBuYW1lX2hhc2jmfPklI8azSwMKAG5ldHdvcmtfaWQL77/BCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:jungle_fence_gate", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0Omp1bmdsZV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNobYVQkfBomIcDCgBuZXR3b3JrX2lkA1zgtgoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:acacia_fence_gate", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmFjYWNpYV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoZnrLUx/XSekDCgBuZXR3b3JrX2lkHg/kTgoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:dark_oak_fence_gate", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OmRhcmtfb2FrX2ZlbmNlX2dhdGUECQBuYW1lX2hhc2j2PTvdJJHcVQMKAG5ldHdvcmtfaWTwjOCeCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:mangrove_fence_gate", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0Om1hbmdyb3ZlX2ZlbmNlX2dhdGUECQBuYW1lX2hhc2i/kOhBKiI/dAMKAG5ldHdvcmtfaWSfweCSCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:cherry_fence_gate", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmNoZXJyeV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoKWLgCk0z+PsDCgBuZXR3b3JrX2lk/9bTZQoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:bamboo_fence_gate", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmJhbWJvb19mZW5jZV9nYXRlBAkAbmFtZV9oYXNopH1JrUgwdIADCgBuZXR3b3JrX2lkzIpPywoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:crimson_fence_gate", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmNyaW1zb25fZmVuY2VfZ2F0ZQQJAG5hbWVfaGFzaHE3Gfd0Z2d2AwoAbmV0d29ya19pZDQzVbEKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQsAaW5fd2FsbF9iaXQAAQgAb3Blbl9iaXQAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:warped_fence_gate", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OndhcnBlZF9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoy0oIBjDIG4kDCgBuZXR3b3JrX2lkkf+/3QoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:normal_stone_stairs", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0Om5vcm1hbF9zdG9uZV9zdGFpcnMECQBuYW1lX2hhc2hAEktZZOkGIwMKAG5ldHdvcmtfaWQeH1ALCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:stone_stairs", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnN0b25lX3N0YWlycwQJAG5hbWVfaGFzaNRjqVC5GRVDAwoAbmV0d29ya19pZDcCv+MKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:mossy_cobblestone_stairs", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0Om1vc3N5X2NvYmJsZXN0b25lX3N0YWlycwQJAG5hbWVfaGFzaMVSTq5z9n1RAwoAbmV0d29ya19pZFIfrhkKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:oak_stairs", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0Om9ha19zdGFpcnMECQBuYW1lX2hhc2jk/HFzdXy0FQMKAG5ldHdvcmtfaWQJjyzBCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:spruce_stairs", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9zdGFpcnMECQBuYW1lX2hhc2iznygw7uBPBQMKAG5ldHdvcmtfaWTv+is3CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:birch_stairs", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX3N0YWlycwQJAG5hbWVfaGFzaPfhbL619a3GAwoAbmV0d29ya19pZFyPlHAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:jungle_stairs", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9zdGFpcnMECQBuYW1lX2hhc2jodJsHUbOVxQMKAG5ldHdvcmtfaWR0z5d4CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:acacia_stairs", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9zdGFpcnMECQBuYW1lX2hhc2h3x1NmD43IqQMKAG5ldHdvcmtfaWS7Jwz6CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:dark_oak_stairs", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX3N0YWlycwQJAG5hbWVfaGFzaMfwkbYPbNmAAwoAbmV0d29ya19pZCmBYKAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:mangrove_stairs", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX3N0YWlycwQJAG5hbWVfaGFzaNpUDY+uGMpyAwoAbmV0d29ya19pZChzUAsKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:cherry_stairs", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9zdGFpcnMECQBuYW1lX2hhc2jMtr0v9JY4zwMKAG5ldHdvcmtfaWRQwq31CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:bamboo_stairs", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19zdGFpcnMECQBuYW1lX2hhc2jFOzWL8PalKwMKAG5ldHdvcmtfaWTVPh42CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:bamboo_mosaic_stairs", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OmJhbWJvb19tb3NhaWNfc3RhaXJzBAkAbmFtZV9oYXNoNLPiveSHPaoDCgBuZXR3b3JrX2lk44PHjgoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:stone_brick_stairs", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OnN0b25lX2JyaWNrX3N0YWlycwQJAG5hbWVfaGFzaN6tQViRo5cwAwoAbmV0d29ya19pZDMyMgIKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:mossy_stone_brick_stairs", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0Om1vc3N5X3N0b25lX2JyaWNrX3N0YWlycwQJAG5hbWVfaGFzaIB/Zv5YBPuYAwoAbmV0d29ya19pZANTOsMKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:sandstone_stairs", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OnNhbmRzdG9uZV9zdGFpcnMECQBuYW1lX2hhc2hOyA0BoYUOPQMKAG5ldHdvcmtfaWSV/834CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:smooth_sandstone_stairs", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OnNtb290aF9zYW5kc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNoB+CuCd8Ruz8DCgBuZXR3b3JrX2lksR+m8QoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:red_sandstone_stairs", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNoPs0LpHPL24YDCgBuZXR3b3JrX2lkLYVt3woGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:smooth_red_sandstone_stairs", - "block_state_b64": "CgAACAQAbmFtZSUAbWluZWNyYWZ0OnNtb290aF9yZWRfc2FuZHN0b25lX3N0YWlycwQJAG5hbWVfaGFzaBvjtQv5pf+MAwoAbmV0d29ya19pZMHNND8KBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:granite_stairs", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmdyYW5pdGVfc3RhaXJzBAkAbmFtZV9oYXNoGzpvtoqKQjgDCgBuZXR3b3JrX2lkPkcB1goGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:polished_granite_stairs", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2dyYW5pdGVfc3RhaXJzBAkAbmFtZV9oYXNo3PvbSfEQklIDCgBuZXR3b3JrX2lkMmEm3AoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:diorite_stairs", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmRpb3JpdGVfc3RhaXJzBAkAbmFtZV9oYXNoi73T8VQuZmcDCgBuZXR3b3JrX2lk6i6nBQoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:polished_diorite_stairs", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2Rpb3JpdGVfc3RhaXJzBAkAbmFtZV9oYXNoFKRJd5Wk5L0DCgBuZXR3b3JrX2lkbt2ioAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:andesite_stairs", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmFuZGVzaXRlX3N0YWlycwQJAG5hbWVfaGFzaO5w2FKBw76EAwoAbmV0d29ya19pZKhXEgUKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:polished_andesite_stairs", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OnBvbGlzaGVkX2FuZGVzaXRlX3N0YWlycwQJAG5hbWVfaGFzaNcZZ/zmLInIAwoAbmV0d29ya19pZJTHrlEKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:brick_stairs", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmJyaWNrX3N0YWlycwQJAG5hbWVfaGFzaMyt+cRDk5O2AwoAbmV0d29ya19pZNeMh58KBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:nether_brick_stairs", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0Om5ldGhlcl9icmlja19zdGFpcnMECQBuYW1lX2hhc2jRqIoOXgifBAMKAG5ldHdvcmtfaWQDiw5yCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:red_nether_brick_stairs", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OnJlZF9uZXRoZXJfYnJpY2tfc3RhaXJzBAkAbmFtZV9oYXNogQvosSbcj7kDCgBuZXR3b3JrX2lkx2IMtAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:end_brick_stairs", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmVuZF9icmlja19zdGFpcnMECQBuYW1lX2hhc2hmlAk+QhsUsQMKAG5ldHdvcmtfaWTN7KFaCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:quartz_stairs", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnF1YXJ0el9zdGFpcnMECQBuYW1lX2hhc2hmvpvOqGi6egMKAG5ldHdvcmtfaWRmUTh7CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:smooth_quartz_stairs", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OnNtb290aF9xdWFydHpfc3RhaXJzBAkAbmFtZV9oYXNoNZZ9rX0qZOsDCgBuZXR3b3JrX2lkzsgQyQoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:purpur_stairs", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnB1cnB1cl9zdGFpcnMECQBuYW1lX2hhc2ifwDxeezXD7gMKAG5ldHdvcmtfaWTT+rxiCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:prismarine_stairs", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnByaXNtYXJpbmVfc3RhaXJzBAkAbmFtZV9oYXNooTHSZ+IrYtcDCgBuZXR3b3JrX2lkxTJfeAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:dark_prismarine_stairs", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmRhcmtfcHJpc21hcmluZV9zdGFpcnMECQBuYW1lX2hhc2hIciLmam4o4AMKAG5ldHdvcmtfaWTVu7TCCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:prismarine_bricks_stairs", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OnByaXNtYXJpbmVfYnJpY2tzX3N0YWlycwQJAG5hbWVfaGFzaNIjq1oBlZMMAwoAbmV0d29ya19pZGEFwLYKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:crimson_stairs", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fc3RhaXJzBAkAbmFtZV9oYXNoZJqIzCBpCq4DCgBuZXR3b3JrX2lktXE00AoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:warped_stairs", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9zdGFpcnMECQBuYW1lX2hhc2hOkY27jLD4RQMKAG5ldHdvcmtfaWQ+E5VrCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:blackstone_stairs", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmJsYWNrc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNokdoUb76p9McDCgBuZXR3b3JrX2lk5fWI5goGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:polished_blackstone_stairs", - "block_state_b64": "CgAACAQAbmFtZSQAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNolCFtFIE8MmADCgBuZXR3b3JrX2lkGTf7sgoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:polished_blackstone_brick_stairs", - "block_state_b64": "CgAACAQAbmFtZSoAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tfc3RhaXJzBAkAbmFtZV9oYXNonks6UlfpOmkDCgBuZXR3b3JrX2lkgYeOdAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:cut_copper_stairs", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmN1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNoHfoAXYq5G3MDCgBuZXR3b3JrX2lkeetf7woGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:exposed_cut_copper_stairs", - "block_state_b64": "CgAACAQAbmFtZSMAbWluZWNyYWZ0OmV4cG9zZWRfY3V0X2NvcHBlcl9zdGFpcnMECQBuYW1lX2hhc2howneQGtZ9cgMKAG5ldHdvcmtfaWSg73zdCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:weathered_cut_copper_stairs", - "block_state_b64": "CgAACAQAbmFtZSUAbWluZWNyYWZ0OndlYXRoZXJlZF9jdXRfY29wcGVyX3N0YWlycwQJAG5hbWVfaGFzaP+R5loXxrVgAwoAbmV0d29ya19pZOnbRf4KBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:oxidized_cut_copper_stairs", - "block_state_b64": "CgAACAQAbmFtZSQAbWluZWNyYWZ0Om94aWRpemVkX2N1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNo6Jeoq5rsPxsDCgBuZXR3b3JrX2lkmRjDnQoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:waxed_cut_copper_stairs", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OndheGVkX2N1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNoh07CQj0/SR8DCgBuZXR3b3JrX2lkmYqoqAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:waxed_exposed_cut_copper_stairs", - "block_state_b64": "CgAACAQAbmFtZSkAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY3V0X2NvcHBlcl9zdGFpcnMECQBuYW1lX2hhc2guVct1ilmxTwMKAG5ldHdvcmtfaWQgCPROCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:waxed_weathered_cut_copper_stairs", - "block_state_b64": "CgAACAQAbmFtZSsAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jdXRfY29wcGVyX3N0YWlycwQJAG5hbWVfaGFzaPXC8Sz/phCpAwoAbmV0d29ya19pZHlwHVsKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:waxed_oxidized_cut_copper_stairs", - "block_state_b64": "CgAACAQAbmFtZSoAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2N1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNoaqGdkuhxVZUDCgBuZXR3b3JrX2lkYQXzzgoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:cobbled_deepslate_stairs", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlX3N0YWlycwQJAG5hbWVfaGFzaPIfa+TpyJcIAwoAbmV0d29ya19pZJUvOYIKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:deepslate_tile_stairs", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlX3N0YWlycwQJAG5hbWVfaGFzaGFRFzB72mN2AwoAbmV0d29ya19pZJEOgIsKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:polished_deepslate_stairs", - "block_state_b64": "CgAACAQAbmFtZSMAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZV9zdGFpcnMECQBuYW1lX2hhc2iNCYxVik9sGAMKAG5ldHdvcmtfaWSRVPnYCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:deepslate_brick_stairs", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja19zdGFpcnMECQBuYW1lX2hhc2hIasOahEf83wMKAG5ldHdvcmtfaWQ1qEDCCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:mud_brick_stairs", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0Om11ZF9icmlja19zdGFpcnMECQBuYW1lX2hhc2gt3qxK1NWajAMKAG5ldHdvcmtfaWSm9N3MCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:wooden_door" - }, - { - "id": "minecraft:spruce_door" - }, - { - "id": "minecraft:birch_door" - }, - { - "id": "minecraft:jungle_door" - }, - { - "id": "minecraft:acacia_door" - }, - { - "id": "minecraft:dark_oak_door" - }, - { - "id": "minecraft:mangrove_door" - }, - { - "id": "minecraft:cherry_door" - }, - { - "id": "minecraft:bamboo_door" - }, - { - "id": "minecraft:iron_door" - }, - { - "id": "minecraft:crimson_door" - }, - { - "id": "minecraft:warped_door" - }, - { - "id": "minecraft:trapdoor", - "block_state_b64": "CgAACAQAbmFtZRIAbWluZWNyYWZ0OnRyYXBkb29yBAkAbmFtZV9oYXNotYiAJGtN0xADCgBuZXR3b3JrX2lkyTAWkAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:spruce_trapdoor", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OnNwcnVjZV90cmFwZG9vcgQJAG5hbWVfaGFzaOwlfbgBkUW4AwoAbmV0d29ya19pZPHy1K0KBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:birch_trapdoor", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmJpcmNoX3RyYXBkb29yBAkAbmFtZV9oYXNoSLtLweOLJ7wDCgBuZXR3b3JrX2lkeJWDfgoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:jungle_trapdoor", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0Omp1bmdsZV90cmFwZG9vcgQJAG5hbWVfaGFzaDP/TnM9wyCIAwoAbmV0d29ya19pZEy2fJoKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:acacia_trapdoor", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmFjYWNpYV90cmFwZG9vcgQJAG5hbWVfaGFzaMj8xi3vmEKOAwoAbmV0d29ya19pZOHj8E8KBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:dark_oak_trapdoor", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmRhcmtfb2FrX3RyYXBkb29yBAkAbmFtZV9oYXNomB2GGJQ2aOMDCgBuZXR3b3JrX2lko5ZHTwoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:mangrove_trapdoor", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0Om1hbmdyb3ZlX3RyYXBkb29yBAkAbmFtZV9oYXNooV3kQsQUUmkDCgBuZXR3b3JrX2lkkF/mxAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:cherry_trapdoor", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmNoZXJyeV90cmFwZG9vcgQJAG5hbWVfaGFzaH/PefpfdHgtAwoAbmV0d29ya19pZOA7eNgKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:bamboo_trapdoor", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmJhbWJvb190cmFwZG9vcgQJAG5hbWVfaGFzaJrEOpsTwtKCAwoAbmV0d29ya19pZLvbPz8KBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:iron_trapdoor", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0Omlyb25fdHJhcGRvb3IECQBuYW1lX2hhc2gwA+IumsEiGQMKAG5ldHdvcmtfaWTvSVl/CgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAEPAHVwc2lkZV9kb3duX2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:crimson_trapdoor", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNyaW1zb25fdHJhcGRvb3IECQBuYW1lX2hhc2jHXufTnwUkYgMKAG5ldHdvcmtfaWQLjMYVCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAEPAHVwc2lkZV9kb3duX2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:warped_trapdoor", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OndhcnBlZF90cmFwZG9vcgQJAG5hbWVfaGFzaA20wG/+vkd6AwoAbmV0d29ya19pZHKR/hYKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:iron_bars", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0Omlyb25fYmFycwQJAG5hbWVfaGFzaPuefWSNAe56AwoAbmV0d29ya19pZN2LB5IKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:glass", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OmdsYXNzBAkAbmFtZV9oYXNowGJByfWff6gDCgBuZXR3b3JrX2lk0hdLNwoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:white_stained_glass", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OndoaXRlX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2iHubqoMbu9fAMKAG5ldHdvcmtfaWRndBrUCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:light_gray_stained_glass", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaKKa+LrRsHQhAwoAbmV0d29ya19pZEv2giYKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:gray_stained_glass", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmdyYXlfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaIETy7Y/HZREAwoAbmV0d29ya19pZDomVrUKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:black_stained_glass", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OmJsYWNrX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2iV6BCwpfDMmwMKAG5ldHdvcmtfaWSV7doJCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:brown_stained_glass", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OmJyb3duX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2igsEiq5np8JgMKAG5ldHdvcmtfaWRMzE/lCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:red_stained_glass", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnJlZF9zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNoCa2J12/lQoIDCgBuZXR3b3JrX2lk283lWAoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:orange_stained_glass", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0Om9yYW5nZV9zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNozgjAuvzhxGsDCgBuZXR3b3JrX2lkW5CkhQoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:yellow_stained_glass", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OnllbGxvd19zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNo7EbHMd5WVugDCgBuZXR3b3JrX2lkkdDyXQoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:lime_stained_glass", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmxpbWVfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaBtZA1nZtwcFAwoAbmV0d29ya19pZDxX85UKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:green_stained_glass", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OmdyZWVuX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2h91ptDgbehWwMKAG5ldHdvcmtfaWTlDhnECgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:cyan_stained_glass", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmN5YW5fc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaBkIYQ8nQLqbAwoAbmV0d29ya19pZOL1lHsKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:light_blue_stained_glass", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaLt05n1G0fiSAwoAbmV0d29ya19pZNbwulIKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:blue_stained_glass", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmJsdWVfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaPhLocSfzduRAwoAbmV0d29ya19pZENsjFwKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:purple_stained_glass", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OnB1cnBsZV9zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNoJk0DhRO0szUDCgBuZXR3b3JrX2lkD98ZxgoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:magenta_stained_glass", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0Om1hZ2VudGFfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaFEDeFiJj3zSAwoAbmV0d29ya19pZG+iFRoKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:pink_stained_glass", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OnBpbmtfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaDijTX87ywxhAwoAbmV0d29ya19pZKdEricKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:tinted_glass", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnRpbnRlZF9nbGFzcwQJAG5hbWVfaGFzaAFZWSamk6KdAwoAbmV0d29ya19pZGSvWX8KBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:glass_pane", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmdsYXNzX3BhbmUECQBuYW1lX2hhc2gRSBHwNMQ4gQMKAG5ldHdvcmtfaWRGwixuCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:white_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OndoaXRlX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaHgxQmgJVtRrAwoAbmV0d29ya19pZBEr/DYKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:light_gray_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZScAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNon0aQw9lNkSEDCgBuZXR3b3JrX2lk9dp5VgoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:gray_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OmdyYXlfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNors74IIw+2MMDCgBuZXR3b3JrX2lkmrGO5woGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:black_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OmJsYWNrX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaOK/5ZRRd+M1AwoAbmV0d29ya19pZDv++oQKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:brown_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OmJyb3duX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaLHeGJyRFTIWAwoAbmV0d29ya19pZMz9L0wKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:red_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OnJlZF9zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2gGr4x6JheAywMKAG5ldHdvcmtfaWQBjCTmCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:orange_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSMAbWluZWNyYWZ0Om9yYW5nZV9zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2hbHxPD2gEbEAMKAG5ldHdvcmtfaWSt/7a5CgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:yellow_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSMAbWluZWNyYWZ0OnllbGxvd19zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2g9tl4aOCyZBwMKAG5ldHdvcmtfaWTXRAS7CgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:lime_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OmxpbWVfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNo3CtUyLwoGegDCgBuZXR3b3JrX2lkYJDnggoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:green_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OmdyZWVuX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaJo6YP7IMy9SAwoAbmV0d29ya19pZHOnixoKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:cyan_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OmN5YW5fc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNoti97c6QrbLQDCgBuZXR3b3JrX2lkUqFUeQoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:light_blue_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZScAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNovDg/gQle104DCgBuZXR3b3JrX2lkFuy4MQoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:blue_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OmJsdWVfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNoGc57tiexbQMDCgBuZXR3b3JrX2lk1eBLUAoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:purple_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSMAbWluZWNyYWZ0OnB1cnBsZV9zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2hDJHYdd0FdfQMKAG5ldHdvcmtfaWSNsdK5CgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:magenta_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSQAbWluZWNyYWZ0Om1hZ2VudGFfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNo3pcOw5bs5XoDCgBuZXR3b3JrX2lkVbOR7AoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:pink_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OnBpbmtfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNoWRhSACMWgswDCgBuZXR3b3JrX2lkIR92xwoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:ladder", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OmxhZGRlcgQJAG5hbWVfaGFzaKBhqheJVOz+AwoAbmV0d29ya19pZCgvzlsKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:scaffolding", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OnNjYWZmb2xkaW5nBAkAbmFtZV9oYXNoYrkevrqcljwDCgBuZXR3b3JrX2lkD13mlAoGAHN0YXRlcwMJAHN0YWJpbGl0eQAAAAABDwBzdGFiaWxpdHlfY2hlY2sAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWTkNl0JCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQwAc21vb3RoX3N0b25lAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:stone_block_slab4", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkQJoxlgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNAUAc3RvbmUAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWRHh04KCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQsAY29iYmxlc3RvbmUAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkVRZB+woGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhEAbW9zc3lfY29iYmxlc3RvbmUAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:wooden_slab", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Ondvb2Rlbl9zbGFiBAkAbmFtZV9oYXNoBVBkRBCCh4MDCgBuZXR3b3JrX2lkBaobgAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20ICQB3b29kX3R5cGUDAG9hawADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:wooden_slab", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Ondvb2Rlbl9zbGFiBAkAbmFtZV9oYXNoBVBkRBCCh4MDCgBuZXR3b3JrX2lkhz9TeQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20ICQB3b29kX3R5cGUGAHNwcnVjZQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:wooden_slab", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Ondvb2Rlbl9zbGFiBAkAbmFtZV9oYXNoBVBkRBCCh4MDCgBuZXR3b3JrX2lk3HkwowoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20ICQB3b29kX3R5cGUFAGJpcmNoAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:wooden_slab", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Ondvb2Rlbl9zbGFiBAkAbmFtZV9oYXNoBVBkRBCCh4MDCgBuZXR3b3JrX2lkDIBqVQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20ICQB3b29kX3R5cGUGAGp1bmdsZQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:wooden_slab", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Ondvb2Rlbl9zbGFiBAkAbmFtZV9oYXNoBVBkRBCCh4MDCgBuZXR3b3JrX2lkL5hFYAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20ICQB3b29kX3R5cGUGAGFjYWNpYQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:wooden_slab", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Ondvb2Rlbl9zbGFiBAkAbmFtZV9oYXNoBVBkRBCCh4MDCgBuZXR3b3JrX2lkKRUHSQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20ICQB3b29kX3R5cGUIAGRhcmtfb2FrAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:mangrove_slab", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0Om1hbmdyb3ZlX3NsYWIECQBuYW1lX2hhc2jYCcmhJPeNMwMKAG5ldHdvcmtfaWQx6U1yCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:cherry_slab", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmNoZXJyeV9zbGFiBAkAbmFtZV9oYXNoTt0MmVn/mqoDCgBuZXR3b3JrX2lk2VVsZQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:bamboo_slab", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmJhbWJvb19zbGFiBAkAbmFtZV9oYXNoo1xuFqINeLYDCgBuZXR3b3JrX2lkVC+0twoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:bamboo_mosaic_slab", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmJhbWJvb19tb3NhaWNfc2xhYgQJAG5hbWVfaGFzaNbVRBZ/ChI3AwoAbmV0d29ya19pZOLZHFMKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWQSiInOCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQsAc3RvbmVfYnJpY2sAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:stone_block_slab4", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkoF89tgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNBEAbW9zc3lfc3RvbmVfYnJpY2sAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWSkoAE4CgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQkAc2FuZHN0b25lAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:stone_block_slab4", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkWfF7pgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNA0AY3V0X3NhbmRzdG9uZQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkbKRChAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAc21vb3RoX3NhbmRzdG9uZQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkBlrvqAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMg0AcmVkX3NhbmRzdG9uZQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:stone_block_slab4", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkRWFXuwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNBEAY3V0X3JlZF9zYW5kc3RvbmUAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkom8neQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxQAc21vb3RoX3JlZF9zYW5kc3RvbmUAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkd1ZaWgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMwcAZ3Jhbml0ZQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkISH4iwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxAAcG9saXNoZWRfZ3Jhbml0ZQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkqxEDMwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMwcAZGlvcml0ZQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkSYs86QoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxAAcG9saXNoZWRfZGlvcml0ZQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkq6BU6goGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMwgAYW5kZXNpdGUAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkTSXY8AoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxEAcG9saXNoZWRfYW5kZXNpdGUAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWQiYHKTCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQUAYnJpY2sAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWTk/0LfCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQwAbmV0aGVyX2JyaWNrAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lk/hXQ7AoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAcmVkX25ldGhlcl9icmljawADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkYJNxrwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMw8AZW5kX3N0b25lX2JyaWNrAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWRlj0/sCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQYAcXVhcnR6AAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:stone_block_slab4", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkMae+2goGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNA0Ac21vb3RoX3F1YXJ0egADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lk+kMHGAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMgYAcHVycHVyAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkKOSOMAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAcHJpc21hcmluZV9yb3VnaAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lk8igLCQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMg8AcHJpc21hcmluZV9kYXJrAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkSFbyEwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAcHJpc21hcmluZV9icmljawADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:crimson_slab", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmNyaW1zb25fc2xhYgQJAG5hbWVfaGFzaKZ+EfP0ZYOZAwoAbmV0d29ya19pZAxRUWAKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:warped_slab", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OndhcnBlZF9zbGFiBAkAbmFtZV9oYXNo/AT0e/Z9W7UDCgBuZXR3b3JrX2lk1yq11AoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:blackstone_slab", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmJsYWNrc3RvbmVfc2xhYgQJAG5hbWVfaGFzaF/DD4ZUlNgtAwoAbmV0d29ya19pZGy1DjwKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:polished_blackstone_slab", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfc2xhYgQJAG5hbWVfaGFzaDYnuUs86EWfAwoAbmV0d29ya19pZJj2bXIKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:polished_blackstone_brick_slab", - "block_state_b64": "CgAACAQAbmFtZSgAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tfc2xhYgQJAG5hbWVfaGFzaKySLqvHc4xXAwoAbmV0d29ya19pZOyWX94KBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:cut_copper_slab", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmN1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaDsNpb2qs4iBAwoAbmV0d29ya19pZOTm2nsKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:exposed_cut_copper_slab", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OmV4cG9zZWRfY3V0X2NvcHBlcl9zbGFiBAkAbmFtZV9oYXNoahQ5OwIQb7kDCgBuZXR3b3JrX2lkrUlZLwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:weathered_cut_copper_slab", - "block_state_b64": "CgAACAQAbmFtZSMAbWluZWNyYWZ0OndlYXRoZXJlZF9jdXRfY29wcGVyX3NsYWIECQBuYW1lX2hhc2hBIuGIOVVXogMKAG5ldHdvcmtfaWQgnaDiCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:oxidized_cut_copper_slab", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0Om94aWRpemVkX2N1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaOptj9ycfpaDAwoAbmV0d29ya19pZMzFSRgKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:waxed_cut_copper_slab", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OndheGVkX2N1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaAlx6DZOCTHzAwoAbmV0d29ya19pZFRBvDAKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:waxed_exposed_cut_copper_slab", - "block_state_b64": "CgAACAQAbmFtZScAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY3V0X2NvcHBlcl9zbGFiBAkAbmFtZV9oYXNo3KqS5OnhtRIDCgBuZXR3b3JrX2lkHTGcTgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:waxed_weathered_cut_copper_slab", - "block_state_b64": "CgAACAQAbmFtZSkAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jdXRfY29wcGVyX3NsYWIECQBuYW1lX2hhc2gzZ1oX0HCFtwMKAG5ldHdvcmtfaWSgJR+XCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:waxed_oxidized_cut_copper_slab", - "block_state_b64": "CgAACAQAbmFtZSgAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2N1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaMjjTnLu1KcqAwoAbmV0d29ya19pZIxsnFYKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:cobbled_deepslate_slab", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlX3NsYWIECQBuYW1lX2hhc2gwJIVWK1TM2QMKAG5ldHdvcmtfaWTYAoX5CgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:polished_deepslate_slab", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZV9zbGFiBAkAbmFtZV9oYXNoC/Adiz8k6RYDCgBuZXR3b3JrX2lkuFYMAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:deepslate_tile_slab", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlX3NsYWIECQBuYW1lX2hhc2hPydV6emzIXAMKAG5ldHdvcmtfaWQwlbFCCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:deepslate_brick_slab", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja19zbGFiBAkAbmFtZV9oYXNoSv62V7iw10UDCgBuZXR3b3JrX2lkWMoragoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:mud_brick_slab", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0Om11ZF9icmlja19zbGFiBAkAbmFtZV9oYXNoq/tGBQWkv08DCgBuZXR3b3JrX2lkl4nnMwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:brick_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmJyaWNrX2Jsb2NrBAkAbmFtZV9oYXNo5Qc2E005S3oDCgBuZXR3b3JrX2lkqeGWRgoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:chiseled_nether_bricks", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmNoaXNlbGVkX25ldGhlcl9icmlja3MECQBuYW1lX2hhc2g31SBPTcUK1QMKAG5ldHdvcmtfaWS8TJ+TCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:cracked_nether_bricks", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OmNyYWNrZWRfbmV0aGVyX2JyaWNrcwQJAG5hbWVfaGFzaAdC6eKzXT5tAwoAbmV0d29ya19pZIUSejwKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:quartz_bricks", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnF1YXJ0el9icmlja3MECQBuYW1lX2hhc2jSZO590dd8sAMKAG5ldHdvcmtfaWSc5xCLCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:stonebrick", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWQ5kni1CgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQcAZGVmYXVsdAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:stonebrick", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWTDw813CgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQUAbW9zc3kAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:stonebrick", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWSTvQGECgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQcAY3JhY2tlZAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:stonebrick", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWQIM0OwCgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQgAY2hpc2VsZWQAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:end_bricks", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmVuZF9icmlja3MECQBuYW1lX2hhc2hIUFfxNLZaFgMKAG5ldHdvcmtfaWQ/vDihCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:prismarine", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnByaXNtYXJpbmUECQBuYW1lX2hhc2jcnQCHi9CspQMKAG5ldHdvcmtfaWSH021WCgYAc3RhdGVzCBUAcHJpc21hcmluZV9ibG9ja190eXBlBgBicmlja3MAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:polished_blackstone_bricks", - "block_state_b64": "CgAACAQAbmFtZSQAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tzBAkAbmFtZV9oYXNoIHgsgIdzKXcDCgBuZXR3b3JrX2lkUw9b3woGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:cracked_polished_blackstone_bricks", - "block_state_b64": "CgAACAQAbmFtZSwAbWluZWNyYWZ0OmNyYWNrZWRfcG9saXNoZWRfYmxhY2tzdG9uZV9icmlja3MECQBuYW1lX2hhc2jQIO1GQDk80AMKAG5ldHdvcmtfaWQ3UlRYCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:gilded_blackstone", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmdpbGRlZF9ibGFja3N0b25lBAkAbmFtZV9oYXNoNoWt1ocG0HEDCgBuZXR3b3JrX2lktL8gUwoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:chiseled_polished_blackstone", - "block_state_b64": "CgAACAQAbmFtZSYAbWluZWNyYWZ0OmNoaXNlbGVkX3BvbGlzaGVkX2JsYWNrc3RvbmUECQBuYW1lX2hhc2gzFa+kEjCJgAMKAG5ldHdvcmtfaWR2NJX2CgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:deepslate_tiles", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlcwQJAG5hbWVfaGFzaGcLLx3NXAFvAwoAbmV0d29ya19pZI/G/xYKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:cracked_deepslate_tiles", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OmNyYWNrZWRfZGVlcHNsYXRlX3RpbGVzBAkAbmFtZV9oYXNo9zWgkFuMM1QDCgBuZXR3b3JrX2lkGwY6OgoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:deepslate_bricks", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja3MECQBuYW1lX2hhc2gucvFmPdZxigMKAG5ldHdvcmtfaWSH4HDPCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:cracked_deepslate_bricks", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OmNyYWNrZWRfZGVlcHNsYXRlX2JyaWNrcwQJAG5hbWVfaGFzaN40aqhh9WqHAwoAbmV0d29ya19pZO9GPBQKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:chiseled_deepslate", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmNoaXNlbGVkX2RlZXBzbGF0ZQQJAG5hbWVfaGFzaEU7/uRG8HSBAwoAbmV0d29ya19pZEqmI0EKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:cobblestone", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmNvYmJsZXN0b25lBAkAbmFtZV9oYXNoPoK7mGlSUz4DCgBuZXR3b3JrX2lkLm7RZwoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:mossy_cobblestone", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0Om1vc3N5X2NvYmJsZXN0b25lBAkAbmFtZV9oYXNoGJ67FCbkChMDCgBuZXR3b3JrX2lk/pYs1AoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:cobbled_deepslate", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlBAkAbmFtZV9oYXNoLUz9Y/ywmLwDCgBuZXR3b3JrX2lkNwzZ+AoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:smooth_stone", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnNtb290aF9zdG9uZQQJAG5hbWVfaGFzaMwf87/JaTNvAwoAbmV0d29ya19pZLkZICEKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:sandstone", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZB2wApMKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGUHAGRlZmF1bHQAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:sandstone", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZB7E+eQKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGULAGhlaXJvZ2x5cGhzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:sandstone", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZFQnDaEKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGUDAGN1dAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:sandstone", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZPO4A3IKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGUGAHNtb290aAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:red_sandstone", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWRhNYiFCgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlBwBkZWZhdWx0AAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:red_sandstone", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWTqXJr1CgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlCwBoZWlyb2dseXBocwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:red_sandstone", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWTQRGkFCgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlAwBjdXQAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:red_sandstone", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWTvAHWDCgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlBgBzbW9vdGgAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:coal_block", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmNvYWxfYmxvY2sECQBuYW1lX2hhc2jH8QQP3t5PiAMKAG5ldHdvcmtfaWRo+sR+CgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:dried_kelp_block", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmRyaWVkX2tlbHBfYmxvY2sECQBuYW1lX2hhc2iRoucexkrl8wMKAG5ldHdvcmtfaWQQCCrvCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:gold_block", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmdvbGRfYmxvY2sECQBuYW1lX2hhc2iYLshvjtXzFwMKAG5ldHdvcmtfaWTDJGBcCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:iron_block", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0Omlyb25fYmxvY2sECQBuYW1lX2hhc2jYINmJQbvV/gMKAG5ldHdvcmtfaWRf7AbICgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:copper_block", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmNvcHBlcl9ibG9jawQJAG5hbWVfaGFzaDVxnehsGaZ1AwoAbmV0d29ya19pZIiUodwKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:exposed_copper", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmV4cG9zZWRfY29wcGVyBAkAbmFtZV9oYXNoQH3Fukmu3CEDCgBuZXR3b3JrX2lk72jFIwoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:weathered_copper", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OndlYXRoZXJlZF9jb3BwZXIECQBuYW1lX2hhc2hJCQXbvobv+gMKAG5ldHdvcmtfaWQwM0lJCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:oxidized_copper", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0Om94aWRpemVkX2NvcHBlcgQJAG5hbWVfaGFzaMDtJqR0G5Y7AwoAbmV0d29ya19pZGjN8bUKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:waxed_copper", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OndheGVkX2NvcHBlcgQJAG5hbWVfaGFzaPF+FG6Eh5fsAwoAbmV0d29ya19pZIjtz/0KBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:waxed_exposed_copper", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY29wcGVyBAkAbmFtZV9oYXNoig8IOc+SCikDCgBuZXR3b3JrX2lklz8yWQoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:waxed_weathered_copper", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jb3BwZXIECQBuYW1lX2hhc2gjtPq8MOdvKgMKAG5ldHdvcmtfaWSQ9Ln9CgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:waxed_oxidized_copper", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OndheGVkX294aWRpemVkX2NvcHBlcgQJAG5hbWVfaGFzaMaORhsO+LzjAwoAbmV0d29ya19pZJhGfLEKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:cut_copper", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmN1dF9jb3BwZXIECQBuYW1lX2hhc2hAfN3NGax3eAMKAG5ldHdvcmtfaWTnFBtYCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:exposed_cut_copper", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmV4cG9zZWRfY3V0X2NvcHBlcgQJAG5hbWVfaGFzaA85G3yv/w6pAwoAbmV0d29ya19pZMQhr0QKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:weathered_cut_copper", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OndlYXRoZXJlZF9jdXRfY29wcGVyBAkAbmFtZV9oYXNoVgRV0fBaz88DCgBuZXR3b3JrX2lk/0cYugoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:oxidized_cut_copper", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0Om94aWRpemVkX2N1dF9jb3BwZXIECQBuYW1lX2hhc2iP8WmFWOkriwMKAG5ldHdvcmtfaWQPdce7CgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:waxed_cut_copper", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OndheGVkX2N1dF9jb3BwZXIECQBuYW1lX2hhc2jumiwOZIqv2AMKAG5ldHdvcmtfaWQvuxx9CgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:waxed_exposed_cut_copper", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY3V0X2NvcHBlcgQJAG5hbWVfaGFzaPE/OfK6IoVMAwoAbmV0d29ya19pZHy5HkcKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:waxed_weathered_cut_copper", - "block_state_b64": "CgAACAQAbmFtZSQAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jdXRfY29wcGVyBAkAbmFtZV9oYXNoCA1xDp11bnwDCgBuZXR3b3JrX2lkDyEDVQoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:waxed_oxidized_cut_copper", - "block_state_b64": "CgAACAQAbmFtZSMAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2N1dF9jb3BwZXIECQBuYW1lX2hhc2i1pZAsZYHLDAMKAG5ldHdvcmtfaWQ/wSkCCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:emerald_block", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmVtZXJhbGRfYmxvY2sECQBuYW1lX2hhc2hK6QunqJznNAMKAG5ldHdvcmtfaWRk5+otCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:diamond_block", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmRpYW1vbmRfYmxvY2sECQBuYW1lX2hhc2iGKrxuvkytFQMKAG5ldHdvcmtfaWQQeQZXCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:lapis_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmxhcGlzX2Jsb2NrBAkAbmFtZV9oYXNoDZ44xdb2zVoDCgBuZXR3b3JrX2lktVy0BAoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:raw_iron_block", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OnJhd19pcm9uX2Jsb2NrBAkAbmFtZV9oYXNo9XyzNIQXxvwDCgBuZXR3b3JrX2lknms1QAoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:raw_copper_block", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OnJhd19jb3BwZXJfYmxvY2sECQBuYW1lX2hhc2hw1KG0TNUGgwMKAG5ldHdvcmtfaWS1vGo/CgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:raw_gold_block", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OnJhd19nb2xkX2Jsb2NrBAkAbmFtZV9oYXNo6YuwuLwfOBwDCgBuZXR3b3JrX2lkLiQ5gQoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:quartz_block", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZEupC1AKBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQcAZGVmYXVsdAgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:quartz_block", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZM97+l0KBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQUAbGluZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:quartz_block", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZCbTfssKBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQgAY2hpc2VsZWQICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:quartz_block", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZJss8V0KBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQYAc21vb3RoCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:prismarine", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnByaXNtYXJpbmUECQBuYW1lX2hhc2jcnQCHi9CspQMKAG5ldHdvcmtfaWRFIsoGCgYAc3RhdGVzCBUAcHJpc21hcmluZV9ibG9ja190eXBlBwBkZWZhdWx0AAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:prismarine", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnByaXNtYXJpbmUECQBuYW1lX2hhc2jcnQCHi9CspQMKAG5ldHdvcmtfaWTDNWOvCgYAc3RhdGVzCBUAcHJpc21hcmluZV9ibG9ja190eXBlBABkYXJrAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:slime", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OnNsaW1lBAkAbmFtZV9oYXNoHJiEEJx+JlkDCgBuZXR3b3JrX2lkfgfVzAoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:honey_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmhvbmV5X2Jsb2NrBAkAbmFtZV9oYXNo9zLYSUlelywDCgBuZXR3b3JrX2lko+dyWgoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:honeycomb_block", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmhvbmV5Y29tYl9ibG9jawQJAG5hbWVfaGFzaASIPuOCYd1oAwoAbmV0d29ya19pZKys4n4KBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:hay_block", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmhheV9ibG9jawQJAG5hbWVfaGFzaIB2VxKxX8EpAwoAbmV0d29ya19pZKuQSloKBgBzdGF0ZXMDCgBkZXByZWNhdGVkAAAAAAgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:bone_block", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmJvbmVfYmxvY2sECQBuYW1lX2hhc2i4ZX576W9AWgMKAG5ldHdvcmtfaWTWGacQCgYAc3RhdGVzAwoAZGVwcmVjYXRlZAAAAAAICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:nether_brick", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0Om5ldGhlcl9icmljawQJAG5hbWVfaGFzaMxcRiheU+nXAwoAbmV0d29ya19pZMkmzloKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:red_nether_brick", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OnJlZF9uZXRoZXJfYnJpY2sECQBuYW1lX2hhc2j8pRO4LfoECAMKAG5ldHdvcmtfaWRpdF0YCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:netherite_block", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0Om5ldGhlcml0ZV9ibG9jawQJAG5hbWVfaGFzaMghh6Zib/ZKAwoAbmV0d29ya19pZIz0mq0KBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:lodestone", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmxvZGVzdG9uZQQJAG5hbWVfaGFzaJ2gmHOTlXv8AwoAbmV0d29ya19pZEfgB4wKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:white_wool", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OndoaXRlX3dvb2wECQBuYW1lX2hhc2jRWB7vaIEDiQMKAG5ldHdvcmtfaWSO8paQCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:light_gray_wool", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfd29vbAQJAG5hbWVfaGFzaOpdQ1a2v4b3AwoAbmV0d29ya19pZIqZCYEKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:gray_wool", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmdyYXlfd29vbAQJAG5hbWVfaGFzaLsc1Lp1xdIOAwoAbmV0d29ya19pZFUs+HgKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:black_wool", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmJsYWNrX3dvb2wECQBuYW1lX2hhc2hP2HC6o0X4HAMKAG5ldHdvcmtfaWRUbORcCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:brown_wool", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmJyb3duX3dvb2wECQBuYW1lX2hhc2ig5IW89PrREwMKAG5ldHdvcmtfaWRjT9j8CgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:red_wool", - "block_state_b64": "CgAACAQAbmFtZRIAbWluZWNyYWZ0OnJlZF93b29sBAkAbmFtZV9oYXNoY4TBDq+mFgUDCgBuZXR3b3JrX2lktn9lcAoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:orange_wool", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Om9yYW5nZV93b29sBAkAbmFtZV9oYXNoFstfrTZfSCgDCgBuZXR3b3JrX2lk+rqywwoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:yellow_wool", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OnllbGxvd193b29sBAkAbmFtZV9oYXNoTFyus2RHegcDCgBuZXR3b3JrX2lkkKBhXAoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:lime_wool", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmxpbWVfd29vbAQJAG5hbWVfaGFzaNVnnzKiMxmeAwoAbmV0d29ya19pZG9b32kKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:green_wool", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmdyZWVuX3dvb2wECQBuYW1lX2hhc2i3mElRYHIcSQMKAG5ldHdvcmtfaWSssprwCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:cyan_wool", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmN5YW5fd29vbAQJAG5hbWVfaGFzaBNDfvHn8dqFAwoAbmV0d29ya19pZK0hAbgKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:light_blue_wool", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfd29vbAQJAG5hbWVfaGFzaLWFAUfyxFPNAwoAbmV0d29ya19pZL2oEugKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:blue_wool", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmJsdWVfd29vbAQJAG5hbWVfaGFzaLjHyxxbTWCLAwoAbmV0d29ya19pZPaLdFQKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:purple_wool", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OnB1cnBsZV93b29sBAkAbmFtZV9oYXNojvFtqzjAf/4DCgBuZXR3b3JrX2lklqASNQoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:magenta_wool", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0Om1hZ2VudGFfd29vbAQJAG5hbWVfaGFzaGuOHvf+Pd4yAwoAbmV0d29ya19pZI4UoDQKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:pink_wool", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OnBpbmtfd29vbAQJAG5hbWVfaGFzaPiVA2pFeoFLAwoAbmV0d29ya19pZOZRO6oKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:white_carpet", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OndoaXRlX2NhcnBldAQJAG5hbWVfaGFzaNeMHTI1fWPXAwoAbmV0d29ya19pZEahDFcKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:light_gray_carpet", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY2FycGV0BAkAbmFtZV9oYXNoHPw6ArBAsP0DCgBuZXR3b3JrX2lkQoAeUAoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:gray_carpet", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmdyYXlfY2FycGV0BAkAbmFtZV9oYXNoZVR0OI+1VRADCgBuZXR3b3JrX2lkETF4WwoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:black_carpet", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmJsYWNrX2NhcnBldAQJAG5hbWVfaGFzaOk7LP9NptyhAwoAbmV0d29ya19pZFjmXtIKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:brown_carpet", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmJyb3duX2NhcnBldAQJAG5hbWVfaGFzaNaXFyOsAvIvAwoAbmV0d29ya19pZHPjFuoKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:red_carpet", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9jYXJwZXQECQBuYW1lX2hhc2i9eSKBf6SO3wMKAG5ldHdvcmtfaWQuhI/KCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:orange_carpet", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0Om9yYW5nZV9jYXJwZXQECQBuYW1lX2hhc2hIUkO4HlAdygMKAG5ldHdvcmtfaWSyKV9OCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:yellow_carpet", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnllbGxvd19jYXJwZXQECQBuYW1lX2hhc2hSDKX3scCamwMKAG5ldHdvcmtfaWT8nq+ECgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:lime_carpet", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmxpbWVfY2FycGV0BAkAbmFtZV9oYXNo+6KFOpzsib4DCgBuZXR3b3JrX2lkT+DS4woGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:green_carpet", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmdyZWVuX2NhcnBldAQJAG5hbWVfaGFzaCHPMP9ltqFJAwoAbmV0d29ya19pZBgwAvAKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:cyan_carpet", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmN5YW5fY2FycGV0BAkAbmFtZV9oYXNobXf62dQBJj8DCgBuZXR3b3JrX2lkKVppLgoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:light_blue_carpet", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY2FycGV0BAkAbmFtZV9oYXNo20l4oktdZ3sDCgBuZXR3b3JrX2lkjdeMiwoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:blue_carpet", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmJsdWVfY2FycGV0BAkAbmFtZV9oYXNo3p3lsW0eQwsDCgBuZXR3b3JrX2lkAovdPQoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:purple_carpet", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnB1cnBsZV9jYXJwZXQECQBuYW1lX2hhc2jwIA9pW/qp7QMKAG5ldHdvcmtfaWTqJqhjCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:magenta_carpet", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0Om1hZ2VudGFfY2FycGV0BAkAbmFtZV9oYXNoFXT36YNNZhMDCgBuZXR3b3JrX2lk+tqsGAoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:pink_carpet", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OnBpbmtfY2FycGV0BAkAbmFtZV9oYXNoHll72oqk+OoDCgBuZXR3b3JrX2lkrnBYDwoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:white_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OndoaXRlX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaFUk9iXVjwV8AwoAbmV0d29ya19pZJPZY8AKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:light_gray_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZSQAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNo7EUk30hmUtYDCgBuZXR3b3JrX2lkh8jVIwoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:gray_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OmdyYXlfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoW77af6WihdwDCgBuZXR3b3JrX2lkSsqC1woGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:black_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OmJsYWNrX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaAfWYp0xtgcfAwoAbmV0d29ya19pZMWTC8EKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:brown_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OmJyb3duX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaB74EeiLO46XAwoAbmV0d29ya19pZEDHKqwKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:red_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OnJlZF9jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2gjFut6Z/VH1gMKAG5ldHdvcmtfaWSvcmwYCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:orange_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0Om9yYW5nZV9jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2gADDj2IJiw+gMKAG5ldHdvcmtfaWTHph0FCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:yellow_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OnllbGxvd19jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2iy6qKNn3ob5wMKAG5ldHdvcmtfaWQZAI39CgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:lime_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OmxpbWVfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNo4dYIPslbXPUDCgBuZXR3b3JrX2lk2O8X0AoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:green_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OmdyZWVuX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaM/c9x2aJh3HAwoAbmV0d29ya19pZA0VfBMKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:cyan_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OmN5YW5fY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNok+xKAe7XXjoDCgBuZXR3b3JrX2lkmkn6uwoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:light_blue_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZSQAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNogScpIQceyAEDCgBuZXR3b3JrX2lkOmVSbgoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:blue_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OmJsdWVfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoFp7mmeL86r0DCgBuZXR3b3JrX2lkS3b3RQoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:purple_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OnB1cnBsZV9jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2iYcVU04hoStwMKAG5ldHdvcmtfaWQXimEjCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:magenta_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0Om1hZ2VudGFfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoy/70q6VPsWgDCgBuZXR3b3JrX2lkf9mxQwoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:pink_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OnBpbmtfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoVikSAf8DwV0DCgBuZXR3b3JrX2lku2MivwoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:white_concrete", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OndoaXRlX2NvbmNyZXRlBAkAbmFtZV9oYXNo6zAp7lsLlvkDCgBuZXR3b3JrX2lk3MAYQAoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:light_gray_concrete", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY29uY3JldGUECQBuYW1lX2hhc2hEtet5wuDIKAMKAG5ldHdvcmtfaWQISs02CgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:gray_concrete", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmdyYXlfY29uY3JldGUECQBuYW1lX2hhc2j92INnb0a83AMKAG5ldHdvcmtfaWQj8RHwCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:black_concrete", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmJsYWNrX2NvbmNyZXRlBAkAbmFtZV9oYXNo2X7NDIQmZ70DCgBuZXR3b3JrX2lk2uiVDQoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:brown_concrete", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmJyb3duX2NvbmNyZXRlBAkAbmFtZV9oYXNoeka02BwXf6oDCgBuZXR3b3JrX2lkYf+xDQoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:red_concrete", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnJlZF9jb25jcmV0ZQQJAG5hbWVfaGFzaPWmNowLGubqAwoAbmV0d29ya19pZKwyx58KBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:orange_concrete", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0Om9yYW5nZV9jb25jcmV0ZQQJAG5hbWVfaGFzaAgE8XmaAi6+AwoAbmV0d29ya19pZMDQNz8KBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:yellow_concrete", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OnllbGxvd19jb25jcmV0ZQQJAG5hbWVfaGFzaE6ONfJPBd0+AwoAbmV0d29ya19pZMarutwKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:lime_concrete", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmxpbWVfY29uY3JldGUECQBuYW1lX2hhc2gnd8JW6wmJcAMKAG5ldHdvcmtfaWTd47aoCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:green_concrete", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmdyZWVuX2NvbmNyZXRlBAkAbmFtZV9oYXNokbFxRKchQZkDCgBuZXR3b3JrX2lkmhZWUgoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:cyan_concrete", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmN5YW5fY29uY3JldGUECQBuYW1lX2hhc2hFRrWJ33qj1wMKAG5ldHdvcmtfaWQbi5b8CgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:light_blue_concrete", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY29uY3JldGUECQBuYW1lX2hhc2gHAe0kl0SE4AMKAG5ldHdvcmtfaWRL/GbSCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:blue_concrete", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmJsdWVfY29uY3JldGUECQBuYW1lX2hhc2hiay301nnj1wMKAG5ldHdvcmtfaWRMvFXNCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:purple_concrete", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OnB1cnBsZV9jb25jcmV0ZQQJAG5hbWVfaGFzaHBHflsPIwdXAwoAbmV0d29ya19pZCyKA5gKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:magenta_concrete", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0Om1hZ2VudGFfY29uY3JldGUECQBuYW1lX2hhc2gN7LuB/OvdZAMKAG5ldHdvcmtfaWTc6ZOdCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:pink_concrete", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnBpbmtfY29uY3JldGUECQBuYW1lX2hhc2ii2G5F0u3SOAMKAG5ldHdvcmtfaWSszGgrCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:clay", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0OmNsYXkECQBuYW1lX2hhc2j/S6sKXRcpzwMKAG5ldHdvcmtfaWRmsb8nCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:hardened_clay", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmhhcmRlbmVkX2NsYXkECQBuYW1lX2hhc2jrnRwCJ0krJAMKAG5ldHdvcmtfaWRBCOrrCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:white_terracotta", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OndoaXRlX3RlcnJhY290dGEECQBuYW1lX2hhc2j3RSdgmnAIewMKAG5ldHdvcmtfaWSimKw+CgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:light_gray_terracotta", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OmxpZ2h0X2dyYXlfdGVycmFjb3R0YQQJAG5hbWVfaGFzaAz1Ri3wIxomAwoAbmV0d29ya19pZH5qgOcKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:gray_terracotta", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmdyYXlfdGVycmFjb3R0YQQJAG5hbWVfaGFzaAXdSLAaNZ9vAwoAbmV0d29ya19pZM1QDV0KBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:black_terracotta", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmJsYWNrX3RlcnJhY290dGEECQBuYW1lX2hhc2jxssdv5vlbpgMKAG5ldHdvcmtfaWRE3Ru/CgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:brown_terracotta", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmJyb3duX3RlcnJhY290dGEECQBuYW1lX2hhc2gG4kPenmOF9gMKAG5ldHdvcmtfaWQ/i0iNCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:red_terracotta", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OnJlZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNo7fX56HXFejEDCgBuZXR3b3JrX2lk8tTF8QoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:orange_terracotta", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0Om9yYW5nZV90ZXJyYWNvdHRhBAkAbmFtZV9oYXNo0Hjmql3sruMDCgBuZXR3b3JrX2lklmqmkAoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:yellow_terracotta", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnllbGxvd190ZXJyYWNvdHRhBAkAbmFtZV9oYXNoqkyKKrmA3VcDCgBuZXR3b3JrX2lkaM/orAoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:lime_terracotta", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmxpbWVfdGVycmFjb3R0YQQJAG5hbWVfaGFzaANjADFOF9v7AwoAbmV0d29ya19pZJt0XsgKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:green_terracotta", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmdyZWVuX3RlcnJhY290dGEECQBuYW1lX2hhc2j5Ybq36yYwRQMKAG5ldHdvcmtfaWQ8kGdHCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:cyan_terracotta", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmN5YW5fdGVycmFjb3R0YQQJAG5hbWVfaGFzaN09COzMuHwAAwoAbmV0d29ya19pZIWPCzoKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:light_blue_terracotta", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OmxpZ2h0X2JsdWVfdGVycmFjb3R0YQQJAG5hbWVfaGFzaOMytez7cOZiAwoAbmV0d29ya19pZFHK1UsKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:blue_terracotta", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmJsdWVfdGVycmFjb3R0YQQJAG5hbWVfaGFzaF6inyTK5RpAAwoAbmV0d29ya19pZF5mVZIKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:purple_terracotta", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnB1cnBsZV90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoKF7YG61yTbEDCgBuZXR3b3JrX2lkhtRDlwoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:magenta_terracotta", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0Om1hZ2VudGFfdGVycmFjb3R0YQQJAG5hbWVfaGFzaLWvtpAVtztyAwoAbmV0d29ya19pZN5SoakKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:pink_terracotta", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OnBpbmtfdGVycmFjb3R0YQQJAG5hbWVfaGFzaJ7mzvyzSQZTAwoAbmV0d29ya19pZDJWe4YKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:white_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OndoaXRlX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoiVzCdoHAJo0DCgBuZXR3b3JrX2lkIlj9AAoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:silver_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OnNpbHZlcl9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaAVsA0CnhzA4AwoAbmV0d29ya19pZPnxtJEKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:gray_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmdyYXlfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2jvLZt9u/lF/AMKAG5ldHdvcmtfaWQVU8eFCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:black_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OmJsYWNrX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoe8I4xAXbO5UDCgBuZXR3b3JrX2lk2Icb9AoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:brown_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OmJyb3duX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoSiNZOobbpjoDCgBuZXR3b3JrX2lkJy0jwgoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:red_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OnJlZF9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaBdWFGLmCLFVAwoAbmV0d29ya19pZMYBJSEKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:orange_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0Om9yYW5nZV9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaMyJMrnPr7szAwoAbmV0d29ya19pZN6+7TUKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:yellow_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OnllbGxvd19nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaN6NaIhf6m0uAwoAbmV0d29ya19pZKRHXeoKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:lime_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmxpbWVfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2iF3E68/rB2EAMKAG5ldHdvcmtfaWSP7qQWCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:green_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OmdyZWVuX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNow5mo8aQDFboDCgBuZXR3b3JrX2lkoF11kgoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:cyan_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmN5YW5fZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2gnNB+cCFRJhwMKAG5ldHdvcmtfaWT9buMtCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:light_blue_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSYAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2gladnCDBKCigMKAG5ldHdvcmtfaWS5CszFCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:blue_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmJsdWVfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2giOZK+2nB1igMKAG5ldHdvcmtfaWR+e22CCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:purple_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OnB1cnBsZV9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaIQU03txeAfHAwoAbmV0d29ya19pZLKbSE4KBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:magenta_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSMAbWluZWNyYWZ0Om1hZ2VudGFfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2i/SNqDJbfjMgMKAG5ldHdvcmtfaWQKf9UvCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:pink_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OnBpbmtfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2hik8DVt4g+twMKAG5ldHdvcmtfaWTKzav2CgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:purpur_block", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnB1cnB1cl9ibG9jawQJAG5hbWVfaGFzaAgLwnUZGlzsAwoAbmV0d29ya19pZLD8ox4KBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQcAZGVmYXVsdAgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:purpur_block", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnB1cnB1cl9ibG9jawQJAG5hbWVfaGFzaAgLwnUZGlzsAwoAbmV0d29ya19pZPSAFFsKBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQUAbGluZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:packed_mud", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnBhY2tlZF9tdWQECQBuYW1lX2hhc2gHOMa121h4FgMKAG5ldHdvcmtfaWTUb6LyCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:mud_bricks", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0Om11ZF9icmlja3MECQBuYW1lX2hhc2iDL/SVl/PewQMKAG5ldHdvcmtfaWSkBjaDCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:nether_wart_block", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0Om5ldGhlcl93YXJ0X2Jsb2NrBAkAbmFtZV9oYXNo9XGS4GNnlV4DCgBuZXR3b3JrX2lkh3apIgoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:warped_wart_block", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OndhcnBlZF93YXJ0X2Jsb2NrBAkAbmFtZV9oYXNo9IqDS9yUPJoDCgBuZXR3b3JrX2lkMpKAbAoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:shroomlight", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OnNocm9vbWxpZ2h0BAkAbmFtZV9oYXNoZHCHcHX/HYADCgBuZXR3b3JrX2lkLG2JiwoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:crimson_nylium", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fbnlsaXVtBAkAbmFtZV9oYXNoOr6DJYW2bFYDCgBuZXR3b3JrX2lkuWpRDgoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:warped_nylium", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9ueWxpdW0ECQBuYW1lX2hhc2g0Zf89cfr3rwMKAG5ldHdvcmtfaWSu/kekCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:netherrack", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0Om5ldGhlcnJhY2sECQBuYW1lX2hhc2i/r5ZyRsvPyQMKAG5ldHdvcmtfaWTAiTOACgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:basalt", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OmJhc2FsdAQJAG5hbWVfaGFzaH+UQO2yWodiAwoAbmV0d29ya19pZBPNSV4KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:polished_basalt", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OnBvbGlzaGVkX2Jhc2FsdAQJAG5hbWVfaGFzaMS+L0gMnRcBAwoAbmV0d29ya19pZF+/mHwKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:smooth_basalt", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnNtb290aF9iYXNhbHQECQBuYW1lX2hhc2jKPUdz89kuNAMKAG5ldHdvcmtfaWTkb/oVCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:soul_soil", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OnNvdWxfc29pbAQJAG5hbWVfaGFzaC1/87ccutuTAwoAbmV0d29ya19pZKc63SMKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:dirt", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0OmRpcnQECQBuYW1lX2hhc2hXp6jnXAe+kQMKAG5ldHdvcmtfaWQmkQtoCgYAc3RhdGVzCAkAZGlydF90eXBlBgBub3JtYWwAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:dirt", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0OmRpcnQECQBuYW1lX2hhc2hXp6jnXAe+kQMKAG5ldHdvcmtfaWQId9pLCgYAc3RhdGVzCAkAZGlydF90eXBlBgBjb2Fyc2UAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:farmland", - "block_state_b64": "CgAACAQAbmFtZRIAbWluZWNyYWZ0OmZhcm1sYW5kBAkAbmFtZV9oYXNoxyQ5ag7LolADCgBuZXR3b3JrX2lkX618FQoGAHN0YXRlcwMSAG1vaXN0dXJpemVkX2Ftb3VudAAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:grass", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OmdyYXNzBAkAbmFtZV9oYXNosppASPWFlsUDCgBuZXR3b3JrX2lkhLLQkQoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:grass_path", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmdyYXNzX3BhdGgECQBuYW1lX2hhc2i0/KZV8Qsy+gMKAG5ldHdvcmtfaWT7CcdzCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:podzol", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OnBvZHpvbAQJAG5hbWVfaGFzaBzqokRjH4Z1AwoAbmV0d29ya19pZPPS/GUKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:mycelium", - "block_state_b64": "CgAACAQAbmFtZRIAbWluZWNyYWZ0Om15Y2VsaXVtBAkAbmFtZV9oYXNojTN09cKickIDCgBuZXR3b3JrX2lkLNPxXQoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:mud", - "block_state_b64": "CgAACAQAbmFtZQ0AbWluZWNyYWZ0Om11ZAQJAG5hbWVfaGFzaPb/3P+uLy+9AwoAbmV0d29ya19pZPIUlUkKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:stone", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OnN0b25lBAkAbmFtZV9oYXNoE3mqhJxzJycDCgBuZXR3b3JrX2lky8FPmgoGAHN0YXRlcwgKAHN0b25lX3R5cGUFAHN0b25lAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:iron_ore", - "block_state_b64": "CgAACAQAbmFtZRIAbWluZWNyYWZ0Omlyb25fb3JlBAkAbmFtZV9oYXNoS7BYtLnfx3gDCgBuZXR3b3JrX2lk3loneQoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:gold_ore", - "block_state_b64": "CgAACAQAbmFtZRIAbWluZWNyYWZ0OmdvbGRfb3JlBAkAbmFtZV9oYXNoC5Y+DUGXLC4DCgBuZXR3b3JrX2lkNhvMfwoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:diamond_ore", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmRpYW1vbmRfb3JlBAkAbmFtZV9oYXNokUOJ2wZZrGQDCgBuZXR3b3JrX2lk/dChVAoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:lapis_ore", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmxhcGlzX29yZQQJAG5hbWVfaGFzaMrmrUrSzb7qAwoAbmV0d29ya19pZMg+qK4KBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:redstone_ore", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnJlZHN0b25lX29yZQQJAG5hbWVfaGFzaFHVnp8Wc4JbAwoAbmV0d29ya19pZKDYvQoKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:coal_ore", - "block_state_b64": "CgAACAQAbmFtZRIAbWluZWNyYWZ0OmNvYWxfb3JlBAkAbmFtZV9oYXNo1OjA+Iuy51oDCgBuZXR3b3JrX2lk+R/aKAoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:copper_ore", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmNvcHBlcl9vcmUECQBuYW1lX2hhc2iSZduSntOzOwMKAG5ldHdvcmtfaWQtIuCnCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:emerald_ore", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmVtZXJhbGRfb3JlBAkAbmFtZV9oYXNoJTovr+VgINsDCgBuZXR3b3JrX2lknbkqCgoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:quartz_ore", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnF1YXJ0el9vcmUECQBuYW1lX2hhc2g0yNHLMK9TaQMKAG5ldHdvcmtfaWSzN7nzCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:nether_gold_ore", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0Om5ldGhlcl9nb2xkX29yZQQJAG5hbWVfaGFzaEJZ7segIBgBAwoAbmV0d29ya19pZNI9pDgKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:ancient_debris", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmFuY2llbnRfZGVicmlzBAkAbmFtZV9oYXNoNrbxMc9AwKcDCgBuZXR3b3JrX2lkrSNjEAoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:deepslate_iron_ore", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmRlZXBzbGF0ZV9pcm9uX29yZQQJAG5hbWVfaGFzaB/fDL9pgvXXAwoAbmV0d29ya19pZFA0bz4KBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:deepslate_gold_ore", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmRlZXBzbGF0ZV9nb2xkX29yZQQJAG5hbWVfaGFzaF9G7WYhKFinAwoAbmV0d29ya19pZHQTfBUKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:deepslate_diamond_ore", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OmRlZXBzbGF0ZV9kaWFtb25kX29yZQQJAG5hbWVfaGFzaEUH5USh+iD3AwoAbmV0d29ya19pZHP6VzAKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:deepslate_lapis_ore", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OmRlZXBzbGF0ZV9sYXBpc19vcmUECQBuYW1lX2hhc2j+yFxU/KZs1gMKAG5ldHdvcmtfaWRKINzICgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:deepslate_redstone_ore", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmRlZXBzbGF0ZV9yZWRzdG9uZV9vcmUECQBuYW1lX2hhc2iVgM3wWWD6ugMKAG5ldHdvcmtfaWReBdYRCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:deepslate_emerald_ore", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OmRlZXBzbGF0ZV9lbWVyYWxkX29yZQQJAG5hbWVfaGFzaNlfo5HTwS6wAwoAbmV0d29ya19pZNeie6sKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:deepslate_coal_ore", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmRlZXBzbGF0ZV9jb2FsX29yZQQJAG5hbWVfaGFzaIjikmcbRrPPAwoAbmV0d29ya19pZD9TiygKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:deepslate_copper_ore", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OmRlZXBzbGF0ZV9jb3BwZXJfb3JlBAkAbmFtZV9oYXNottjV4Ev5LAQDCgBuZXR3b3JrX2lkP23rgQoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:gravel", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OmdyYXZlbAQJAG5hbWVfaGFzaOFxz8XJd2r/AwoAbmV0d29ya19pZBpfI1sKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:stone", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OnN0b25lBAkAbmFtZV9oYXNoE3mqhJxzJycDCgBuZXR3b3JrX2lkbtgs0goGAHN0YXRlcwgKAHN0b25lX3R5cGUHAGdyYW5pdGUAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:stone", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OnN0b25lBAkAbmFtZV9oYXNoE3mqhJxzJycDCgBuZXR3b3JrX2lk3sDePAoGAHN0YXRlcwgKAHN0b25lX3R5cGUHAGRpb3JpdGUAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:stone", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OnN0b25lBAkAbmFtZV9oYXNoE3mqhJxzJycDCgBuZXR3b3JrX2lkYG+0YwoGAHN0YXRlcwgKAHN0b25lX3R5cGUIAGFuZGVzaXRlAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:blackstone", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmJsYWNrc3RvbmUECQBuYW1lX2hhc2iMFYziD80D6QMKAG5ldHdvcmtfaWSrUryHCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:deepslate", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmRlZXBzbGF0ZQQJAG5hbWVfaGFzaKX5pAblxz8TAwoAbmV0d29ya19pZOJoQjsKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:stone", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OnN0b25lBAkAbmFtZV9oYXNoE3mqhJxzJycDCgBuZXR3b3JrX2lkREbyhwoGAHN0YXRlcwgKAHN0b25lX3R5cGUOAGdyYW5pdGVfc21vb3RoAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:stone", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OnN0b25lBAkAbmFtZV9oYXNoE3mqhJxzJycDCgBuZXR3b3JrX2lk/EZ3UwoGAHN0YXRlcwgKAHN0b25lX3R5cGUOAGRpb3JpdGVfc21vb3RoAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:stone", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OnN0b25lBAkAbmFtZV9oYXNoE3mqhJxzJycDCgBuZXR3b3JrX2lkmjeVIwoGAHN0YXRlcwgKAHN0b25lX3R5cGUPAGFuZGVzaXRlX3Ntb290aAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:polished_blackstone", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmUECQBuYW1lX2hhc2jT9fHCl6vWQQMKAG5ldHdvcmtfaWR/Ho6oCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:polished_deepslate", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZQQJAG5hbWVfaGFzaHC1edoaWF3uAwoAbmV0d29ya19pZCPeQsEKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:sand", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0OnNhbmQECQBuYW1lX2hhc2i6lthXXbAyWAMKAG5ldHdvcmtfaWTekU/mCgYAc3RhdGVzCAkAc2FuZF90eXBlBgBub3JtYWwAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:sand", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0OnNhbmQECQBuYW1lX2hhc2i6lthXXbAyWAMKAG5ldHdvcmtfaWSTgcqmCgYAc3RhdGVzCAkAc2FuZF90eXBlAwByZWQAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:cactus", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OmNhY3R1cwQJAG5hbWVfaGFzaCG9zL0N4wvGAwoAbmV0d29ya19pZDeCERAKBgBzdGF0ZXMDAwBhZ2UAAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:oak_log", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0Om9ha19sb2cECQBuYW1lX2hhc2ho6TS+K7PZFQMKAG5ldHdvcmtfaWQjfjoxCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:stripped_oak_log", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OnN0cmlwcGVkX29ha19sb2cECQBuYW1lX2hhc2h8dqh+OOHU4wMKAG5ldHdvcmtfaWSYKjdrCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:spruce_log", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnNwcnVjZV9sb2cECQBuYW1lX2hhc2hZ03qaLoF3WgMKAG5ldHdvcmtfaWRlFD8eCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:stripped_spruce_log", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX3NwcnVjZV9sb2cECQBuYW1lX2hhc2iNrhKjS5IyrgMKAG5ldHdvcmtfaWRQcEC3CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:birch_log", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmJpcmNoX2xvZwQJAG5hbWVfaGFzaBUzT3NxsZAnAwoAbmV0d29ya19pZBKN3VQKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:stripped_birch_log", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OnN0cmlwcGVkX2JpcmNoX2xvZwQJAG5hbWVfaGFzaCFKS4AeuSidAwoAbmV0d29ya19pZN0IONIKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:jungle_log", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0Omp1bmdsZV9sb2cECQBuYW1lX2hhc2gkwW0KNulqDgMKAG5ldHdvcmtfaWQaziU/CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:stripped_jungle_log", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2p1bmdsZV9sb2cECQBuYW1lX2hhc2hAwMsgOk02JAMKAG5ldHdvcmtfaWQvls0eCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:acacia_log", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmFjYWNpYV9sb2cECQBuYW1lX2hhc2iV48VpYhjoYQMKAG5ldHdvcmtfaWRxEqe0CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:stripped_acacia_log", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2FjYWNpYV9sb2cECQBuYW1lX2hhc2hJb0lQqnEqlgMKAG5ldHdvcmtfaWRg3IdRCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:dark_oak_log", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmRhcmtfb2FrX2xvZwQJAG5hbWVfaGFzaIWfVRd0XUo3AwoAbmV0d29ya19pZPMM7LYKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:stripped_dark_oak_log", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX2Rhcmtfb2FrX2xvZwQJAG5hbWVfaGFzaPFTdxRdPwkOAwoAbmV0d29ya19pZDIzenIKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:mangrove_log", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0Om1hbmdyb3ZlX2xvZwQJAG5hbWVfaGFzaHZe6DzPZBobAwoAbmV0d29ya19pZG6DuYkKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:stripped_mangrove_log", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX21hbmdyb3ZlX2xvZwQJAG5hbWVfaGFzaLqIBo4hwA//AwoAbmV0d29ya19pZPtRn7UKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:cherry_log", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmNoZXJyeV9sb2cECQBuYW1lX2hhc2hwFlaioppB1wMKAG5ldHdvcmtfaWS2sdXECgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:stripped_cherry_log", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2NoZXJyeV9sb2cECQBuYW1lX2hhc2i85H6G+WhXaAMKAG5ldHdvcmtfaWRjzoglCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:crimson_stem", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmNyaW1zb25fc3RlbQQJAG5hbWVfaGFzaM0FzfL0UTKZAwoAbmV0d29ya19pZKvzID0KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:stripped_crimson_stem", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX2NyaW1zb25fc3RlbQQJAG5hbWVfaGFzaDlA6nood57EAwoAbmV0d29ya19pZHrIqjIKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:warped_stem", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OndhcnBlZF9zdGVtBAkAbmFtZV9oYXNon7cKfPZxdrUDCgBuZXR3b3JrX2lkerWyMwoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:stripped_warped_stem", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX3dhcnBlZF9zdGVtBAkAbmFtZV9oYXNoEw+y0dDPSd8DCgBuZXR3b3JrX2lkIQ9vBAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWSYGFlqCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQACAkAd29vZF90eXBlAwBvYWsAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWSxnUzvCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQBCAkAd29vZF90eXBlAwBvYWsAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWToyw4RCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQACAkAd29vZF90eXBlBgBzcHJ1Y2UAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWTL0a3ZCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQBCAkAd29vZF90eXBlBgBzcHJ1Y2UAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWQV99vJCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQACAkAd29vZF90eXBlBQBiaXJjaAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWQYDJk1CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQBCAkAd29vZF90eXBlBQBiaXJjaAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWSfH48gCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQACAkAd29vZF90eXBlBgBqdW5nbGUAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWQ44auiCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQBCAkAd29vZF90eXBlBgBqdW5nbGUAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWSogpPYCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQACAkAd29vZF90eXBlBgBhY2FjaWEAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWSD7hT1CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQBCAkAd29vZF90eXBlBgBhY2FjaWEAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWQagb3gCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQACAkAd29vZF90eXBlCABkYXJrX29hawADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWQdnWU+CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQBCAkAd29vZF90eXBlCABkYXJrX29hawADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:mangrove_wood", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0Om1hbmdyb3ZlX3dvb2QECQBuYW1lX2hhc2iXVxG0JG2fVAMKAG5ldHdvcmtfaWTok1JCCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:stripped_mangrove_wood", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OnN0cmlwcGVkX21hbmdyb3ZlX3dvb2QECQBuYW1lX2hhc2h7CkbaBF7/WAMKAG5ldHdvcmtfaWQLAX88CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:cherry_wood", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmNoZXJyeV93b29kBAkAbmFtZV9oYXNoAW8srlmpBM8DCgBuZXR3b3JrX2lkEALMfAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AQwAc3RyaXBwZWRfYml0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:stripped_cherry_wood", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX2NoZXJyeV93b29kBAkAbmFtZV9oYXNo/e7KXv+CB38DCgBuZXR3b3JrX2lkg5aVtQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:crimson_hyphae", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25faHlwaGFlBAkAbmFtZV9oYXNouRmKmfSqEWADCgBuZXR3b3JrX2lk+Tm5rQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:stripped_crimson_hyphae", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OnN0cmlwcGVkX2NyaW1zb25faHlwaGFlBAkAbmFtZV9oYXNoFffwmABq4LUDCgBuZXR3b3JrX2lkZAlUbgoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:warped_hyphae", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9oeXBoYWUECQBuYW1lX2hhc2hn8plQUr6pmQMKAG5ldHdvcmtfaWRU2AIBCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:stripped_warped_hyphae", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OnN0cmlwcGVkX3dhcnBlZF9oeXBoYWUECQBuYW1lX2hhc2irKq+HYPSgjQMKAG5ldHdvcmtfaWSbrOPDCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:bamboo_block", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmJhbWJvb19ibG9jawQJAG5hbWVfaGFzaAbDeur6stIBAwoAbmV0d29ya19pZCJAwn0KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:stripped_bamboo_block", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX2JhbWJvb19ibG9jawQJAG5hbWVfaGFzaJpwytpZOZM9AwoAbmV0d29ya19pZKuRbNEKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:leaves", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OmxlYXZlcwQJAG5hbWVfaGFzaACPIsusW0mnAwoAbmV0d29ya19pZOmqtzMKBgBzdGF0ZXMIDQBvbGRfbGVhZl90eXBlAwBvYWsBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:leaves", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OmxlYXZlcwQJAG5hbWVfaGFzaACPIsusW0mnAwoAbmV0d29ya19pZFMVNEQKBgBzdGF0ZXMIDQBvbGRfbGVhZl90eXBlBgBzcHJ1Y2UBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:leaves", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OmxlYXZlcwQJAG5hbWVfaGFzaACPIsusW0mnAwoAbmV0d29ya19pZKCZEm8KBgBzdGF0ZXMIDQBvbGRfbGVhZl90eXBlBQBiaXJjaAEOAHBlcnNpc3RlbnRfYml0AAEKAHVwZGF0ZV9iaXQAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:leaves", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OmxlYXZlcwQJAG5hbWVfaGFzaACPIsusW0mnAwoAbmV0d29ya19pZABprGgKBgBzdGF0ZXMIDQBvbGRfbGVhZl90eXBlBgBqdW5nbGUBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:leaves2", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OmxlYXZlczIECQBuYW1lX2hhc2gy/bgrncY1ZAMKAG5ldHdvcmtfaWSFh3olCgYAc3RhdGVzCA0AbmV3X2xlYWZfdHlwZQYAYWNhY2lhAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:leaves2", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OmxlYXZlczIECQBuYW1lX2hhc2gy/bgrncY1ZAMKAG5ldHdvcmtfaWTvEAyeCgYAc3RhdGVzCA0AbmV3X2xlYWZfdHlwZQgAZGFya19vYWsBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:mangrove_leaves", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX2xlYXZlcwQJAG5hbWVfaGFzaKyI/dWvhEG8AwoAbmV0d29ya19pZPQxCZ8KBgBzdGF0ZXMBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:cherry_leaves", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9sZWF2ZXMECQBuYW1lX2hhc2giTs9ChhYBlQMKAG5ldHdvcmtfaWR8bPpwCgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:azalea_leaves", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmF6YWxlYV9sZWF2ZXMECQBuYW1lX2hhc2iXFhD57wFS7AMKAG5ldHdvcmtfaWTNB/9ECgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:azalea_leaves_flowered", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmF6YWxlYV9sZWF2ZXNfZmxvd2VyZWQECQBuYW1lX2hhc2gs8jxlS/pMrwMKAG5ldHdvcmtfaWQ7W4PyCgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:sapling", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWQmoOEvCgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUDAG9hawADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:sapling", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWQO8pAmCgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUGAHNwcnVjZQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:sapling", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWQDHhokCgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUFAGJpcmNoAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:sapling", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWTdQrcyCgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUGAGp1bmdsZQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:sapling", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWRCDffNCgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUGAGFjYWNpYQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:sapling", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWR0BRzPCgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUIAGRhcmtfb2FrAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:mangrove_propagule", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0Om1hbmdyb3ZlX3Byb3BhZ3VsZQQJAG5hbWVfaGFzaJGeox6hkfLFAwoAbmV0d29ya19pZAIpvpYKBgBzdGF0ZXMBBwBoYW5naW5nAAMPAHByb3BhZ3VsZV9zdGFnZQAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:cherry_sapling", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNoZXJyeV9zYXBsaW5nBAkAbmFtZV9oYXNoGrPpNMf1LtcDCgBuZXR3b3JrX2lkypakXQoGAHN0YXRlcwEHAGFnZV9iaXQAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:bee_nest", - "block_state_b64": "CgAACAQAbmFtZRIAbWluZWNyYWZ0OmJlZV9uZXN0BAkAbmFtZV9oYXNo2R2WBxUHEZIDCgBuZXR3b3JrX2lkiXWLEAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAADCwBob25leV9sZXZlbAAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:wheat_seeds" - }, - { - "id": "minecraft:pumpkin_seeds" - }, - { - "id": "minecraft:melon_seeds" - }, - { - "id": "minecraft:beetroot_seeds" - }, - { - "id": "minecraft:torchflower_seeds" - }, - { - "id": "minecraft:pitcher_pod" - }, - { - "id": "minecraft:wheat" - }, - { - "id": "minecraft:beetroot" - }, - { - "id": "minecraft:potato" - }, - { - "id": "minecraft:poisonous_potato" - }, - { - "id": "minecraft:carrot" - }, - { - "id": "minecraft:golden_carrot" - }, - { - "id": "minecraft:apple" - }, - { - "id": "minecraft:golden_apple" - }, - { - "id": "minecraft:enchanted_golden_apple" - }, - { - "id": "minecraft:melon_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Om1lbG9uX2Jsb2NrBAkAbmFtZV9oYXNoXxSm0iYpAx8DCgBuZXR3b3JrX2lkC9rqygoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:melon_slice" - }, - { - "id": "minecraft:glistering_melon_slice" - }, - { - "id": "minecraft:sweet_berries" - }, - { - "id": "minecraft:glow_berries" - }, - { - "id": "minecraft:pumpkin", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OnB1bXBraW4ECQBuYW1lX2hhc2gc8A3jaSzWbgMKAG5ldHdvcmtfaWRFGA+xCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:carved_pumpkin", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNhcnZlZF9wdW1wa2luBAkAbmFtZV9oYXNoPu1T0MJuG90DCgBuZXR3b3JrX2lkXNNn5QoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:lit_pumpkin", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmxpdF9wdW1wa2luBAkAbmFtZV9oYXNo7gWtEm2uPL0DCgBuZXR3b3JrX2lki8sU4AoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:honeycomb" - }, - { - "id": "minecraft:tallgrass", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OnRhbGxncmFzcwQJAG5hbWVfaGFzaC3PXpAXXYswAwoAbmV0d29ya19pZOh33DMKBgBzdGF0ZXMIDwB0YWxsX2dyYXNzX3R5cGUEAGZlcm4AAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:double_plant", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZMx1sfgKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQQAZmVybgEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:tallgrass", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OnRhbGxncmFzcwQJAG5hbWVfaGFzaC3PXpAXXYswAwoAbmV0d29ya19pZErptfIKBgBzdGF0ZXMIDwB0YWxsX2dyYXNzX3R5cGUEAHRhbGwAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:double_plant", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZAbadmIKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQUAZ3Jhc3MBDwB1cHBlcl9ibG9ja19iaXQAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:nether_sprouts" - }, - { - "id": "minecraft:fire_coral", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmZpcmVfY29yYWwECQBuYW1lX2hhc2hOHyyECVQVJwMKAG5ldHdvcmtfaWS9vF0UCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:brain_coral", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmJyYWluX2NvcmFsBAkAbmFtZV9oYXNoRiWlLCwA2ycDCgBuZXR3b3JrX2lkrjAuhgoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:bubble_coral", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmJ1YmJsZV9jb3JhbAQJAG5hbWVfaGFzaJz6rWnl+v2qAwoAbmV0d29ya19pZImIWy0KBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:tube_coral", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnR1YmVfY29yYWwECQBuYW1lX2hhc2iYa8oO/tgk7wMKAG5ldHdvcmtfaWRTfND5CgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:horn_coral", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0Omhvcm5fY29yYWwECQBuYW1lX2hhc2iZnRHjZbnLPgMKAG5ldHdvcmtfaWR+GGp8CgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:dead_fire_coral", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmRlYWRfZmlyZV9jb3JhbAQJAG5hbWVfaGFzaEPU6tFy/latAwoAbmV0d29ya19pZNMa7V4KBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:dead_brain_coral", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmRlYWRfYnJhaW5fY29yYWwECQBuYW1lX2hhc2j5L6QJCISvzwMKAG5ldHdvcmtfaWQkKzeiCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:dead_bubble_coral", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmRlYWRfYnViYmxlX2NvcmFsBAkAbmFtZV9oYXNoSTOZ/8wpeNYDCgBuZXR3b3JrX2lka6w9DAoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:dead_tube_coral", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmRlYWRfdHViZV9jb3JhbAQJAG5hbWVfaGFzaJGjNWhlaIJeAwoAbmV0d29ya19pZO3Z0ygKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:dead_horn_coral", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmRlYWRfaG9ybl9jb3JhbAQJAG5hbWVfaGFzaJBkz3qt+g2cAwoAbmV0d29ya19pZBAN+eYKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:coral_fan", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmNvcmFsX2ZhbgQJAG5hbWVfaGFzaAFROjbTm8JzAwoAbmV0d29ya19pZOg7iS4KBgBzdGF0ZXMICwBjb3JhbF9jb2xvcgMAcmVkAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:coral_fan", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmNvcmFsX2ZhbgQJAG5hbWVfaGFzaAFROjbTm8JzAwoAbmV0d29ya19pZIDj8HMKBgBzdGF0ZXMICwBjb3JhbF9jb2xvcgQAcGluawMTAGNvcmFsX2Zhbl9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:coral_fan", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmNvcmFsX2ZhbgQJAG5hbWVfaGFzaAFROjbTm8JzAwoAbmV0d29ya19pZLCJP0kKBgBzdGF0ZXMICwBjb3JhbF9jb2xvcgYAcHVycGxlAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:coral_fan", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmNvcmFsX2ZhbgQJAG5hbWVfaGFzaAFROjbTm8JzAwoAbmV0d29ya19pZFz2ly4KBgBzdGF0ZXMICwBjb3JhbF9jb2xvcgQAYmx1ZQMTAGNvcmFsX2Zhbl9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:coral_fan", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmNvcmFsX2ZhbgQJAG5hbWVfaGFzaAFROjbTm8JzAwoAbmV0d29ya19pZE4TgnYKBgBzdGF0ZXMICwBjb3JhbF9jb2xvcgYAeWVsbG93AxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:coral_fan_dead", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNvcmFsX2Zhbl9kZWFkBAkAbmFtZV9oYXNo3kgokLV4uQIDCgBuZXR3b3JrX2lkdhLQzwoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yAwByZWQDEwBjb3JhbF9mYW5fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:coral_fan_dead", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNvcmFsX2Zhbl9kZWFkBAkAbmFtZV9oYXNo3kgokLV4uQIDCgBuZXR3b3JrX2lkSi6srQoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABwaW5rAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:coral_fan_dead", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNvcmFsX2Zhbl9kZWFkBAkAbmFtZV9oYXNo3kgokLV4uQIDCgBuZXR3b3JrX2lkGiGSzAoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgBwdXJwbGUDEwBjb3JhbF9mYW5fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:coral_fan_dead", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNvcmFsX2Zhbl9kZWFkBAkAbmFtZV9oYXNo3kgokLV4uQIDCgBuZXR3b3JrX2lkmvZKOgoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABibHVlAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:coral_fan_dead", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNvcmFsX2Zhbl9kZWFkBAkAbmFtZV9oYXNo3kgokLV4uQIDCgBuZXR3b3JrX2lknLw+4QoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgB5ZWxsb3cDEwBjb3JhbF9mYW5fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:crimson_roots", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmNyaW1zb25fcm9vdHMECQBuYW1lX2hhc2j1fWgQLViv5QMKAG5ldHdvcmtfaWRLh5DXCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:warped_roots", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OndhcnBlZF9yb290cwQJAG5hbWVfaGFzaBc3WvbJOLlkAwoAbmV0d29ya19pZNLgDnAKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:yellow_flower", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnllbGxvd19mbG93ZXIECQBuYW1lX2hhc2jWbU1pF0OUGAMKAG5ldHdvcmtfaWQgO3hpCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWSqsqQGCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUFAHBvcHB5AAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWTqDajjCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUGAG9yY2hpZAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWT5CjveCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUGAGFsbGl1bQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWTORIBJCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUJAGhvdXN0b25pYQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWTuNhmYCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUJAHR1bGlwX3JlZAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWT0O4nfCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUMAHR1bGlwX29yYW5nZQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWTqkthyCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGULAHR1bGlwX3doaXRlAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWRMbBA7CgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUKAHR1bGlwX3BpbmsAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWRexMAuCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUFAG94ZXllAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWQgs7BECgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUKAGNvcm5mbG93ZXIAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWRvDuNbCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUSAGxpbHlfb2ZfdGhlX3ZhbGxleQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:double_plant", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZOemRt4KBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQkAc3VuZmxvd2VyAQ8AdXBwZXJfYmxvY2tfYml0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:double_plant", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZOFugoEKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQcAc3lyaW5nYQEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:double_plant", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZN4O+/gKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQQAcm9zZQEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:double_plant", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZI3w4GMKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQcAcGFlb25pYQEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:pitcher_plant", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnBpdGNoZXJfcGxhbnQECQBuYW1lX2hhc2hRJHzsbDH+SQMKAG5ldHdvcmtfaWRnY76VCgYAc3RhdGVzAQ8AdXBwZXJfYmxvY2tfYml0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:pink_petals", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OnBpbmtfcGV0YWxzBAkAbmFtZV9oYXNo6DQwN9SwV3QDCgBuZXR3b3JrX2lkNWneGgoGAHN0YXRlcwMGAGdyb3d0aAAAAAAIHABtaW5lY3JhZnQ6Y2FyZGluYWxfZGlyZWN0aW9uBQBzb3V0aAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:wither_rose", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OndpdGhlcl9yb3NlBAkAbmFtZV9oYXNoaSKxl3I516gDCgBuZXR3b3JrX2lkATXLPwoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:torchflower", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OnRvcmNoZmxvd2VyBAkAbmFtZV9oYXNoL+mHtElwbqQDCgBuZXR3b3JrX2lkI34O+AoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:white_dye" - }, - { - "id": "minecraft:light_gray_dye" - }, - { - "id": "minecraft:gray_dye" - }, - { - "id": "minecraft:black_dye" - }, - { - "id": "minecraft:brown_dye" - }, - { - "id": "minecraft:red_dye" - }, - { - "id": "minecraft:orange_dye" - }, - { - "id": "minecraft:yellow_dye" - }, - { - "id": "minecraft:lime_dye" - }, - { - "id": "minecraft:green_dye" - }, - { - "id": "minecraft:cyan_dye" - }, - { - "id": "minecraft:light_blue_dye" - }, - { - "id": "minecraft:blue_dye" - }, - { - "id": "minecraft:purple_dye" - }, - { - "id": "minecraft:magenta_dye" - }, - { - "id": "minecraft:pink_dye" - }, - { - "id": "minecraft:ink_sac" - }, - { - "id": "minecraft:glow_ink_sac" - }, - { - "id": "minecraft:cocoa_beans" - }, - { - "id": "minecraft:lapis_lazuli" - }, - { - "id": "minecraft:bone_meal" - }, - { - "id": "minecraft:vine", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0OnZpbmUECQBuYW1lX2hhc2j0Sj8/XeXOLAMKAG5ldHdvcmtfaWSUkDtbCgYAc3RhdGVzAxMAdmluZV9kaXJlY3Rpb25fYml0cwAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:weeping_vines", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OndlZXBpbmdfdmluZXMECQBuYW1lX2hhc2jrLgLHkQygiwMKAG5ldHdvcmtfaWQ8NHSJCgYAc3RhdGVzAxEAd2VlcGluZ192aW5lc19hZ2UAAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:twisting_vines", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OnR3aXN0aW5nX3ZpbmVzBAkAbmFtZV9oYXNoDYR5QgVUQJADCgBuZXR3b3JrX2lk5kYVIQoGAHN0YXRlcwMSAHR3aXN0aW5nX3ZpbmVzX2FnZQAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:waterlily", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OndhdGVybGlseQQJAG5hbWVfaGFzaEHgC4c1SXg0AwoAbmV0d29ya19pZOOerp8KBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:seagrass", - "block_state_b64": "CgAACAQAbmFtZRIAbWluZWNyYWZ0OnNlYWdyYXNzBAkAbmFtZV9oYXNoHSBFtoHdWxIDCgBuZXR3b3JrX2lkd3lhEAoGAHN0YXRlcwgOAHNlYV9ncmFzc190eXBlBwBkZWZhdWx0AAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:kelp" - }, - { - "id": "minecraft:deadbush", - "block_state_b64": "CgAACAQAbmFtZRIAbWluZWNyYWZ0OmRlYWRidXNoBAkAbmFtZV9oYXNoPFODe4IScnYDCgBuZXR3b3JrX2lkVfnl+goGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:bamboo", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OmJhbWJvbwQJAG5hbWVfaGFzaBgpGmyzhedCAwoAbmV0d29ya19pZIZv1nYKBgBzdGF0ZXMBBwBhZ2VfYml0AAgQAGJhbWJvb19sZWFmX3NpemUJAG5vX2xlYXZlcwgWAGJhbWJvb19zdGFsa190aGlja25lc3MEAHRoaW4AAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:snow", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0OnNub3cECQBuYW1lX2hhc2gVHr5XXdETWAMKAG5ldHdvcmtfaWQ0zCeHCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:ice", - "block_state_b64": "CgAACAQAbmFtZQ0AbWluZWNyYWZ0OmljZQQJAG5hbWVfaGFzaNF26f+uUT29AwoAbmV0d29ya19pZOUMaQYKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:packed_ice", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnBhY2tlZF9pY2UECQBuYW1lX2hhc2hk4bu123ZrFgMKAG5ldHdvcmtfaWTr/ooaCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:blue_ice", - "block_state_b64": "CgAACAQAbmFtZRIAbWluZWNyYWZ0OmJsdWVfaWNlBAkAbmFtZV9oYXNo+EKxYgFhKcgDCgBuZXR3b3JrX2lkxfsA8goGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:snow_layer", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnNub3dfbGF5ZXIECQBuYW1lX2hhc2hXka6atMYUCQMKAG5ldHdvcmtfaWRCrIPcCgYAc3RhdGVzAQsAY292ZXJlZF9iaXQAAwYAaGVpZ2h0AAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:pointed_dripstone", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnBvaW50ZWRfZHJpcHN0b25lBAkAbmFtZV9oYXNoJMISzmHQgt8DCgBuZXR3b3JrX2lkbWrtYgoGAHN0YXRlcwgTAGRyaXBzdG9uZV90aGlja25lc3MDAHRpcAEHAGhhbmdpbmcBAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:dripstone_block", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmRyaXBzdG9uZV9ibG9jawQJAG5hbWVfaGFzaIIXnEqY77YsAwoAbmV0d29ya19pZMZi2kwKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:moss_carpet", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Om1vc3NfY2FycGV0BAkAbmFtZV9oYXNo/NEDxRPTshYDCgBuZXR3b3JrX2lkaGG3QwoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:moss_block", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0Om1vc3NfYmxvY2sECQBuYW1lX2hhc2iovcsPUYX2tgMKAG5ldHdvcmtfaWT3JSbfCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:dirt_with_roots", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmRpcnRfd2l0aF9yb290cwQJAG5hbWVfaGFzaLCNDYPviDCIAwoAbmV0d29ya19pZNCkwzoKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:hanging_roots", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0Omhhbmdpbmdfcm9vdHMECQBuYW1lX2hhc2jaXn+Y5UZpDAMKAG5ldHdvcmtfaWRU4c2vCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:mangrove_roots", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0Om1hbmdyb3ZlX3Jvb3RzBAkAbmFtZV9oYXNoa786PzQGZ6kDCgBuZXR3b3JrX2lklA0AHgoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:muddy_mangrove_roots", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0Om11ZGR5X21hbmdyb3ZlX3Jvb3RzBAkAbmFtZV9oYXNo9YApdHpo1RkDCgBuZXR3b3JrX2lkH0Oc4woGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:big_dripleaf", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmJpZ19kcmlwbGVhZgQJAG5hbWVfaGFzaGBEhXjo6qSdAwoAbmV0d29ya19pZMETsb8KBgBzdGF0ZXMBEQBiaWdfZHJpcGxlYWZfaGVhZAEIEQBiaWdfZHJpcGxlYWZfdGlsdAQAbm9uZQgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:small_dripleaf_block", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OnNtYWxsX2RyaXBsZWFmX2Jsb2NrBAkAbmFtZV9oYXNojxRAgXP9uWADCgBuZXR3b3JrX2lkozbVPwoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24EAGVhc3QBDwB1cHBlcl9ibG9ja19iaXQBAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:spore_blossom", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnNwb3JlX2Jsb3Nzb20ECQBuYW1lX2hhc2il3U72Gbco2gMKAG5ldHdvcmtfaWSbbbgcCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:azalea", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OmF6YWxlYQQJAG5hbWVfaGFzaNyUl+BW9JrBAwoAbmV0d29ya19pZO/XZtQKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:flowering_azalea", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmZsb3dlcmluZ19hemFsZWEECQBuYW1lX2hhc2ie9r33wz8kiwMKAG5ldHdvcmtfaWQ3ij0VCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:glow_lichen", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Omdsb3dfbGljaGVuBAkAbmFtZV9oYXNobyPUrIYlo44DCgBuZXR3b3JrX2lkCh8lSAoGAHN0YXRlcwMZAG11bHRpX2ZhY2VfZGlyZWN0aW9uX2JpdHM/AAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:amethyst_block", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmFtZXRoeXN0X2Jsb2NrBAkAbmFtZV9oYXNob+JK1iiAthcDCgBuZXR3b3JrX2lk8HtpzgoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:budding_amethyst", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmJ1ZGRpbmdfYW1ldGh5c3QECQBuYW1lX2hhc2gJvAwfI14fxgMKAG5ldHdvcmtfaWTQYqfACgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:amethyst_cluster", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmFtZXRoeXN0X2NsdXN0ZXIECQBuYW1lX2hhc2jK82S88Jgm8wMKAG5ldHdvcmtfaWSCPMPGCgYAc3RhdGVzCBQAbWluZWNyYWZ0OmJsb2NrX2ZhY2UCAHVwAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:large_amethyst_bud", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmxhcmdlX2FtZXRoeXN0X2J1ZAQJAG5hbWVfaGFzaAHhdpWD+sd5AwoAbmV0d29ya19pZKkQxOcKBgBzdGF0ZXMIFABtaW5lY3JhZnQ6YmxvY2tfZmFjZQIAdXAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:medium_amethyst_bud", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0Om1lZGl1bV9hbWV0aHlzdF9idWQECQBuYW1lX2hhc2g5lBGtC0DzZQMKAG5ldHdvcmtfaWSYiP4gCgYAc3RhdGVzCBQAbWluZWNyYWZ0OmJsb2NrX2ZhY2UCAHVwAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:small_amethyst_bud", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OnNtYWxsX2FtZXRoeXN0X2J1ZAQJAG5hbWVfaGFzaEnb4+q9PO4YAwoAbmV0d29ya19pZGWzxrQKBgBzdGF0ZXMIFABtaW5lY3JhZnQ6YmxvY2tfZmFjZQIAdXAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:tuff", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0OnR1ZmYECQBuYW1lX2hhc2h1Rwc1XYsBGwMKAG5ldHdvcmtfaWRwQGn0CgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:calcite", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OmNhbGNpdGUECQBuYW1lX2hhc2ixKLu8ZIdzDQMKAG5ldHdvcmtfaWQlSbJDCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:chicken" - }, - { - "id": "minecraft:porkchop" - }, - { - "id": "minecraft:beef" - }, - { - "id": "minecraft:mutton" - }, - { - "id": "minecraft:rabbit" - }, - { - "id": "minecraft:cod" - }, - { - "id": "minecraft:salmon" - }, - { - "id": "minecraft:tropical_fish" - }, - { - "id": "minecraft:pufferfish" - }, - { - "id": "minecraft:brown_mushroom", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmJyb3duX211c2hyb29tBAkAbmFtZV9oYXNonYw/FO78WDoDCgBuZXR3b3JrX2lkLh1OXAoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:red_mushroom", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnJlZF9tdXNocm9vbQQJAG5hbWVfaGFzaPpzJua7669xAwoAbmV0d29ya19pZCvWPYkKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:crimson_fungus", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fZnVuZ3VzBAkAbmFtZV9oYXNolIcCUuFM2u0DCgBuZXR3b3JrX2lkD2NN0QoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:warped_fungus", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9mdW5ndXMECQBuYW1lX2hhc2gq8bSnRVTAFgMKAG5ldHdvcmtfaWTkwS+rCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:brown_mushroom_block", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OmJyb3duX211c2hyb29tX2Jsb2NrBAkAbmFtZV9oYXNoIyjnbI6xy9sDCgBuZXR3b3JrX2lkdOMhDAoGAHN0YXRlcwMSAGh1Z2VfbXVzaHJvb21fYml0cw4AAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:red_mushroom_block", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OnJlZF9tdXNocm9vbV9ibG9jawQJAG5hbWVfaGFzaJTTyJbth9M9AwoAbmV0d29ya19pZM+AyboKBgBzdGF0ZXMDEgBodWdlX211c2hyb29tX2JpdHMOAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:brown_mushroom_block", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OmJyb3duX211c2hyb29tX2Jsb2NrBAkAbmFtZV9oYXNoIyjnbI6xy9sDCgBuZXR3b3JrX2lkbdt3CAoGAHN0YXRlcwMSAGh1Z2VfbXVzaHJvb21fYml0cw8AAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:brown_mushroom_block", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OmJyb3duX211c2hyb29tX2Jsb2NrBAkAbmFtZV9oYXNoIyjnbI6xy9sDCgBuZXR3b3JrX2lkSrMl9goGAHN0YXRlcwMSAGh1Z2VfbXVzaHJvb21fYml0cwAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:egg" - }, - { - "id": "minecraft:sugar_cane" - }, - { - "id": "minecraft:sugar" - }, - { - "id": "minecraft:rotten_flesh" - }, - { - "id": "minecraft:bone" - }, - { - "id": "minecraft:web", - "block_state_b64": "CgAACAQAbmFtZQ0AbWluZWNyYWZ0OndlYgQJAG5hbWVfaGFzaA4GKQCvG4i9AwoAbmV0d29ya19pZApt+jgKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:spider_eye" - }, - { - "id": "minecraft:mob_spawner", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Om1vYl9zcGF3bmVyBAkAbmFtZV9oYXNoNwGrCV/Fkh8DCgBuZXR3b3JrX2lkM1wTmgoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:monster_egg", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkqXH7RgoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGUFAHN0b25lAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:monster_egg", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkeIBb6QoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGULAGNvYmJsZXN0b25lAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:monster_egg", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkDZ2cFQoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGULAHN0b25lX2JyaWNrAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:monster_egg", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkOR/cTAoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGURAG1vc3N5X3N0b25lX2JyaWNrAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:monster_egg", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkqdwlHAoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGUTAGNyYWNrZWRfc3RvbmVfYnJpY2sAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:monster_egg", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkFqqPggoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGUUAGNoaXNlbGVkX3N0b25lX2JyaWNrAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:infested_deepslate", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmluZmVzdGVkX2RlZXBzbGF0ZQQJAG5hbWVfaGFzaICF2VYccxF1AwoAbmV0d29ya19pZDa/624KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:dragon_egg", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmRyYWdvbl9lZ2cECQBuYW1lX2hhc2inMzXrV+/e1wMKAG5ldHdvcmtfaWTgO1yRCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:turtle_egg", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnR1cnRsZV9lZ2cECQBuYW1lX2hhc2iwSRcxOJIJ9gMKAG5ldHdvcmtfaWSIRNUhCgYAc3RhdGVzCA0AY3JhY2tlZF9zdGF0ZQkAbm9fY3JhY2tzCBAAdHVydGxlX2VnZ19jb3VudAcAb25lX2VnZwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:sniffer_egg", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OnNuaWZmZXJfZWdnBAkAbmFtZV9oYXNoY1lozc8lPcYDCgBuZXR3b3JrX2lk7yb/2QoGAHN0YXRlcwgNAGNyYWNrZWRfc3RhdGUJAG5vX2NyYWNrcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:frog_spawn", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmZyb2dfc3Bhd24ECQBuYW1lX2hhc2iWmd7idp3ZZwMKAG5ldHdvcmtfaWRFzJudCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:pearlescent_froglight", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OnBlYXJsZXNjZW50X2Zyb2dsaWdodAQJAG5hbWVfaGFzaKkcFRyycYGyAwoAbmV0d29ya19pZJqYakAKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:verdant_froglight", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnZlcmRhbnRfZnJvZ2xpZ2h0BAkAbmFtZV9oYXNoA+eXuTBohrQDCgBuZXR3b3JrX2lkDIVnsQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:ochre_froglight", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0Om9jaHJlX2Zyb2dsaWdodAQJAG5hbWVfaGFzaMY59kjPe+c3AwoAbmV0d29ya19pZO2TD50KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:chicken_spawn_egg" - }, - { - "id": "minecraft:bee_spawn_egg" - }, - { - "id": "minecraft:cow_spawn_egg" - }, - { - "id": "minecraft:pig_spawn_egg" - }, - { - "id": "minecraft:sheep_spawn_egg" - }, - { - "id": "minecraft:wolf_spawn_egg" - }, - { - "id": "minecraft:polar_bear_spawn_egg" - }, - { - "id": "minecraft:ocelot_spawn_egg" - }, - { - "id": "minecraft:cat_spawn_egg" - }, - { - "id": "minecraft:mooshroom_spawn_egg" - }, - { - "id": "minecraft:bat_spawn_egg" - }, - { - "id": "minecraft:parrot_spawn_egg" - }, - { - "id": "minecraft:rabbit_spawn_egg" - }, - { - "id": "minecraft:llama_spawn_egg" - }, - { - "id": "minecraft:horse_spawn_egg" - }, - { - "id": "minecraft:donkey_spawn_egg" - }, - { - "id": "minecraft:mule_spawn_egg" - }, - { - "id": "minecraft:skeleton_horse_spawn_egg" - }, - { - "id": "minecraft:zombie_horse_spawn_egg" - }, - { - "id": "minecraft:tropical_fish_spawn_egg" - }, - { - "id": "minecraft:cod_spawn_egg" - }, - { - "id": "minecraft:pufferfish_spawn_egg" - }, - { - "id": "minecraft:salmon_spawn_egg" - }, - { - "id": "minecraft:dolphin_spawn_egg" - }, - { - "id": "minecraft:turtle_spawn_egg" - }, - { - "id": "minecraft:panda_spawn_egg" - }, - { - "id": "minecraft:fox_spawn_egg" - }, - { - "id": "minecraft:creeper_spawn_egg" - }, - { - "id": "minecraft:enderman_spawn_egg" - }, - { - "id": "minecraft:silverfish_spawn_egg" - }, - { - "id": "minecraft:skeleton_spawn_egg" - }, - { - "id": "minecraft:wither_skeleton_spawn_egg" - }, - { - "id": "minecraft:stray_spawn_egg" - }, - { - "id": "minecraft:slime_spawn_egg" - }, - { - "id": "minecraft:spider_spawn_egg" - }, - { - "id": "minecraft:zombie_spawn_egg" - }, - { - "id": "minecraft:zombie_pigman_spawn_egg" - }, - { - "id": "minecraft:husk_spawn_egg" - }, - { - "id": "minecraft:drowned_spawn_egg" - }, - { - "id": "minecraft:squid_spawn_egg" - }, - { - "id": "minecraft:glow_squid_spawn_egg" - }, - { - "id": "minecraft:cave_spider_spawn_egg" - }, - { - "id": "minecraft:witch_spawn_egg" - }, - { - "id": "minecraft:guardian_spawn_egg" - }, - { - "id": "minecraft:elder_guardian_spawn_egg" - }, - { - "id": "minecraft:endermite_spawn_egg" - }, - { - "id": "minecraft:magma_cube_spawn_egg" - }, - { - "id": "minecraft:strider_spawn_egg" - }, - { - "id": "minecraft:hoglin_spawn_egg" - }, - { - "id": "minecraft:piglin_spawn_egg" - }, - { - "id": "minecraft:zoglin_spawn_egg" - }, - { - "id": "minecraft:piglin_brute_spawn_egg" - }, - { - "id": "minecraft:goat_spawn_egg" - }, - { - "id": "minecraft:axolotl_spawn_egg" - }, - { - "id": "minecraft:warden_spawn_egg" - }, - { - "id": "minecraft:allay_spawn_egg" - }, - { - "id": "minecraft:frog_spawn_egg" - }, - { - "id": "minecraft:tadpole_spawn_egg" - }, - { - "id": "minecraft:trader_llama_spawn_egg" - }, - { - "id": "minecraft:camel_spawn_egg" - }, - { - "id": "minecraft:ghast_spawn_egg" - }, - { - "id": "minecraft:blaze_spawn_egg" - }, - { - "id": "minecraft:shulker_spawn_egg" - }, - { - "id": "minecraft:vindicator_spawn_egg" - }, - { - "id": "minecraft:evoker_spawn_egg" - }, - { - "id": "minecraft:vex_spawn_egg" - }, - { - "id": "minecraft:villager_spawn_egg" - }, - { - "id": "minecraft:wandering_trader_spawn_egg" - }, - { - "id": "minecraft:zombie_villager_spawn_egg" - }, - { - "id": "minecraft:phantom_spawn_egg" - }, - { - "id": "minecraft:pillager_spawn_egg" - }, - { - "id": "minecraft:ravager_spawn_egg" - }, - { - "id": "minecraft:iron_golem_spawn_egg" - }, - { - "id": "minecraft:snow_golem_spawn_egg" - }, - { - "id": "minecraft:sniffer_spawn_egg" - }, - { - "id": "minecraft:obsidian", - "block_state_b64": "CgAACAQAbmFtZRIAbWluZWNyYWZ0Om9ic2lkaWFuBAkAbmFtZV9oYXNoiz4qrb8QjyEDCgBuZXR3b3JrX2lkuqnPpQoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:crying_obsidian", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmNyeWluZ19vYnNpZGlhbgQJAG5hbWVfaGFzaKT0JlA7Z1K+AwoAbmV0d29ya19pZCjbPV4KBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:bedrock", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OmJlZHJvY2sECQBuYW1lX2hhc2hWfFrh4LVtxwMKAG5ldHdvcmtfaWT7fKz1CgYAc3RhdGVzAQ4AaW5maW5pYnVybl9iaXQAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:soul_sand", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OnNvdWxfc2FuZAQJAG5hbWVfaGFzaMaf+bccu+KTAwoAbmV0d29ya19pZBQSHrMKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:magma", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0Om1hZ21hBAkAbmFtZV9oYXNoqyTjKaIsWfYDCgBuZXR3b3JrX2lkyfWAZgoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:nether_wart" - }, - { - "id": "minecraft:end_stone", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmVuZF9zdG9uZQQJAG5hbWVfaGFzaH1J9jA39GJNAwoAbmV0d29ya19pZFeFQ7UKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:chorus_flower", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmNob3J1c19mbG93ZXIECQBuYW1lX2hhc2iMpSodli5uawMKAG5ldHdvcmtfaWRnd1ZWCgYAc3RhdGVzAwMAYWdlAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:chorus_plant", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmNob3J1c19wbGFudAQJAG5hbWVfaGFzaJhSrmNGKwaMAwoAbmV0d29ya19pZA3uVqMKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:chorus_fruit" - }, - { - "id": "minecraft:popped_chorus_fruit" - }, - { - "id": "minecraft:sponge", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OnNwb25nZQQJAG5hbWVfaGFzaLrd2ScYRDMiAwoAbmV0d29ya19pZF01rO0KBgBzdGF0ZXMICwBzcG9uZ2VfdHlwZQMAZHJ5AAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:sponge", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OnNwb25nZQQJAG5hbWVfaGFzaLrd2ScYRDMiAwoAbmV0d29ya19pZPiOc4QKBgBzdGF0ZXMICwBzcG9uZ2VfdHlwZQMAd2V0AAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkGnlaAwoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABibHVlAQgAZGVhZF9iaXQAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkSnHuagoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABwaW5rAQgAZGVhZF9iaXQAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkmkHyegoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgBwdXJwbGUBCABkZWFkX2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkdpUDxgoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yAwByZWQBCABkZWFkX2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkYNWvYgoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgB5ZWxsb3cBCABkZWFkX2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkZSxBQgoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABibHVlAQgAZGVhZF9iaXQBAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lklSTVqQoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABwaW5rAQgAZGVhZF9iaXQBAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lk5fTYuQoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgBwdXJwbGUBCABkZWFkX2JpdAEAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkwUjqBAoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yAwByZWQBCABkZWFkX2JpdAEAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkq4iWoQoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgB5ZWxsb3cBCABkZWFkX2JpdAEAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:sculk", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OnNjdWxrBAkAbmFtZV9oYXNo2Lq7T5yQF8kDCgBuZXR3b3JrX2lkyqUPPgoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:sculk_vein", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnNjdWxrX3ZlaW4ECQBuYW1lX2hhc2gJUdhVooV4zwMKAG5ldHdvcmtfaWSUfn1XCgYAc3RhdGVzAxkAbXVsdGlfZmFjZV9kaXJlY3Rpb25fYml0cwAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:sculk_catalyst", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OnNjdWxrX2NhdGFseXN0BAkAbmFtZV9oYXNo+gCpbrCHST4DCgBuZXR3b3JrX2lkMJ2n/woGAHN0YXRlcwEFAGJsb29tAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:sculk_shrieker", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OnNjdWxrX3Nocmlla2VyBAkAbmFtZV9oYXNo5OXtyObniQ4DCgBuZXR3b3JrX2lkxapoNAoGAHN0YXRlcwEGAGFjdGl2ZQABCgBjYW5fc3VtbW9uAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:sculk_sensor", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnNjdWxrX3NlbnNvcgQJAG5hbWVfaGFzaCkmHreeTgNnAwoAbmV0d29ya19pZLj2WPcKBgBzdGF0ZXMDEgBzY3Vsa19zZW5zb3JfcGhhc2UAAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:calibrated_sculk_sensor", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OmNhbGlicmF0ZWRfc2N1bGtfc2Vuc29yBAkAbmFtZV9oYXNoffAcXXN/iJUDCgBuZXR3b3JrX2lkwOx3QQoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAxIAc2N1bGtfc2Vuc29yX3BoYXNlAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:reinforced_deepslate", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OnJlaW5mb3JjZWRfZGVlcHNsYXRlBAkAbmFtZV9oYXNoldDmj91EapQDCgBuZXR3b3JrX2lkHIt+aQoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:leather_helmet" - }, - { - "id": "minecraft:chainmail_helmet" - }, - { - "id": "minecraft:iron_helmet" - }, - { - "id": "minecraft:golden_helmet" - }, - { - "id": "minecraft:diamond_helmet" - }, - { - "id": "minecraft:netherite_helmet" - }, - { - "id": "minecraft:leather_chestplate" - }, - { - "id": "minecraft:chainmail_chestplate" - }, - { - "id": "minecraft:iron_chestplate" - }, - { - "id": "minecraft:golden_chestplate" - }, - { - "id": "minecraft:diamond_chestplate" - }, - { - "id": "minecraft:netherite_chestplate" - }, - { - "id": "minecraft:leather_leggings" - }, - { - "id": "minecraft:chainmail_leggings" - }, - { - "id": "minecraft:iron_leggings" - }, - { - "id": "minecraft:golden_leggings" - }, - { - "id": "minecraft:diamond_leggings" - }, - { - "id": "minecraft:netherite_leggings" - }, - { - "id": "minecraft:leather_boots" - }, - { - "id": "minecraft:chainmail_boots" - }, - { - "id": "minecraft:iron_boots" - }, - { - "id": "minecraft:golden_boots" - }, - { - "id": "minecraft:diamond_boots" - }, - { - "id": "minecraft:netherite_boots" - }, - { - "id": "minecraft:wooden_sword" - }, - { - "id": "minecraft:stone_sword" - }, - { - "id": "minecraft:iron_sword" - }, - { - "id": "minecraft:golden_sword" - }, - { - "id": "minecraft:diamond_sword" - }, - { - "id": "minecraft:netherite_sword" - }, - { - "id": "minecraft:wooden_axe" - }, - { - "id": "minecraft:stone_axe" - }, - { - "id": "minecraft:iron_axe" - }, - { - "id": "minecraft:golden_axe" - }, - { - "id": "minecraft:diamond_axe" - }, - { - "id": "minecraft:netherite_axe" - }, - { - "id": "minecraft:wooden_pickaxe" - }, - { - "id": "minecraft:stone_pickaxe" - }, - { - "id": "minecraft:iron_pickaxe" - }, - { - "id": "minecraft:golden_pickaxe" - }, - { - "id": "minecraft:diamond_pickaxe" - }, - { - "id": "minecraft:netherite_pickaxe" - }, - { - "id": "minecraft:wooden_shovel" - }, - { - "id": "minecraft:stone_shovel" - }, - { - "id": "minecraft:iron_shovel" - }, - { - "id": "minecraft:golden_shovel" - }, - { - "id": "minecraft:diamond_shovel" - }, - { - "id": "minecraft:netherite_shovel" - }, - { - "id": "minecraft:wooden_hoe" - }, - { - "id": "minecraft:stone_hoe" - }, - { - "id": "minecraft:iron_hoe" - }, - { - "id": "minecraft:golden_hoe" - }, - { - "id": "minecraft:diamond_hoe" - }, - { - "id": "minecraft:netherite_hoe" - }, - { - "id": "minecraft:bow" - }, - { - "id": "minecraft:crossbow" - }, - { - "id": "minecraft:arrow" - }, - { - "id": "minecraft:arrow", - "damage": 6 - }, - { - "id": "minecraft:arrow", - "damage": 7 - }, - { - "id": "minecraft:arrow", - "damage": 8 - }, - { - "id": "minecraft:arrow", - "damage": 9 - }, - { - "id": "minecraft:arrow", - "damage": 10 - }, - { - "id": "minecraft:arrow", - "damage": 11 - }, - { - "id": "minecraft:arrow", - "damage": 12 - }, - { - "id": "minecraft:arrow", - "damage": 13 - }, - { - "id": "minecraft:arrow", - "damage": 14 - }, - { - "id": "minecraft:arrow", - "damage": 15 - }, - { - "id": "minecraft:arrow", - "damage": 16 - }, - { - "id": "minecraft:arrow", - "damage": 17 - }, - { - "id": "minecraft:arrow", - "damage": 18 - }, - { - "id": "minecraft:arrow", - "damage": 19 - }, - { - "id": "minecraft:arrow", - "damage": 20 - }, - { - "id": "minecraft:arrow", - "damage": 21 - }, - { - "id": "minecraft:arrow", - "damage": 22 - }, - { - "id": "minecraft:arrow", - "damage": 23 - }, - { - "id": "minecraft:arrow", - "damage": 24 - }, - { - "id": "minecraft:arrow", - "damage": 25 - }, - { - "id": "minecraft:arrow", - "damage": 26 - }, - { - "id": "minecraft:arrow", - "damage": 27 - }, - { - "id": "minecraft:arrow", - "damage": 28 - }, - { - "id": "minecraft:arrow", - "damage": 29 - }, - { - "id": "minecraft:arrow", - "damage": 30 - }, - { - "id": "minecraft:arrow", - "damage": 31 - }, - { - "id": "minecraft:arrow", - "damage": 32 - }, - { - "id": "minecraft:arrow", - "damage": 33 - }, - { - "id": "minecraft:arrow", - "damage": 34 - }, - { - "id": "minecraft:arrow", - "damage": 35 - }, - { - "id": "minecraft:arrow", - "damage": 36 - }, - { - "id": "minecraft:arrow", - "damage": 37 - }, - { - "id": "minecraft:arrow", - "damage": 38 - }, - { - "id": "minecraft:arrow", - "damage": 39 - }, - { - "id": "minecraft:arrow", - "damage": 40 - }, - { - "id": "minecraft:arrow", - "damage": 41 - }, - { - "id": "minecraft:arrow", - "damage": 42 - }, - { - "id": "minecraft:arrow", - "damage": 43 - }, - { - "id": "minecraft:shield" - }, - { - "id": "minecraft:cooked_chicken" - }, - { - "id": "minecraft:cooked_porkchop" - }, - { - "id": "minecraft:cooked_beef" - }, - { - "id": "minecraft:cooked_mutton" - }, - { - "id": "minecraft:cooked_rabbit" - }, - { - "id": "minecraft:cooked_cod" - }, - { - "id": "minecraft:cooked_salmon" - }, - { - "id": "minecraft:bread" - }, - { - "id": "minecraft:mushroom_stew" - }, - { - "id": "minecraft:beetroot_soup" - }, - { - "id": "minecraft:rabbit_stew" - }, - { - "id": "minecraft:baked_potato" - }, - { - "id": "minecraft:cookie" - }, - { - "id": "minecraft:pumpkin_pie" - }, - { - "id": "minecraft:cake" - }, - { - "id": "minecraft:dried_kelp" - }, - { - "id": "minecraft:fishing_rod" - }, - { - "id": "minecraft:carrot_on_a_stick" - }, - { - "id": "minecraft:warped_fungus_on_a_stick" - }, - { - "id": "minecraft:snowball" - }, - { - "id": "minecraft:shears" - }, - { - "id": "minecraft:flint_and_steel" - }, - { - "id": "minecraft:lead" - }, - { - "id": "minecraft:clock" - }, - { - "id": "minecraft:compass" - }, - { - "id": "minecraft:recovery_compass" - }, - { - "id": "minecraft:goat_horn" - }, - { - "id": "minecraft:goat_horn", - "damage": 1 - }, - { - "id": "minecraft:goat_horn", - "damage": 2 - }, - { - "id": "minecraft:goat_horn", - "damage": 3 - }, - { - "id": "minecraft:goat_horn", - "damage": 4 - }, - { - "id": "minecraft:goat_horn", - "damage": 5 - }, - { - "id": "minecraft:goat_horn", - "damage": 6 - }, - { - "id": "minecraft:goat_horn", - "damage": 7 - }, - { - "id": "minecraft:empty_map" - }, - { - "id": "minecraft:empty_map", - "damage": 2 - }, - { - "id": "minecraft:saddle" - }, - { - "id": "minecraft:leather_horse_armor" - }, - { - "id": "minecraft:iron_horse_armor" - }, - { - "id": "minecraft:golden_horse_armor" - }, - { - "id": "minecraft:diamond_horse_armor" - }, - { - "id": "minecraft:trident" - }, - { - "id": "minecraft:turtle_helmet" - }, - { - "id": "minecraft:elytra" - }, - { - "id": "minecraft:totem_of_undying" - }, - { - "id": "minecraft:glass_bottle" - }, - { - "id": "minecraft:experience_bottle" - }, - { - "id": "minecraft:potion" - }, - { - "id": "minecraft:potion", - "damage": 1 - }, - { - "id": "minecraft:potion", - "damage": 2 - }, - { - "id": "minecraft:potion", - "damage": 3 - }, - { - "id": "minecraft:potion", - "damage": 4 - }, - { - "id": "minecraft:potion", - "damage": 5 - }, - { - "id": "minecraft:potion", - "damage": 6 - }, - { - "id": "minecraft:potion", - "damage": 7 - }, - { - "id": "minecraft:potion", - "damage": 8 - }, - { - "id": "minecraft:potion", - "damage": 9 - }, - { - "id": "minecraft:potion", - "damage": 10 - }, - { - "id": "minecraft:potion", - "damage": 11 - }, - { - "id": "minecraft:potion", - "damage": 12 - }, - { - "id": "minecraft:potion", - "damage": 13 - }, - { - "id": "minecraft:potion", - "damage": 14 - }, - { - "id": "minecraft:potion", - "damage": 15 - }, - { - "id": "minecraft:potion", - "damage": 16 - }, - { - "id": "minecraft:potion", - "damage": 17 - }, - { - "id": "minecraft:potion", - "damage": 18 - }, - { - "id": "minecraft:potion", - "damage": 19 - }, - { - "id": "minecraft:potion", - "damage": 20 - }, - { - "id": "minecraft:potion", - "damage": 21 - }, - { - "id": "minecraft:potion", - "damage": 22 - }, - { - "id": "minecraft:potion", - "damage": 23 - }, - { - "id": "minecraft:potion", - "damage": 24 - }, - { - "id": "minecraft:potion", - "damage": 25 - }, - { - "id": "minecraft:potion", - "damage": 26 - }, - { - "id": "minecraft:potion", - "damage": 27 - }, - { - "id": "minecraft:potion", - "damage": 28 - }, - { - "id": "minecraft:potion", - "damage": 29 - }, - { - "id": "minecraft:potion", - "damage": 30 - }, - { - "id": "minecraft:potion", - "damage": 31 - }, - { - "id": "minecraft:potion", - "damage": 32 - }, - { - "id": "minecraft:potion", - "damage": 33 - }, - { - "id": "minecraft:potion", - "damage": 34 - }, - { - "id": "minecraft:potion", - "damage": 35 - }, - { - "id": "minecraft:potion", - "damage": 36 - }, - { - "id": "minecraft:potion", - "damage": 37 - }, - { - "id": "minecraft:potion", - "damage": 38 - }, - { - "id": "minecraft:potion", - "damage": 39 - }, - { - "id": "minecraft:potion", - "damage": 40 - }, - { - "id": "minecraft:potion", - "damage": 41 - }, - { - "id": "minecraft:potion", - "damage": 42 - }, - { - "id": "minecraft:splash_potion" - }, - { - "id": "minecraft:splash_potion", - "damage": 1 - }, - { - "id": "minecraft:splash_potion", - "damage": 2 - }, - { - "id": "minecraft:splash_potion", - "damage": 3 - }, - { - "id": "minecraft:splash_potion", - "damage": 4 - }, - { - "id": "minecraft:splash_potion", - "damage": 5 - }, - { - "id": "minecraft:splash_potion", - "damage": 6 - }, - { - "id": "minecraft:splash_potion", - "damage": 7 - }, - { - "id": "minecraft:splash_potion", - "damage": 8 - }, - { - "id": "minecraft:splash_potion", - "damage": 9 - }, - { - "id": "minecraft:splash_potion", - "damage": 10 - }, - { - "id": "minecraft:splash_potion", - "damage": 11 - }, - { - "id": "minecraft:splash_potion", - "damage": 12 - }, - { - "id": "minecraft:splash_potion", - "damage": 13 - }, - { - "id": "minecraft:splash_potion", - "damage": 14 - }, - { - "id": "minecraft:splash_potion", - "damage": 15 - }, - { - "id": "minecraft:splash_potion", - "damage": 16 - }, - { - "id": "minecraft:splash_potion", - "damage": 17 - }, - { - "id": "minecraft:splash_potion", - "damage": 18 - }, - { - "id": "minecraft:splash_potion", - "damage": 19 - }, - { - "id": "minecraft:splash_potion", - "damage": 20 - }, - { - "id": "minecraft:splash_potion", - "damage": 21 - }, - { - "id": "minecraft:splash_potion", - "damage": 22 - }, - { - "id": "minecraft:splash_potion", - "damage": 23 - }, - { - "id": "minecraft:splash_potion", - "damage": 24 - }, - { - "id": "minecraft:splash_potion", - "damage": 25 - }, - { - "id": "minecraft:splash_potion", - "damage": 26 - }, - { - "id": "minecraft:splash_potion", - "damage": 27 - }, - { - "id": "minecraft:splash_potion", - "damage": 28 - }, - { - "id": "minecraft:splash_potion", - "damage": 29 - }, - { - "id": "minecraft:splash_potion", - "damage": 30 - }, - { - "id": "minecraft:splash_potion", - "damage": 31 - }, - { - "id": "minecraft:splash_potion", - "damage": 32 - }, - { - "id": "minecraft:splash_potion", - "damage": 33 - }, - { - "id": "minecraft:splash_potion", - "damage": 34 - }, - { - "id": "minecraft:splash_potion", - "damage": 35 - }, - { - "id": "minecraft:splash_potion", - "damage": 36 - }, - { - "id": "minecraft:splash_potion", - "damage": 37 - }, - { - "id": "minecraft:splash_potion", - "damage": 38 - }, - { - "id": "minecraft:splash_potion", - "damage": 39 - }, - { - "id": "minecraft:splash_potion", - "damage": 40 - }, - { - "id": "minecraft:splash_potion", - "damage": 41 - }, - { - "id": "minecraft:splash_potion", - "damage": 42 - }, - { - "id": "minecraft:lingering_potion" - }, - { - "id": "minecraft:lingering_potion", - "damage": 1 - }, - { - "id": "minecraft:lingering_potion", - "damage": 2 - }, - { - "id": "minecraft:lingering_potion", - "damage": 3 - }, - { - "id": "minecraft:lingering_potion", - "damage": 4 - }, - { - "id": "minecraft:lingering_potion", - "damage": 5 - }, - { - "id": "minecraft:lingering_potion", - "damage": 6 - }, - { - "id": "minecraft:lingering_potion", - "damage": 7 - }, - { - "id": "minecraft:lingering_potion", - "damage": 8 - }, - { - "id": "minecraft:lingering_potion", - "damage": 9 - }, - { - "id": "minecraft:lingering_potion", - "damage": 10 - }, - { - "id": "minecraft:lingering_potion", - "damage": 11 - }, - { - "id": "minecraft:lingering_potion", - "damage": 12 - }, - { - "id": "minecraft:lingering_potion", - "damage": 13 - }, - { - "id": "minecraft:lingering_potion", - "damage": 14 - }, - { - "id": "minecraft:lingering_potion", - "damage": 15 - }, - { - "id": "minecraft:lingering_potion", - "damage": 16 - }, - { - "id": "minecraft:lingering_potion", - "damage": 17 - }, - { - "id": "minecraft:lingering_potion", - "damage": 18 - }, - { - "id": "minecraft:lingering_potion", - "damage": 19 - }, - { - "id": "minecraft:lingering_potion", - "damage": 20 - }, - { - "id": "minecraft:lingering_potion", - "damage": 21 - }, - { - "id": "minecraft:lingering_potion", - "damage": 22 - }, - { - "id": "minecraft:lingering_potion", - "damage": 23 - }, - { - "id": "minecraft:lingering_potion", - "damage": 24 - }, - { - "id": "minecraft:lingering_potion", - "damage": 25 - }, - { - "id": "minecraft:lingering_potion", - "damage": 26 - }, - { - "id": "minecraft:lingering_potion", - "damage": 27 - }, - { - "id": "minecraft:lingering_potion", - "damage": 28 - }, - { - "id": "minecraft:lingering_potion", - "damage": 29 - }, - { - "id": "minecraft:lingering_potion", - "damage": 30 - }, - { - "id": "minecraft:lingering_potion", - "damage": 31 - }, - { - "id": "minecraft:lingering_potion", - "damage": 32 - }, - { - "id": "minecraft:lingering_potion", - "damage": 33 - }, - { - "id": "minecraft:lingering_potion", - "damage": 34 - }, - { - "id": "minecraft:lingering_potion", - "damage": 35 - }, - { - "id": "minecraft:lingering_potion", - "damage": 36 - }, - { - "id": "minecraft:lingering_potion", - "damage": 37 - }, - { - "id": "minecraft:lingering_potion", - "damage": 38 - }, - { - "id": "minecraft:lingering_potion", - "damage": 39 - }, - { - "id": "minecraft:lingering_potion", - "damage": 40 - }, - { - "id": "minecraft:lingering_potion", - "damage": 41 - }, - { - "id": "minecraft:lingering_potion", - "damage": 42 - }, - { - "id": "minecraft:spyglass" - }, - { - "id": "minecraft:brush" - }, - { - "id": "minecraft:stick" - }, - { - "id": "minecraft:bed" - }, - { - "id": "minecraft:bed", - "damage": 8 - }, - { - "id": "minecraft:bed", - "damage": 7 - }, - { - "id": "minecraft:bed", - "damage": 15 - }, - { - "id": "minecraft:bed", - "damage": 12 - }, - { - "id": "minecraft:bed", - "damage": 14 - }, - { - "id": "minecraft:bed", - "damage": 1 - }, - { - "id": "minecraft:bed", - "damage": 4 - }, - { - "id": "minecraft:bed", - "damage": 5 - }, - { - "id": "minecraft:bed", - "damage": 13 - }, - { - "id": "minecraft:bed", - "damage": 9 - }, - { - "id": "minecraft:bed", - "damage": 3 - }, - { - "id": "minecraft:bed", - "damage": 11 - }, - { - "id": "minecraft:bed", - "damage": 10 - }, - { - "id": "minecraft:bed", - "damage": 2 - }, - { - "id": "minecraft:bed", - "damage": 6 - }, - { - "id": "minecraft:torch", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OnRvcmNoBAkAbmFtZV9oYXNoagn7rmDBzisDCgBuZXR3b3JrX2lk+BwwuQoGAHN0YXRlcwgWAHRvcmNoX2ZhY2luZ19kaXJlY3Rpb24HAHVua25vd24AAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:soul_torch", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnNvdWxfdG9yY2gECQBuYW1lX2hhc2huixOT04BRdQMKAG5ldHdvcmtfaWShbFILCgYAc3RhdGVzCBYAdG9yY2hfZmFjaW5nX2RpcmVjdGlvbgcAdW5rbm93bgADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:sea_pickle", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnNlYV9waWNrbGUECQBuYW1lX2hhc2iONEfZJB+glgMKAG5ldHdvcmtfaWSINWQyCgYAc3RhdGVzAw0AY2x1c3Rlcl9jb3VudAAAAAABCABkZWFkX2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:lantern", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OmxhbnRlcm4ECQBuYW1lX2hhc2hMw44VI2HWygMKAG5ldHdvcmtfaWRkjQvzCgYAc3RhdGVzAQcAaGFuZ2luZwAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:soul_lantern", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnNvdWxfbGFudGVybgQJAG5hbWVfaGFzaGjIpjxk9z+RAwoAbmV0d29ya19pZGfoP8cKBgBzdGF0ZXMBBwBoYW5naW5nAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:candle", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OmNhbmRsZQQJAG5hbWVfaGFzaHPd+MsNdWTfAwoAbmV0d29ya19pZHsBMA0KBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:white_candle", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OndoaXRlX2NhbmRsZQQJAG5hbWVfaGFzaN1EG5Q1mHiEAwoAbmV0d29ya19pZKN1mmgKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:orange_candle", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0Om9yYW5nZV9jYW5kbGUECQBuYW1lX2hhc2jySEVWHgUIHQMKAG5ldHdvcmtfaWSfVz82CgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:magenta_candle", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0Om1hZ2VudGFfY2FuZGxlBAkAbmFtZV9oYXNoG0u6YIOoBSEDCgBuZXR3b3JrX2lk9xGNkQoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:light_blue_candle", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY2FuZGxlBAkAbmFtZV9oYXNocXGeK0zgrG0DCgBuZXR3b3JrX2lk2m1y8goGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:yellow_candle", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnllbGxvd19jYW5kbGUECQBuYW1lX2hhc2i00dtusU3CqQMKAG5ldHdvcmtfaWR9LTmpCgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:lime_candle", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmxpbWVfY2FuZGxlBAkAbmFtZV9oYXNokcmrw5xvz7ADCgBuZXR3b3JrX2lkIAUu6QoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:pink_candle", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OnBpbmtfY2FuZGxlBAkAbmFtZV9oYXNoQJdEY4sZ0dwDCgBuZXR3b3JrX2lk23Rn5AoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:gray_candle", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmdyYXlfY2FuZGxlBAkAbmFtZV9oYXNoS5poSo9wBDEDCgBuZXR3b3JrX2lk3trRCAoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:light_gray_candle", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY2FuZGxlBAkAbmFtZV9oYXNo9ruTZLBNMasDCgBuZXR3b3JrX2lkb6DOegoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:cyan_candle", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmN5YW5fY2FuZGxlBAkAbmFtZV9oYXNoc/M8PNVcjOwDCgBuZXR3b3JrX2lkZoIQOQoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:purple_candle", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnB1cnBsZV9jYW5kbGUECQBuYW1lX2hhc2jaI3xUW0/myQMKAG5ldHdvcmtfaWSnLI2BCgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:blue_candle", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmJsdWVfY2FuZGxlBAkAbmFtZV9oYXNoAASSPW6TgQADCgBuZXR3b3JrX2lkrxrjQAoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:brown_candle", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmJyb3duX2NhbmRsZQQJAG5hbWVfaGFzaDia0l6s1+WYAwoAbmV0d29ya19pZKSkBXYKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:green_candle", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmdyZWVuX2NhbmRsZQQJAG5hbWVfaGFzaLeFPO1l+fIoAwoAbmV0d29ya19pZBkznDsKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:red_candle", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9jYW5kbGUECQBuYW1lX2hhc2jjAQpGf59ZdwMKAG5ldHdvcmtfaWRbb88GCgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:black_candle", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmJsYWNrX2NhbmRsZQQJAG5hbWVfaGFzaB+wRDpOqREKAwoAbmV0d29ya19pZNnOnuEKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:crafting_table", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNyYWZ0aW5nX3RhYmxlBAkAbmFtZV9oYXNoe76VAmjvbpYDCgBuZXR3b3JrX2lkwCxwaAoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:cartography_table", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmNhcnRvZ3JhcGh5X3RhYmxlBAkAbmFtZV9oYXNomaWiiD/znP8DCgBuZXR3b3JrX2lkI6FzMwoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:fletching_table", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmZsZXRjaGluZ190YWJsZQQJAG5hbWVfaGFzaPFibh8unKyUAwoAbmV0d29ya19pZJ2mW0oKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:smithing_table", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OnNtaXRoaW5nX3RhYmxlBAkAbmFtZV9oYXNo4tFES2xOXEYDCgBuZXR3b3JrX2lkXWMBzQoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:beehive", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OmJlZWhpdmUECQBuYW1lX2hhc2hCcqn12UbNpwMKAG5ldHdvcmtfaWR/idcaCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAMLAGhvbmV5X2xldmVsAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:suspicious_sand", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OnN1c3BpY2lvdXNfc2FuZAQJAG5hbWVfaGFzaL67QsuvLP00AwoAbmV0d29ya19pZKnkaIAKBgBzdGF0ZXMDEABicnVzaGVkX3Byb2dyZXNzAAAAAAEHAGhhbmdpbmcBAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:suspicious_gravel", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN1c3BpY2lvdXNfZ3JhdmVsBAkAbmFtZV9oYXNoJSVbGNk7C3oDCgBuZXR3b3JrX2lkvIEJAAoGAHN0YXRlcwMQAGJydXNoZWRfcHJvZ3Jlc3MAAAAAAQcAaGFuZ2luZwEAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:campfire" - }, - { - "id": "minecraft:soul_campfire" - }, - { - "id": "minecraft:furnace", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OmZ1cm5hY2UECQBuYW1lX2hhc2ioOQrludYY8wMKAG5ldHdvcmtfaWRZxnDOCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:blast_furnace", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmJsYXN0X2Z1cm5hY2UECQBuYW1lX2hhc2ivDbnjkpGm5QMKAG5ldHdvcmtfaWTcEbV/CgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:smoker", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OnNtb2tlcgQJAG5hbWVfaGFzaJd1rDMkRWomAwoAbmV0d29ya19pZGWswMwKBgBzdGF0ZXMIHABtaW5lY3JhZnQ6Y2FyZGluYWxfZGlyZWN0aW9uBQBzb3V0aAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:respawn_anchor", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OnJlc3Bhd25fYW5jaG9yBAkAbmFtZV9oYXNoZOdcjW05qigDCgBuZXR3b3JrX2lkmhMcaQoGAHN0YXRlcwMVAHJlc3Bhd25fYW5jaG9yX2NoYXJnZQAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:brewing_stand" - }, - { - "id": "minecraft:anvil", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OmFudmlsBAkAbmFtZV9oYXNoNqB3fgcUCbwDCgBuZXR3b3JrX2lk8Z3VowoGAHN0YXRlcwgGAGRhbWFnZQkAdW5kYW1hZ2VkCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:anvil", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OmFudmlsBAkAbmFtZV9oYXNoNqB3fgcUCbwDCgBuZXR3b3JrX2lkpiv8BAoGAHN0YXRlcwgGAGRhbWFnZRAAc2xpZ2h0bHlfZGFtYWdlZAgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:anvil", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OmFudmlsBAkAbmFtZV9oYXNoNqB3fgcUCbwDCgBuZXR3b3JrX2lkFu+pdwoGAHN0YXRlcwgGAGRhbWFnZQwAdmVyeV9kYW1hZ2VkCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:grindstone", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmdyaW5kc3RvbmUECQBuYW1lX2hhc2id56zc0nk99wMKAG5ldHdvcmtfaWS4Es07CgYAc3RhdGVzCAoAYXR0YWNobWVudAgAc3RhbmRpbmcDCQBkaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:enchanting_table", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmVuY2hhbnRpbmdfdGFibGUECQBuYW1lX2hhc2jgIx24VLvMvwMKAG5ldHdvcmtfaWRliFFJCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:bookshelf", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmJvb2tzaGVsZgQJAG5hbWVfaGFzaDU04DrgJCS9AwoAbmV0d29ya19pZBcWwIwKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:chiseled_bookshelf", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmNoaXNlbGVkX2Jvb2tzaGVsZgQJAG5hbWVfaGFzaNXDBnsIsywYAwoAbmV0d29ya19pZIprt5IKBgBzdGF0ZXMDDABib29rc19zdG9yZWQAAAAAAwkAZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:lectern", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OmxlY3Rlcm4ECQBuYW1lX2hhc2j5Z4Mmi/1QxAMKAG5ldHdvcmtfaWR4JfDHCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgBCwBwb3dlcmVkX2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:cauldron" - }, - { - "id": "minecraft:composter", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmNvbXBvc3RlcgQJAG5hbWVfaGFzaPAADHptzeWJAwoAbmV0d29ya19pZHIL6i4KBgBzdGF0ZXMDFABjb21wb3N0ZXJfZmlsbF9sZXZlbAAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:chest", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OmNoZXN0BAkAbmFtZV9oYXNog9ozMxlcA88DCgBuZXR3b3JrX2lkDkOFvAoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAG5vcnRoAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:trapped_chest", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnRyYXBwZWRfY2hlc3QECQBuYW1lX2hhc2g2qpF9stsEjgMKAG5ldHdvcmtfaWTjJWYxCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAbm9ydGgAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:ender_chest", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmVuZGVyX2NoZXN0BAkAbmFtZV9oYXNohEZzOFdg0WUDCgBuZXR3b3JrX2lkx4jiSQoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAG5vcnRoAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:barrel", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OmJhcnJlbAQJAG5hbWVfaGFzaHDkRPGymiRqAwoAbmV0d29ya19pZPnxzgsKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:undyed_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OnVuZHllZF9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaOC9mypm/MlBAwoAbmV0d29ya19pZJ8rxp0KBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:white_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OndoaXRlX3NodWxrZXJfYm94BAkAbmFtZV9oYXNosK79m1rPUBwDCgBuZXR3b3JrX2lkjrET6goGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:light_gray_shulker_box", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2iBe5zq7PxHmgMKAG5ldHdvcmtfaWSCVJv0CgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:gray_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmdyYXlfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2ga2s8ctjHUhgMKAG5ldHdvcmtfaWS3WMsWCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:black_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmJsYWNrX3NodWxrZXJfYm94BAkAbmFtZV9oYXNoPm03OZphrp8DCgBuZXR3b3JrX2lkXHztNAoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:brown_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmJyb3duX3NodWxrZXJfYm94BAkAbmFtZV9oYXNoT3DD6qAL9cADCgBuZXR3b3JrX2lkaXxpYQoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:red_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OnJlZF9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaMIlKSCzqSZoAwoAbmV0d29ya19pZNrf+icKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:orange_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0Om9yYW5nZV9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaG2MAXU67wGrAwoAbmV0d29ya19pZGoO05gKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:yellow_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OnllbGxvd19zaHVsa2VyX2JveAQJAG5hbWVfaGFzaIsLwQHYjcIEAwoAbmV0d29ya19pZBCBSiYKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:lime_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmxpbWVfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2hUwBkg+faUGAMKAG5ldHdvcmtfaWRJeKqqCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:green_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmdyZWVuX3NodWxrZXJfYm94BAkAbmFtZV9oYXNoZgUeT3LupLUDCgBuZXR3b3JrX2lkzJiohQoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:cyan_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmN5YW5fc2h1bGtlcl9ib3gECQBuYW1lX2hhc2gSfbjteXg5yAMKAG5ldHdvcmtfaWTHeliECgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:light_blue_shulker_box", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2h0VFCX0qsRxQMKAG5ldHdvcmtfaWQXD8U0CgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:blue_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmJsdWVfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2hn9gS0XIe6rAMKAG5ldHdvcmtfaWTO4PJaCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:purple_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OnB1cnBsZV9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaEV/lkNPxRDdAwoAbmV0d29ya19pZFK25GAKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:magenta_shulker_box", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0Om1hZ2VudGFfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2iqWM7IJHxcFgMKAG5ldHdvcmtfaWTyyudTCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:pink_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OnBpbmtfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2in1tkJ1GNcZgMKAG5ldHdvcmtfaWQOEGXjCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:armor_stand" - }, - { - "id": "minecraft:noteblock", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0Om5vdGVibG9jawQJAG5hbWVfaGFzaHPA8dBBH0UaAwoAbmV0d29ya19pZH1U5QkKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:jukebox", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0Omp1a2Vib3gECQBuYW1lX2hhc2ieAIPExf/ZfgMKAG5ldHdvcmtfaWSmR7JfCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:music_disc_13" - }, - { - "id": "minecraft:music_disc_cat" - }, - { - "id": "minecraft:music_disc_blocks" - }, - { - "id": "minecraft:music_disc_chirp" - }, - { - "id": "minecraft:music_disc_far" - }, - { - "id": "minecraft:music_disc_mall" - }, - { - "id": "minecraft:music_disc_mellohi" - }, - { - "id": "minecraft:music_disc_stal" - }, - { - "id": "minecraft:music_disc_strad" - }, - { - "id": "minecraft:music_disc_ward" - }, - { - "id": "minecraft:music_disc_11" - }, - { - "id": "minecraft:music_disc_wait" - }, - { - "id": "minecraft:music_disc_otherside" - }, - { - "id": "minecraft:music_disc_5" - }, - { - "id": "minecraft:music_disc_pigstep" - }, - { - "id": "minecraft:music_disc_relic" - }, - { - "id": "minecraft:disc_fragment_5" - }, - { - "id": "minecraft:glowstone_dust" - }, - { - "id": "minecraft:glowstone", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0Omdsb3dzdG9uZQQJAG5hbWVfaGFzaFYqXNkefIlPAwoAbmV0d29ya19pZGT7WYYKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:redstone_lamp", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZHN0b25lX2xhbXAECQBuYW1lX2hhc2hJ9V80caPvEgMKAG5ldHdvcmtfaWRvNPwnCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:sea_lantern", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OnNlYV9sYW50ZXJuBAkAbmFtZV9oYXNoLPsv1TX9M+QDCgBuZXR3b3JrX2lk1PPVyAoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:oak_sign" - }, - { - "id": "minecraft:spruce_sign" - }, - { - "id": "minecraft:birch_sign" - }, - { - "id": "minecraft:jungle_sign" - }, - { - "id": "minecraft:acacia_sign" - }, - { - "id": "minecraft:dark_oak_sign" - }, - { - "id": "minecraft:mangrove_sign" - }, - { - "id": "minecraft:cherry_sign" - }, - { - "id": "minecraft:bamboo_sign" - }, - { - "id": "minecraft:crimson_sign" - }, - { - "id": "minecraft:warped_sign" - }, - { - "id": "minecraft:oak_hanging_sign" - }, - { - "id": "minecraft:spruce_hanging_sign" - }, - { - "id": "minecraft:birch_hanging_sign" - }, - { - "id": "minecraft:jungle_hanging_sign" - }, - { - "id": "minecraft:acacia_hanging_sign" - }, - { - "id": "minecraft:dark_oak_hanging_sign" - }, - { - "id": "minecraft:mangrove_hanging_sign" - }, - { - "id": "minecraft:cherry_hanging_sign" - }, - { - "id": "minecraft:bamboo_hanging_sign" - }, - { - "id": "minecraft:crimson_hanging_sign" - }, - { - "id": "minecraft:warped_hanging_sign" - }, - { - "id": "minecraft:painting" - }, - { - "id": "minecraft:frame" - }, - { - "id": "minecraft:glow_frame" - }, - { - "id": "minecraft:honey_bottle" - }, - { - "id": "minecraft:flower_pot" - }, - { - "id": "minecraft:bowl" - }, - { - "id": "minecraft:bucket" - }, - { - "id": "minecraft:milk_bucket" - }, - { - "id": "minecraft:water_bucket" - }, - { - "id": "minecraft:lava_bucket" - }, - { - "id": "minecraft:cod_bucket" - }, - { - "id": "minecraft:salmon_bucket" - }, - { - "id": "minecraft:tropical_fish_bucket" - }, - { - "id": "minecraft:pufferfish_bucket" - }, - { - "id": "minecraft:powder_snow_bucket" - }, - { - "id": "minecraft:axolotl_bucket" - }, - { - "id": "minecraft:tadpole_bucket" - }, - { - "id": "minecraft:skull", - "damage": 3 - }, - { - "id": "minecraft:skull", - "damage": 2 - }, - { - "id": "minecraft:skull", - "damage": 4 - }, - { - "id": "minecraft:skull", - "damage": 5 - }, - { - "id": "minecraft:skull" - }, - { - "id": "minecraft:skull", - "damage": 1 - }, - { - "id": "minecraft:skull", - "damage": 6 - }, - { - "id": "minecraft:beacon", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OmJlYWNvbgQJAG5hbWVfaGFzaACwhhfSkdkHAwoAbmV0d29ya19pZF8jfiEKBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:bell", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0OmJlbGwECQBuYW1lX2hhc2iPqsgDXRcsxAMKAG5ldHdvcmtfaWT7zhOoCgYAc3RhdGVzCAoAYXR0YWNobWVudAgAc3RhbmRpbmcDCQBkaXJlY3Rpb24AAAAAAQoAdG9nZ2xlX2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:conduit", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OmNvbmR1aXQECQBuYW1lX2hhc2jqxKAxq2EaWQMKAG5ldHdvcmtfaWTWcBVnCgYAc3RhdGVzAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:stonecutter_block", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lY3V0dGVyX2Jsb2NrBAkAbmFtZV9oYXNoQAXTbAM3MeYDCgBuZXR3b3JrX2lkWS4RjAoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAG5vcnRoAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:end_portal_frame", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmVuZF9wb3J0YWxfZnJhbWUECQBuYW1lX2hhc2gqofyUIjGOpQMKAG5ldHdvcmtfaWRbGHf8CgYAc3RhdGVzARIAZW5kX3BvcnRhbF9leWVfYml0AAgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:coal" - }, - { - "id": "minecraft:charcoal" - }, - { - "id": "minecraft:diamond" - }, - { - "id": "minecraft:iron_nugget" - }, - { - "id": "minecraft:raw_iron" - }, - { - "id": "minecraft:raw_gold" - }, - { - "id": "minecraft:raw_copper" - }, - { - "id": "minecraft:copper_ingot" - }, - { - "id": "minecraft:iron_ingot" - }, - { - "id": "minecraft:netherite_scrap" - }, - { - "id": "minecraft:netherite_ingot" - }, - { - "id": "minecraft:gold_nugget" - }, - { - "id": "minecraft:gold_ingot" - }, - { - "id": "minecraft:emerald" - }, - { - "id": "minecraft:quartz" - }, - { - "id": "minecraft:clay_ball" - }, - { - "id": "minecraft:brick" - }, - { - "id": "minecraft:netherbrick" - }, - { - "id": "minecraft:prismarine_shard" - }, - { - "id": "minecraft:amethyst_shard" - }, - { - "id": "minecraft:prismarine_crystals" - }, - { - "id": "minecraft:nautilus_shell" - }, - { - "id": "minecraft:heart_of_the_sea" - }, - { - "id": "minecraft:scute" - }, - { - "id": "minecraft:phantom_membrane" - }, - { - "id": "minecraft:string" - }, - { - "id": "minecraft:feather" - }, - { - "id": "minecraft:flint" - }, - { - "id": "minecraft:gunpowder" - }, - { - "id": "minecraft:leather" - }, - { - "id": "minecraft:rabbit_hide" - }, - { - "id": "minecraft:rabbit_foot" - }, - { - "id": "minecraft:fire_charge" - }, - { - "id": "minecraft:blaze_rod" - }, - { - "id": "minecraft:blaze_powder" - }, - { - "id": "minecraft:magma_cream" - }, - { - "id": "minecraft:fermented_spider_eye" - }, - { - "id": "minecraft:echo_shard" - }, - { - "id": "minecraft:dragon_breath" - }, - { - "id": "minecraft:shulker_shell" - }, - { - "id": "minecraft:ghast_tear" - }, - { - "id": "minecraft:slime_ball" - }, - { - "id": "minecraft:ender_pearl" - }, - { - "id": "minecraft:ender_eye" - }, - { - "id": "minecraft:nether_star" - }, - { - "id": "minecraft:end_rod", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OmVuZF9yb2QECQBuYW1lX2hhc2jx/q5cEA0hmQMKAG5ldHdvcmtfaWQ2eM8kCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:lightning_rod", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmxpZ2h0bmluZ19yb2QECQBuYW1lX2hhc2ioXQF1xvfHNQMKAG5ldHdvcmtfaWRLuHyACgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:end_crystal" - }, - { - "id": "minecraft:paper" - }, - { - "id": "minecraft:book" - }, - { - "id": "minecraft:writable_book" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQFAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQFAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQFAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQGAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQGAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQGAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQHAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQHAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQHAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQIAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAUAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAUAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAUAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQMAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQMAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQNAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQNAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQOAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQOAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQOAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAUAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQQAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQRAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQRAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQRAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQSAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQSAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQSAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAUAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQUAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQUAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQVAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQWAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQXAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQXAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQXAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQYAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQYAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQYAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQZAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQZAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQaAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQbAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQcAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAUAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQeAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQeAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQeAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQfAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQfAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQfAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQgAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQhAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQjAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQjAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQjAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQkAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQkAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQkAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQlAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQlAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQlAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:oak_boat" - }, - { - "id": "minecraft:spruce_boat" - }, - { - "id": "minecraft:birch_boat" - }, - { - "id": "minecraft:jungle_boat" - }, - { - "id": "minecraft:acacia_boat" - }, - { - "id": "minecraft:dark_oak_boat" - }, - { - "id": "minecraft:mangrove_boat" - }, - { - "id": "minecraft:cherry_boat" - }, - { - "id": "minecraft:bamboo_raft" - }, - { - "id": "minecraft:oak_chest_boat" - }, - { - "id": "minecraft:spruce_chest_boat" - }, - { - "id": "minecraft:birch_chest_boat" - }, - { - "id": "minecraft:jungle_chest_boat" - }, - { - "id": "minecraft:acacia_chest_boat" - }, - { - "id": "minecraft:dark_oak_chest_boat" - }, - { - "id": "minecraft:mangrove_chest_boat" - }, - { - "id": "minecraft:cherry_chest_boat" - }, - { - "id": "minecraft:bamboo_chest_raft" - }, - { - "id": "minecraft:rail", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0OnJhaWwECQBuYW1lX2hhc2hUzmhUXYJDUQMKAG5ldHdvcmtfaWR+Sp6YCgYAc3RhdGVzAw4AcmFpbF9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:golden_rail", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmdvbGRlbl9yYWlsBAkAbmFtZV9oYXNoOoV5MaKipoUDCgBuZXR3b3JrX2lkfAcxLwoGAHN0YXRlcwENAHJhaWxfZGF0YV9iaXQAAw4AcmFpbF9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:detector_rail", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmRldGVjdG9yX3JhaWwECQBuYW1lX2hhc2gVUk31qOysUQMKAG5ldHdvcmtfaWRVW/aICgYAc3RhdGVzAQ0AcmFpbF9kYXRhX2JpdAADDgByYWlsX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:activator_rail", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmFjdGl2YXRvcl9yYWlsBAkAbmFtZV9oYXNosIL91qriCRkDCgBuZXR3b3JrX2lkZfckmwoGAHN0YXRlcwENAHJhaWxfZGF0YV9iaXQAAw4AcmFpbF9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:minecart" - }, - { - "id": "minecraft:chest_minecart" - }, - { - "id": "minecraft:hopper_minecart" - }, - { - "id": "minecraft:tnt_minecart" - }, - { - "id": "minecraft:redstone" - }, - { - "id": "minecraft:redstone_block", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OnJlZHN0b25lX2Jsb2NrBAkAbmFtZV9oYXNoRhULL0r8o0sDCgBuZXR3b3JrX2lklayOHgoGAHN0YXRlcwADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:redstone_torch", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OnJlZHN0b25lX3RvcmNoBAkAbmFtZV9oYXNoizFRjpYMIDgDCgBuZXR3b3JrX2lkuHz7yAoGAHN0YXRlcwgWAHRvcmNoX2ZhY2luZ19kaXJlY3Rpb24HAHVua25vd24AAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:lever", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OmxldmVyBAkAbmFtZV9oYXNoGMJeLJsUMLYDCgBuZXR3b3JrX2lkEF/GuAoGAHN0YXRlcwgPAGxldmVyX2RpcmVjdGlvbg4AZG93bl9lYXN0X3dlc3QBCABvcGVuX2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:wooden_button", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0Ondvb2Rlbl9idXR0b24ECQBuYW1lX2hhc2hR7PgSTQt0sQMKAG5ldHdvcmtfaWSU07kYCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:spruce_button", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9idXR0b24ECQBuYW1lX2hhc2jBW9Z8aYE7YQMKAG5ldHdvcmtfaWTkUIGuCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:birch_button", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX2J1dHRvbgQJAG5hbWVfaGFzaJXYgGuSHbTwAwoAbmV0d29ya19pZGWp3yoKBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:jungle_button", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9idXR0b24ECQBuYW1lX2hhc2iCgNANcJs+BQMKAG5ldHdvcmtfaWT9fImWCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:acacia_button", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9idXR0b24ECQBuYW1lX2hhc2gVvmcT7LTO0wMKAG5ldHdvcmtfaWRQnxIJCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:dark_oak_button", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX2J1dHRvbgQJAG5hbWVfaGFzaIV10ZGGrCIEAwoAbmV0d29ya19pZN5vAmIKBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:mangrove_button", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX2J1dHRvbgQJAG5hbWVfaGFzaNzeYYKLgOzJAwoAbmV0d29ya19pZAFEGQ0KBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:cherry_button", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9idXR0b24ECQBuYW1lX2hhc2j2/IHjeAbUcwMKAG5ldHdvcmtfaWRJ1irQCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:bamboo_button", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19idXR0b24ECQBuYW1lX2hhc2j7AddMi+6nsgMKAG5ldHdvcmtfaWSa9w4/CgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:stone_button", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnN0b25lX2J1dHRvbgQJAG5hbWVfaGFzaM4ejMctmvohAwoAbmV0d29ya19pZMw+aC0KBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:crimson_button", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fYnV0dG9uBAkAbmFtZV9oYXNofnjYHaYIeWgDCgBuZXR3b3JrX2lk+n1vyQoGAHN0YXRlcwESAGJ1dHRvbl9wcmVzc2VkX2JpdAADEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:warped_button", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9idXR0b24ECQBuYW1lX2hhc2jwkV2EU6Cn1QMKAG5ldHdvcmtfaWTnHnk1CgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:polished_blackstone_button", - "block_state_b64": "CgAACAQAbmFtZSQAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnV0dG9uBAkAbmFtZV9oYXNojmxzQKS0S/EDCgBuZXR3b3JrX2lkDtQ95woGAHN0YXRlcwESAGJ1dHRvbl9wcmVzc2VkX2JpdAADEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:tripwire_hook", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnRyaXB3aXJlX2hvb2sECQBuYW1lX2hhc2gQdp+oGZLNnAMKAG5ldHdvcmtfaWSy+1KJCgYAc3RhdGVzAQwAYXR0YWNoZWRfYml0AAMJAGRpcmVjdGlvbgAAAAABCwBwb3dlcmVkX2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:wooden_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0Ondvb2Rlbl9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaGkGs5kCuA74AwoAbmV0d29ya19pZDRzPNwKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:spruce_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OnNwcnVjZV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaNmwuq549fJKAwoAbmV0d29ya19pZLQMCw0KBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:birch_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OmJpcmNoX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNorQkT9kDdlTwDCgBuZXR3b3JrX2lkH0G97AoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:jungle_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0Omp1bmdsZV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaJ7DcteCkb8/AwoAbmV0d29ya19pZLdPBSAKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:acacia_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OmFjYWNpYV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaC2frZtfoYqCAwoAbmV0d29ya19pZIDdI18KBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:dark_oak_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OmRhcmtfb2FrX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoHUCJsTy52pwDCgBuZXR3b3JrX2lkKpi8rAoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:mangrove_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0Om1hbmdyb3ZlX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoiDsTfJaX100DCgBuZXR3b3JrX2lkuwWDyQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:cherry_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OmNoZXJyeV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaALMqYEZDUQHAwoAbmV0d29ya19pZPNT+r0KBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:bamboo_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OmJhbWJvb19wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaNvxJ7NIAaqlAwoAbmV0d29ya19pZIZ8XnYKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:crimson_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmNyaW1zb25fcHJlc3N1cmVfcGxhdGUECQBuYW1lX2hhc2hqBDVDAd31/gMKAG5ldHdvcmtfaWRmV18LCgYAc3RhdGVzAw8AcmVkc3RvbmVfc2lnbmFsAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:warped_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OndhcnBlZF9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaBxFoQksWtYUAwoAbmV0d29ya19pZJVRoIcKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:stone_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OnN0b25lX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNounJuTBUTrU8DCgBuZXR3b3JrX2lkjDydwQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:light_weighted_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZScAbWluZWNyYWZ0OmxpZ2h0X3dlaWdodGVkX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoOyOJkNxLtkEDCgBuZXR3b3JrX2lkrr2AjgoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:heavy_weighted_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZScAbWluZWNyYWZ0OmhlYXZ5X3dlaWdodGVkX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoltgDmDvTajUDCgBuZXR3b3JrX2lkFxVKuQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:polished_blackstone_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZSwAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfcHJlc3N1cmVfcGxhdGUECQBuYW1lX2hhc2h65Ci6/CeGqwMKAG5ldHdvcmtfaWTaSW5xCgYAc3RhdGVzAw8AcmVkc3RvbmVfc2lnbmFsAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:observer", - "block_state_b64": "CgAACAQAbmFtZRIAbWluZWNyYWZ0Om9ic2VydmVyBAkAbmFtZV9oYXNoYhlh1lpmHTgDCgBuZXR3b3JrX2lkQEh55goGAHN0YXRlcwgaAG1pbmVjcmFmdDpmYWNpbmdfZGlyZWN0aW9uBABkb3duAQsAcG93ZXJlZF9iaXQAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:daylight_detector", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmRheWxpZ2h0X2RldGVjdG9yBAkAbmFtZV9oYXNoV0F0s7B7PVgDCgBuZXR3b3JrX2lkri5afQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:repeater" - }, - { - "id": "minecraft:comparator" - }, - { - "id": "minecraft:hopper" - }, - { - "id": "minecraft:dropper", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OmRyb3BwZXIECQBuYW1lX2hhc2joXP7XqU0l3QMKAG5ldHdvcmtfaWQfQN6zCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgMAAAABDQB0cmlnZ2VyZWRfYml0AAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:dispenser", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmRpc3BlbnNlcgQJAG5hbWVfaGFzaP1RR+zAbYP2AwoAbmV0d29ya19pZGAayD0KBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAwAAAAENAHRyaWdnZXJlZF9iaXQAAAMHAHZlcnNpb24DKBQBAA==" - }, - { - "id": "minecraft:piston", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OnBpc3RvbgQJAG5hbWVfaGFzaDs3AFh1fL0uAwoAbmV0d29ya19pZLD/5XQKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAQAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:sticky_piston", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnN0aWNreV9waXN0b24ECQBuYW1lX2hhc2hPFJFJSiJ0ZQMKAG5ldHdvcmtfaWT/MzCJCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgEAAAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:tnt", - "block_state_b64": "CgAACAQAbmFtZQ0AbWluZWNyYWZ0OnRudAQJAG5hbWVfaGFzaEYOHwCvJH29AwoAbmV0d29ya19pZCGfjU4KBgBzdGF0ZXMBFABhbGxvd191bmRlcndhdGVyX2JpdAABCwBleHBsb2RlX2JpdAAAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:name_tag" - }, - { - "id": "minecraft:loom", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0Omxvb20ECQBuYW1lX2hhc2i7DKjAXNq8TAMKAG5ldHdvcmtfaWR/49HXCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:banner" - }, - { - "id": "minecraft:banner", - "damage": 8 - }, - { - "id": "minecraft:banner", - "damage": 7 - }, - { - "id": "minecraft:banner", - "damage": 15 - }, - { - "id": "minecraft:banner", - "damage": 12 - }, - { - "id": "minecraft:banner", - "damage": 14 - }, - { - "id": "minecraft:banner", - "damage": 1 - }, - { - "id": "minecraft:banner", - "damage": 4 - }, - { - "id": "minecraft:banner", - "damage": 5 - }, - { - "id": "minecraft:banner", - "damage": 13 - }, - { - "id": "minecraft:banner", - "damage": 9 - }, - { - "id": "minecraft:banner", - "damage": 3 - }, - { - "id": "minecraft:banner", - "damage": 11 - }, - { - "id": "minecraft:banner", - "damage": 10 - }, - { - "id": "minecraft:banner", - "damage": 2 - }, - { - "id": "minecraft:banner", - "damage": 6 - }, - { - "id": "minecraft:banner", - "damage": 15, - "nbt_b64": "CgAAAwQAVHlwZQEAAAAA" - }, - { - "id": "minecraft:creeper_banner_pattern" - }, - { - "id": "minecraft:skull_banner_pattern" - }, - { - "id": "minecraft:flower_banner_pattern" - }, - { - "id": "minecraft:mojang_banner_pattern" - }, - { - "id": "minecraft:field_masoned_banner_pattern" - }, - { - "id": "minecraft:bordure_indented_banner_pattern" - }, - { - "id": "minecraft:piglin_banner_pattern" - }, - { - "id": "minecraft:globe_banner_pattern" - }, - { - "id": "minecraft:angler_pottery_sherd" - }, - { - "id": "minecraft:archer_pottery_sherd" - }, - { - "id": "minecraft:arms_up_pottery_sherd" - }, - { - "id": "minecraft:blade_pottery_sherd" - }, - { - "id": "minecraft:brewer_pottery_sherd" - }, - { - "id": "minecraft:burn_pottery_sherd" - }, - { - "id": "minecraft:danger_pottery_sherd" - }, - { - "id": "minecraft:explorer_pottery_sherd" - }, - { - "id": "minecraft:friend_pottery_sherd" - }, - { - "id": "minecraft:heart_pottery_sherd" - }, - { - "id": "minecraft:heartbreak_pottery_sherd" - }, - { - "id": "minecraft:howl_pottery_sherd" - }, - { - "id": "minecraft:miner_pottery_sherd" - }, - { - "id": "minecraft:mourner_pottery_sherd" - }, - { - "id": "minecraft:plenty_pottery_sherd" - }, - { - "id": "minecraft:prize_pottery_sherd" - }, - { - "id": "minecraft:sheaf_pottery_sherd" - }, - { - "id": "minecraft:shelter_pottery_sherd" - }, - { - "id": "minecraft:skull_pottery_sherd" - }, - { - "id": "minecraft:snort_pottery_sherd" - }, - { - "id": "minecraft:netherite_upgrade_smithing_template" - }, - { - "id": "minecraft:sentry_armor_trim_smithing_template" - }, - { - "id": "minecraft:vex_armor_trim_smithing_template" - }, - { - "id": "minecraft:wild_armor_trim_smithing_template" - }, - { - "id": "minecraft:coast_armor_trim_smithing_template" - }, - { - "id": "minecraft:dune_armor_trim_smithing_template" - }, - { - "id": "minecraft:wayfinder_armor_trim_smithing_template" - }, - { - "id": "minecraft:shaper_armor_trim_smithing_template" - }, - { - "id": "minecraft:raiser_armor_trim_smithing_template" - }, - { - "id": "minecraft:host_armor_trim_smithing_template" - }, - { - "id": "minecraft:ward_armor_trim_smithing_template" - }, - { - "id": "minecraft:silence_armor_trim_smithing_template" - }, - { - "id": "minecraft:tide_armor_trim_smithing_template" - }, - { - "id": "minecraft:snout_armor_trim_smithing_template" - }, - { - "id": "minecraft:rib_armor_trim_smithing_template" - }, - { - "id": "minecraft:eye_armor_trim_smithing_template" - }, - { - "id": "minecraft:spire_armor_trim_smithing_template" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwAAAAAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAABwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAIBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAHBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAPBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAMBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAOBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAABBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAEBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAFBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAANBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAJBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAADBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAALBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAKBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAACBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAGBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_star", - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yIR0d/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 8, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yUk9H/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 7, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yl52d/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 15, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9y8PDw/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 12, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9y2rM6/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 14, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yHYD5/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 1, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yJi6w/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 4, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yqkQ8/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 5, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yuDKJ/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 13, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yvU7H/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 9, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yqovz/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 3, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yMlSD/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 11, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yPdj+/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 10, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yH8eA/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 2, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yFnxe/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 6, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9ynJwW/wA=" - }, - { - "id": "minecraft:chain" - }, - { - "id": "minecraft:target", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OnRhcmdldAQJAG5hbWVfaGFzaJc66SVbYlaxAwoAbmV0d29ya19pZPBozs0KBgBzdGF0ZXMAAwcAdmVyc2lvbgMoFAEA" - }, - { - "id": "minecraft:decorated_pot", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmRlY29yYXRlZF9wb3QECQBuYW1lX2hhc2jjQgckn8VTvwMKAG5ldHdvcmtfaWRwvkUUCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAygUAQA=" - }, - { - "id": "minecraft:lodestone_compass" - }, - { - "id": "minecraft:wither_spawn_egg" - }, - { - "id": "minecraft:ender_dragon_spawn_egg" - } - ] -} \ No newline at end of file diff --git a/core/src/main/resources/bedrock/creative_items.1_20_50.json b/core/src/main/resources/bedrock/creative_items.1_20_50.json deleted file mode 100644 index d93aa4c00..000000000 --- a/core/src/main/resources/bedrock/creative_items.1_20_50.json +++ /dev/null @@ -1,5995 +0,0 @@ -{ - "items": [ - { - "id": "minecraft:oak_planks", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0Om9ha19wbGFua3MECQBuYW1lX2hhc2ilMDLR92rQ4wMKAG5ldHdvcmtfaWS2GotyCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:spruce_planks", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9wbGFua3MECQBuYW1lX2hhc2iumBkmFGFE8gMKAG5ldHdvcmtfaWSo8TFgCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:birch_planks", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX3BsYW5rcwQJAG5hbWVfaGFzaLrrAKJqV2WFAwoAbmV0d29ya19pZL+e3ZAKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:jungle_planks", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9wbGFua3MECQBuYW1lX2hhc2iBM3k4T3FAugMKAG5ldHdvcmtfaWSXUmBCCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:acacia_planks", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9wbGFua3MECQBuYW1lX2hhc2g60edJxO5/aAMKAG5ldHdvcmtfaWTUXozECgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:dark_oak_planks", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX3BsYW5rcwQJAG5hbWVfaGFzaAr64wkQ9cA7AwoAbmV0d29ya19pZFbMeR0KBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:mangrove_planks", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX3BsYW5rcwQJAG5hbWVfaGFzaPvLtcEA0F8xAwoAbmV0d29ya19pZEvnlCYKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:cherry_planks", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9wbGFua3MECQBuYW1lX2hhc2hNIvVh/lVW7gMKAG5ldHdvcmtfaWQTXpRoCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:bamboo_planks", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19wbGFua3MECQBuYW1lX2hhc2gYnjNz7SCCjgMKAG5ldHdvcmtfaWTi8ySSCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:bamboo_mosaic", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19tb3NhaWMECQBuYW1lX2hhc2izSEgiMKOp/AMKAG5ldHdvcmtfaWQZ/p8xCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:crimson_planks", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fcGxhbmtzBAkAbmFtZV9oYXNoJc5IKqNXJnwDCgBuZXR3b3JrX2lkwtJDdQoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:warped_planks", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9wbGFua3MECQBuYW1lX2hhc2g3yGXEWhe6LgMKAG5ldHdvcmtfaWStTABvCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWSE4JosCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCwBjb2JibGVzdG9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWTUvV6XCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlEQBtb3NzeV9jb2JibGVzdG9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWT4opb2CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlBwBncmFuaXRlCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQAMQTVCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlBwBkaW9yaXRlCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQIbDOcCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCABhbmRlc2l0ZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWSZKhusCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCQBzYW5kc3RvbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWSp4zgCCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlDQByZWRfc2FuZHN0b25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRbqVHTCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCwBzdG9uZV9icmljawgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRr0ZT/CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlEQBtb3NzeV9zdG9uZV9icmljawgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRnLis3CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlBQBicmljawgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQNLzfSCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlDABuZXRoZXJfYnJpY2sIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQ5h0xwCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlEAByZWRfbmV0aGVyX2JyaWNrCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWS9J0B2CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCQBlbmRfYnJpY2sIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRPbkJeCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCgBwcmlzbWFyaW5lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:blackstone_wall", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmJsYWNrc3RvbmVfd2FsbAQJAG5hbWVfaGFzaMP8XppUSU1RAwoAbmV0d29ya19pZMbeBBsKBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:polished_blackstone_wall", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfd2FsbAQJAG5hbWVfaGFzaP6SwV08YwzAAwoAbmV0d29ya19pZAJLsz8KBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:polished_blackstone_brick_wall", - "block_state_b64": "CgAACAQAbmFtZSgAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tfd2FsbAQJAG5hbWVfaGFzaBBIDZbHxiEzAwoAbmV0d29ya19pZEbLV8cKBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:cobbled_deepslate_wall", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlX3dhbGwECQBuYW1lX2hhc2iECY5oKxeT+gMKAG5ldHdvcmtfaWRCnPrFCgYAc3RhdGVzCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:deepslate_tile_wall", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlX3dhbGwECQBuYW1lX2hhc2jz7N+PeuEXgQMKAG5ldHdvcmtfaWTqw4s4CgYAc3RhdGVzCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:polished_deepslate_wall", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZV93YWxsBAkAbmFtZV9oYXNoHxjTdj9pevMDCgBuZXR3b3JrX2lkIvBYYwoGAHN0YXRlcwgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:deepslate_brick_wall", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja193YWxsBAkAbmFtZV9oYXNoEs3EQrjroyEDCgBuZXR3b3JrX2lkwlrCGwoGAHN0YXRlcwgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:mud_brick_wall", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0Om11ZF9icmlja193YWxsBAkAbmFtZV9oYXNov9b98ATpUSwDCgBuZXR3b3JrX2lkH/1WZQoGAHN0YXRlcwgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:oak_fence", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0Om9ha19mZW5jZQQJAG5hbWVfaGFzaGEmid7AaCWRAwoAbmV0d29ya19pZDvPEXcKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:spruce_fence", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnNwcnVjZV9mZW5jZQQJAG5hbWVfaGFzaPQCm+aX1ZQeAwoAbmV0d29ya19pZD1QUEoKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:birch_fence", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmJpcmNoX2ZlbmNlBAkAbmFtZV9oYXNo6CJ2ATpANfgDCgBuZXR3b3JrX2lkmCUV2QoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:jungle_fence", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0Omp1bmdsZV9mZW5jZQQJAG5hbWVfaGFzaOX4cD9uAmsdAwoAbmV0d29ya19pZHz1VxkKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:acacia_fence", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmFjYWNpYV9mZW5jZQQJAG5hbWVfaGFzaGjn+RlKVDH6AwoAbmV0d29ya19pZNVGubwKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:dark_oak_fence", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmRhcmtfb2FrX2ZlbmNlBAkAbmFtZV9oYXNoGPj0gCgM0c0DCgBuZXR3b3JrX2lk2w+gEwoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:mangrove_fence", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0Om1hbmdyb3ZlX2ZlbmNlBAkAbmFtZV9oYXNowwAd7tPu9bsDCgBuZXR3b3JrX2lkKEcd0goGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:cherry_fence", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmNoZXJyeV9mZW5jZQQJAG5hbWVfaGFzaFmtUfHfTxcxAwoAbmV0d29ya19pZPCBxAIKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:bamboo_fence", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmJhbWJvb19mZW5jZQQJAG5hbWVfaGFzaCKRbxfXsfkiAwoAbmV0d29ya19pZJNXKFcKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:nether_brick_fence", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0Om5ldGhlcl9icmlja19mZW5jZQQJAG5hbWVfaGFzaA6030ngawxcAwoAbmV0d29ya19pZLnjLF4KBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:crimson_fence", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmNyaW1zb25fZmVuY2UECQBuYW1lX2hhc2jhUhKv1HGj9AMKAG5ldHdvcmtfaWR3OH3OCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:warped_fence", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OndhcnBlZF9mZW5jZQQJAG5hbWVfaGFzaJfb3/YuKmOWAwoAbmV0d29ya19pZCpaGC8KBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:fence_gate", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmZlbmNlX2dhdGUECQBuYW1lX2hhc2hTxpjEDmRzAwMKAG5ldHdvcmtfaWR+T9kTCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:spruce_fence_gate", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnNwcnVjZV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoanTVB84HRbkDCgBuZXR3b3JrX2lkEnw5egoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:birch_fence_gate", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmJpcmNoX2ZlbmNlX2dhdGUECQBuYW1lX2hhc2jmfPklI8azSwMKAG5ldHdvcmtfaWQL77/BCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:jungle_fence_gate", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0Omp1bmdsZV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNobYVQkfBomIcDCgBuZXR3b3JrX2lkA1zgtgoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:acacia_fence_gate", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmFjYWNpYV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoZnrLUx/XSekDCgBuZXR3b3JrX2lkHg/kTgoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:dark_oak_fence_gate", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OmRhcmtfb2FrX2ZlbmNlX2dhdGUECQBuYW1lX2hhc2j2PTvdJJHcVQMKAG5ldHdvcmtfaWTwjOCeCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:mangrove_fence_gate", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0Om1hbmdyb3ZlX2ZlbmNlX2dhdGUECQBuYW1lX2hhc2i/kOhBKiI/dAMKAG5ldHdvcmtfaWSfweCSCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:cherry_fence_gate", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmNoZXJyeV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoKWLgCk0z+PsDCgBuZXR3b3JrX2lk/9bTZQoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:bamboo_fence_gate", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmJhbWJvb19mZW5jZV9nYXRlBAkAbmFtZV9oYXNopH1JrUgwdIADCgBuZXR3b3JrX2lkzIpPywoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:crimson_fence_gate", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmNyaW1zb25fZmVuY2VfZ2F0ZQQJAG5hbWVfaGFzaHE3Gfd0Z2d2AwoAbmV0d29ya19pZDQzVbEKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQsAaW5fd2FsbF9iaXQAAQgAb3Blbl9iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:warped_fence_gate", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OndhcnBlZF9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoy0oIBjDIG4kDCgBuZXR3b3JrX2lkkf+/3QoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:normal_stone_stairs", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0Om5vcm1hbF9zdG9uZV9zdGFpcnMECQBuYW1lX2hhc2hAEktZZOkGIwMKAG5ldHdvcmtfaWQeH1ALCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:stone_stairs", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnN0b25lX3N0YWlycwQJAG5hbWVfaGFzaNRjqVC5GRVDAwoAbmV0d29ya19pZDcCv+MKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:mossy_cobblestone_stairs", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0Om1vc3N5X2NvYmJsZXN0b25lX3N0YWlycwQJAG5hbWVfaGFzaMVSTq5z9n1RAwoAbmV0d29ya19pZFIfrhkKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:oak_stairs", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0Om9ha19zdGFpcnMECQBuYW1lX2hhc2jk/HFzdXy0FQMKAG5ldHdvcmtfaWQJjyzBCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:spruce_stairs", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9zdGFpcnMECQBuYW1lX2hhc2iznygw7uBPBQMKAG5ldHdvcmtfaWTv+is3CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:birch_stairs", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX3N0YWlycwQJAG5hbWVfaGFzaPfhbL619a3GAwoAbmV0d29ya19pZFyPlHAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:jungle_stairs", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9zdGFpcnMECQBuYW1lX2hhc2jodJsHUbOVxQMKAG5ldHdvcmtfaWR0z5d4CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:acacia_stairs", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9zdGFpcnMECQBuYW1lX2hhc2h3x1NmD43IqQMKAG5ldHdvcmtfaWS7Jwz6CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:dark_oak_stairs", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX3N0YWlycwQJAG5hbWVfaGFzaMfwkbYPbNmAAwoAbmV0d29ya19pZCmBYKAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:mangrove_stairs", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX3N0YWlycwQJAG5hbWVfaGFzaNpUDY+uGMpyAwoAbmV0d29ya19pZChzUAsKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:cherry_stairs", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9zdGFpcnMECQBuYW1lX2hhc2jMtr0v9JY4zwMKAG5ldHdvcmtfaWRQwq31CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:bamboo_stairs", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19zdGFpcnMECQBuYW1lX2hhc2jFOzWL8PalKwMKAG5ldHdvcmtfaWTVPh42CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:bamboo_mosaic_stairs", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OmJhbWJvb19tb3NhaWNfc3RhaXJzBAkAbmFtZV9oYXNoNLPiveSHPaoDCgBuZXR3b3JrX2lk44PHjgoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:stone_brick_stairs", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OnN0b25lX2JyaWNrX3N0YWlycwQJAG5hbWVfaGFzaN6tQViRo5cwAwoAbmV0d29ya19pZDMyMgIKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:mossy_stone_brick_stairs", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0Om1vc3N5X3N0b25lX2JyaWNrX3N0YWlycwQJAG5hbWVfaGFzaIB/Zv5YBPuYAwoAbmV0d29ya19pZANTOsMKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:sandstone_stairs", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OnNhbmRzdG9uZV9zdGFpcnMECQBuYW1lX2hhc2hOyA0BoYUOPQMKAG5ldHdvcmtfaWSV/834CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:smooth_sandstone_stairs", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OnNtb290aF9zYW5kc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNoB+CuCd8Ruz8DCgBuZXR3b3JrX2lksR+m8QoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:red_sandstone_stairs", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNoPs0LpHPL24YDCgBuZXR3b3JrX2lkLYVt3woGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:smooth_red_sandstone_stairs", - "block_state_b64": "CgAACAQAbmFtZSUAbWluZWNyYWZ0OnNtb290aF9yZWRfc2FuZHN0b25lX3N0YWlycwQJAG5hbWVfaGFzaBvjtQv5pf+MAwoAbmV0d29ya19pZMHNND8KBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:granite_stairs", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmdyYW5pdGVfc3RhaXJzBAkAbmFtZV9oYXNoGzpvtoqKQjgDCgBuZXR3b3JrX2lkPkcB1goGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:polished_granite_stairs", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2dyYW5pdGVfc3RhaXJzBAkAbmFtZV9oYXNo3PvbSfEQklIDCgBuZXR3b3JrX2lkMmEm3AoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:diorite_stairs", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmRpb3JpdGVfc3RhaXJzBAkAbmFtZV9oYXNoi73T8VQuZmcDCgBuZXR3b3JrX2lk6i6nBQoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:polished_diorite_stairs", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2Rpb3JpdGVfc3RhaXJzBAkAbmFtZV9oYXNoFKRJd5Wk5L0DCgBuZXR3b3JrX2lkbt2ioAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:andesite_stairs", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmFuZGVzaXRlX3N0YWlycwQJAG5hbWVfaGFzaO5w2FKBw76EAwoAbmV0d29ya19pZKhXEgUKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:polished_andesite_stairs", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OnBvbGlzaGVkX2FuZGVzaXRlX3N0YWlycwQJAG5hbWVfaGFzaNcZZ/zmLInIAwoAbmV0d29ya19pZJTHrlEKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:brick_stairs", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmJyaWNrX3N0YWlycwQJAG5hbWVfaGFzaMyt+cRDk5O2AwoAbmV0d29ya19pZNeMh58KBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:nether_brick_stairs", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0Om5ldGhlcl9icmlja19zdGFpcnMECQBuYW1lX2hhc2jRqIoOXgifBAMKAG5ldHdvcmtfaWQDiw5yCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:red_nether_brick_stairs", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OnJlZF9uZXRoZXJfYnJpY2tfc3RhaXJzBAkAbmFtZV9oYXNogQvosSbcj7kDCgBuZXR3b3JrX2lkx2IMtAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:end_brick_stairs", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmVuZF9icmlja19zdGFpcnMECQBuYW1lX2hhc2hmlAk+QhsUsQMKAG5ldHdvcmtfaWTN7KFaCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:quartz_stairs", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnF1YXJ0el9zdGFpcnMECQBuYW1lX2hhc2hmvpvOqGi6egMKAG5ldHdvcmtfaWRmUTh7CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:smooth_quartz_stairs", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OnNtb290aF9xdWFydHpfc3RhaXJzBAkAbmFtZV9oYXNoNZZ9rX0qZOsDCgBuZXR3b3JrX2lkzsgQyQoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:purpur_stairs", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnB1cnB1cl9zdGFpcnMECQBuYW1lX2hhc2ifwDxeezXD7gMKAG5ldHdvcmtfaWTT+rxiCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:prismarine_stairs", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnByaXNtYXJpbmVfc3RhaXJzBAkAbmFtZV9oYXNooTHSZ+IrYtcDCgBuZXR3b3JrX2lkxTJfeAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:dark_prismarine_stairs", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmRhcmtfcHJpc21hcmluZV9zdGFpcnMECQBuYW1lX2hhc2hIciLmam4o4AMKAG5ldHdvcmtfaWTVu7TCCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:prismarine_bricks_stairs", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OnByaXNtYXJpbmVfYnJpY2tzX3N0YWlycwQJAG5hbWVfaGFzaNIjq1oBlZMMAwoAbmV0d29ya19pZGEFwLYKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:crimson_stairs", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fc3RhaXJzBAkAbmFtZV9oYXNoZJqIzCBpCq4DCgBuZXR3b3JrX2lktXE00AoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:warped_stairs", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9zdGFpcnMECQBuYW1lX2hhc2hOkY27jLD4RQMKAG5ldHdvcmtfaWQ+E5VrCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:blackstone_stairs", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmJsYWNrc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNokdoUb76p9McDCgBuZXR3b3JrX2lk5fWI5goGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:polished_blackstone_stairs", - "block_state_b64": "CgAACAQAbmFtZSQAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNolCFtFIE8MmADCgBuZXR3b3JrX2lkGTf7sgoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:polished_blackstone_brick_stairs", - "block_state_b64": "CgAACAQAbmFtZSoAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tfc3RhaXJzBAkAbmFtZV9oYXNonks6UlfpOmkDCgBuZXR3b3JrX2lkgYeOdAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:cut_copper_stairs", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmN1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNoHfoAXYq5G3MDCgBuZXR3b3JrX2lkeetf7woGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:exposed_cut_copper_stairs", - "block_state_b64": "CgAACAQAbmFtZSMAbWluZWNyYWZ0OmV4cG9zZWRfY3V0X2NvcHBlcl9zdGFpcnMECQBuYW1lX2hhc2howneQGtZ9cgMKAG5ldHdvcmtfaWSg73zdCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:weathered_cut_copper_stairs", - "block_state_b64": "CgAACAQAbmFtZSUAbWluZWNyYWZ0OndlYXRoZXJlZF9jdXRfY29wcGVyX3N0YWlycwQJAG5hbWVfaGFzaP+R5loXxrVgAwoAbmV0d29ya19pZOnbRf4KBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:oxidized_cut_copper_stairs", - "block_state_b64": "CgAACAQAbmFtZSQAbWluZWNyYWZ0Om94aWRpemVkX2N1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNo6Jeoq5rsPxsDCgBuZXR3b3JrX2lkmRjDnQoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:waxed_cut_copper_stairs", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OndheGVkX2N1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNoh07CQj0/SR8DCgBuZXR3b3JrX2lkmYqoqAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:waxed_exposed_cut_copper_stairs", - "block_state_b64": "CgAACAQAbmFtZSkAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY3V0X2NvcHBlcl9zdGFpcnMECQBuYW1lX2hhc2guVct1ilmxTwMKAG5ldHdvcmtfaWQgCPROCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:waxed_weathered_cut_copper_stairs", - "block_state_b64": "CgAACAQAbmFtZSsAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jdXRfY29wcGVyX3N0YWlycwQJAG5hbWVfaGFzaPXC8Sz/phCpAwoAbmV0d29ya19pZHlwHVsKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:waxed_oxidized_cut_copper_stairs", - "block_state_b64": "CgAACAQAbmFtZSoAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2N1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNoaqGdkuhxVZUDCgBuZXR3b3JrX2lkYQXzzgoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:cobbled_deepslate_stairs", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlX3N0YWlycwQJAG5hbWVfaGFzaPIfa+TpyJcIAwoAbmV0d29ya19pZJUvOYIKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:deepslate_tile_stairs", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlX3N0YWlycwQJAG5hbWVfaGFzaGFRFzB72mN2AwoAbmV0d29ya19pZJEOgIsKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:polished_deepslate_stairs", - "block_state_b64": "CgAACAQAbmFtZSMAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZV9zdGFpcnMECQBuYW1lX2hhc2iNCYxVik9sGAMKAG5ldHdvcmtfaWSRVPnYCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:deepslate_brick_stairs", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja19zdGFpcnMECQBuYW1lX2hhc2hIasOahEf83wMKAG5ldHdvcmtfaWQ1qEDCCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:mud_brick_stairs", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0Om11ZF9icmlja19zdGFpcnMECQBuYW1lX2hhc2gt3qxK1NWajAMKAG5ldHdvcmtfaWSm9N3MCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:wooden_door" - }, - { - "id": "minecraft:spruce_door" - }, - { - "id": "minecraft:birch_door" - }, - { - "id": "minecraft:jungle_door" - }, - { - "id": "minecraft:acacia_door" - }, - { - "id": "minecraft:dark_oak_door" - }, - { - "id": "minecraft:mangrove_door" - }, - { - "id": "minecraft:cherry_door" - }, - { - "id": "minecraft:bamboo_door" - }, - { - "id": "minecraft:iron_door" - }, - { - "id": "minecraft:crimson_door" - }, - { - "id": "minecraft:warped_door" - }, - { - "id": "minecraft:trapdoor", - "block_state_b64": "CgAACAQAbmFtZRIAbWluZWNyYWZ0OnRyYXBkb29yBAkAbmFtZV9oYXNotYiAJGtN0xADCgBuZXR3b3JrX2lkyTAWkAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:spruce_trapdoor", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OnNwcnVjZV90cmFwZG9vcgQJAG5hbWVfaGFzaOwlfbgBkUW4AwoAbmV0d29ya19pZPHy1K0KBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:birch_trapdoor", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmJpcmNoX3RyYXBkb29yBAkAbmFtZV9oYXNoSLtLweOLJ7wDCgBuZXR3b3JrX2lkeJWDfgoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:jungle_trapdoor", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0Omp1bmdsZV90cmFwZG9vcgQJAG5hbWVfaGFzaDP/TnM9wyCIAwoAbmV0d29ya19pZEy2fJoKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:acacia_trapdoor", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmFjYWNpYV90cmFwZG9vcgQJAG5hbWVfaGFzaMj8xi3vmEKOAwoAbmV0d29ya19pZOHj8E8KBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:dark_oak_trapdoor", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmRhcmtfb2FrX3RyYXBkb29yBAkAbmFtZV9oYXNomB2GGJQ2aOMDCgBuZXR3b3JrX2lko5ZHTwoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:mangrove_trapdoor", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0Om1hbmdyb3ZlX3RyYXBkb29yBAkAbmFtZV9oYXNooV3kQsQUUmkDCgBuZXR3b3JrX2lkkF/mxAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:cherry_trapdoor", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmNoZXJyeV90cmFwZG9vcgQJAG5hbWVfaGFzaH/PefpfdHgtAwoAbmV0d29ya19pZOA7eNgKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:bamboo_trapdoor", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmJhbWJvb190cmFwZG9vcgQJAG5hbWVfaGFzaJrEOpsTwtKCAwoAbmV0d29ya19pZLvbPz8KBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:iron_trapdoor", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0Omlyb25fdHJhcGRvb3IECQBuYW1lX2hhc2gwA+IumsEiGQMKAG5ldHdvcmtfaWTvSVl/CgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAEPAHVwc2lkZV9kb3duX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:crimson_trapdoor", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmNyaW1zb25fdHJhcGRvb3IECQBuYW1lX2hhc2jHXufTnwUkYgMKAG5ldHdvcmtfaWQLjMYVCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAEPAHVwc2lkZV9kb3duX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:warped_trapdoor", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OndhcnBlZF90cmFwZG9vcgQJAG5hbWVfaGFzaA20wG/+vkd6AwoAbmV0d29ya19pZHKR/hYKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:iron_bars", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0Omlyb25fYmFycwQJAG5hbWVfaGFzaPuefWSNAe56AwoAbmV0d29ya19pZN2LB5IKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:glass", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OmdsYXNzBAkAbmFtZV9oYXNowGJByfWff6gDCgBuZXR3b3JrX2lk0hdLNwoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:white_stained_glass", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OndoaXRlX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2iHubqoMbu9fAMKAG5ldHdvcmtfaWRndBrUCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:light_gray_stained_glass", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaKKa+LrRsHQhAwoAbmV0d29ya19pZEv2giYKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:gray_stained_glass", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmdyYXlfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaIETy7Y/HZREAwoAbmV0d29ya19pZDomVrUKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:black_stained_glass", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OmJsYWNrX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2iV6BCwpfDMmwMKAG5ldHdvcmtfaWSV7doJCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:brown_stained_glass", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OmJyb3duX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2igsEiq5np8JgMKAG5ldHdvcmtfaWRMzE/lCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:red_stained_glass", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnJlZF9zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNoCa2J12/lQoIDCgBuZXR3b3JrX2lk283lWAoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:orange_stained_glass", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0Om9yYW5nZV9zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNozgjAuvzhxGsDCgBuZXR3b3JrX2lkW5CkhQoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:yellow_stained_glass", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OnllbGxvd19zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNo7EbHMd5WVugDCgBuZXR3b3JrX2lkkdDyXQoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:lime_stained_glass", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmxpbWVfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaBtZA1nZtwcFAwoAbmV0d29ya19pZDxX85UKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:green_stained_glass", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OmdyZWVuX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2h91ptDgbehWwMKAG5ldHdvcmtfaWTlDhnECgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:cyan_stained_glass", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmN5YW5fc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaBkIYQ8nQLqbAwoAbmV0d29ya19pZOL1lHsKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:light_blue_stained_glass", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaLt05n1G0fiSAwoAbmV0d29ya19pZNbwulIKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:blue_stained_glass", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmJsdWVfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaPhLocSfzduRAwoAbmV0d29ya19pZENsjFwKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:purple_stained_glass", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OnB1cnBsZV9zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNoJk0DhRO0szUDCgBuZXR3b3JrX2lkD98ZxgoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:magenta_stained_glass", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0Om1hZ2VudGFfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaFEDeFiJj3zSAwoAbmV0d29ya19pZG+iFRoKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:pink_stained_glass", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OnBpbmtfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaDijTX87ywxhAwoAbmV0d29ya19pZKdEricKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:tinted_glass", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnRpbnRlZF9nbGFzcwQJAG5hbWVfaGFzaAFZWSamk6KdAwoAbmV0d29ya19pZGSvWX8KBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:glass_pane", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmdsYXNzX3BhbmUECQBuYW1lX2hhc2gRSBHwNMQ4gQMKAG5ldHdvcmtfaWRGwixuCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:white_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OndoaXRlX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaHgxQmgJVtRrAwoAbmV0d29ya19pZBEr/DYKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:light_gray_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZScAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNon0aQw9lNkSEDCgBuZXR3b3JrX2lk9dp5VgoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:gray_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OmdyYXlfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNors74IIw+2MMDCgBuZXR3b3JrX2lkmrGO5woGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:black_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OmJsYWNrX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaOK/5ZRRd+M1AwoAbmV0d29ya19pZDv++oQKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:brown_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OmJyb3duX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaLHeGJyRFTIWAwoAbmV0d29ya19pZMz9L0wKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:red_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OnJlZF9zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2gGr4x6JheAywMKAG5ldHdvcmtfaWQBjCTmCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:orange_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSMAbWluZWNyYWZ0Om9yYW5nZV9zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2hbHxPD2gEbEAMKAG5ldHdvcmtfaWSt/7a5CgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:yellow_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSMAbWluZWNyYWZ0OnllbGxvd19zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2g9tl4aOCyZBwMKAG5ldHdvcmtfaWTXRAS7CgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:lime_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OmxpbWVfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNo3CtUyLwoGegDCgBuZXR3b3JrX2lkYJDnggoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:green_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OmdyZWVuX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaJo6YP7IMy9SAwoAbmV0d29ya19pZHOnixoKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:cyan_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OmN5YW5fc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNoti97c6QrbLQDCgBuZXR3b3JrX2lkUqFUeQoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:light_blue_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZScAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNovDg/gQle104DCgBuZXR3b3JrX2lkFuy4MQoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:blue_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OmJsdWVfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNoGc57tiexbQMDCgBuZXR3b3JrX2lk1eBLUAoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:purple_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSMAbWluZWNyYWZ0OnB1cnBsZV9zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2hDJHYdd0FdfQMKAG5ldHdvcmtfaWSNsdK5CgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:magenta_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSQAbWluZWNyYWZ0Om1hZ2VudGFfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNo3pcOw5bs5XoDCgBuZXR3b3JrX2lkVbOR7AoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:pink_stained_glass_pane", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OnBpbmtfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNoWRhSACMWgswDCgBuZXR3b3JrX2lkIR92xwoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:ladder", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OmxhZGRlcgQJAG5hbWVfaGFzaKBhqheJVOz+AwoAbmV0d29ya19pZCgvzlsKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:scaffolding", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OnNjYWZmb2xkaW5nBAkAbmFtZV9oYXNoYrkevrqcljwDCgBuZXR3b3JrX2lkD13mlAoGAHN0YXRlcwMJAHN0YWJpbGl0eQAAAAABDwBzdGFiaWxpdHlfY2hlY2sAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWTkNl0JCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQwAc21vb3RoX3N0b25lAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:stone_block_slab4", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkQJoxlgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNAUAc3RvbmUAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWRHh04KCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQsAY29iYmxlc3RvbmUAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkVRZB+woGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhEAbW9zc3lfY29iYmxlc3RvbmUAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:wooden_slab", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Ondvb2Rlbl9zbGFiBAkAbmFtZV9oYXNoBVBkRBCCh4MDCgBuZXR3b3JrX2lkBaobgAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20ICQB3b29kX3R5cGUDAG9hawADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:wooden_slab", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Ondvb2Rlbl9zbGFiBAkAbmFtZV9oYXNoBVBkRBCCh4MDCgBuZXR3b3JrX2lkhz9TeQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20ICQB3b29kX3R5cGUGAHNwcnVjZQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:wooden_slab", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Ondvb2Rlbl9zbGFiBAkAbmFtZV9oYXNoBVBkRBCCh4MDCgBuZXR3b3JrX2lk3HkwowoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20ICQB3b29kX3R5cGUFAGJpcmNoAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:wooden_slab", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Ondvb2Rlbl9zbGFiBAkAbmFtZV9oYXNoBVBkRBCCh4MDCgBuZXR3b3JrX2lkDIBqVQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20ICQB3b29kX3R5cGUGAGp1bmdsZQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:wooden_slab", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Ondvb2Rlbl9zbGFiBAkAbmFtZV9oYXNoBVBkRBCCh4MDCgBuZXR3b3JrX2lkL5hFYAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20ICQB3b29kX3R5cGUGAGFjYWNpYQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:wooden_slab", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Ondvb2Rlbl9zbGFiBAkAbmFtZV9oYXNoBVBkRBCCh4MDCgBuZXR3b3JrX2lkKRUHSQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20ICQB3b29kX3R5cGUIAGRhcmtfb2FrAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:mangrove_slab", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0Om1hbmdyb3ZlX3NsYWIECQBuYW1lX2hhc2jYCcmhJPeNMwMKAG5ldHdvcmtfaWQx6U1yCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:cherry_slab", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmNoZXJyeV9zbGFiBAkAbmFtZV9oYXNoTt0MmVn/mqoDCgBuZXR3b3JrX2lk2VVsZQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:bamboo_slab", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmJhbWJvb19zbGFiBAkAbmFtZV9oYXNoo1xuFqINeLYDCgBuZXR3b3JrX2lkVC+0twoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:bamboo_mosaic_slab", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmJhbWJvb19tb3NhaWNfc2xhYgQJAG5hbWVfaGFzaNbVRBZ/ChI3AwoAbmV0d29ya19pZOLZHFMKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWQSiInOCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQsAc3RvbmVfYnJpY2sAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:stone_block_slab4", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkoF89tgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNBEAbW9zc3lfc3RvbmVfYnJpY2sAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWSkoAE4CgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQkAc2FuZHN0b25lAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:stone_block_slab4", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkWfF7pgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNA0AY3V0X3NhbmRzdG9uZQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkbKRChAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAc21vb3RoX3NhbmRzdG9uZQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkBlrvqAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMg0AcmVkX3NhbmRzdG9uZQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:stone_block_slab4", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkRWFXuwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNBEAY3V0X3JlZF9zYW5kc3RvbmUAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkom8neQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxQAc21vb3RoX3JlZF9zYW5kc3RvbmUAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkd1ZaWgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMwcAZ3Jhbml0ZQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkISH4iwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxAAcG9saXNoZWRfZ3Jhbml0ZQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkqxEDMwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMwcAZGlvcml0ZQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkSYs86QoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxAAcG9saXNoZWRfZGlvcml0ZQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkq6BU6goGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMwgAYW5kZXNpdGUAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkTSXY8AoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxEAcG9saXNoZWRfYW5kZXNpdGUAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWQiYHKTCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQUAYnJpY2sAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWTk/0LfCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQwAbmV0aGVyX2JyaWNrAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lk/hXQ7AoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAcmVkX25ldGhlcl9icmljawADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkYJNxrwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMw8AZW5kX3N0b25lX2JyaWNrAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWRlj0/sCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQYAcXVhcnR6AAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:stone_block_slab4", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkMae+2goGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNA0Ac21vb3RoX3F1YXJ0egADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lk+kMHGAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMgYAcHVycHVyAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkKOSOMAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAcHJpc21hcmluZV9yb3VnaAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lk8igLCQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMg8AcHJpc21hcmluZV9kYXJrAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkSFbyEwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAcHJpc21hcmluZV9icmljawADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:crimson_slab", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmNyaW1zb25fc2xhYgQJAG5hbWVfaGFzaKZ+EfP0ZYOZAwoAbmV0d29ya19pZAxRUWAKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:warped_slab", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OndhcnBlZF9zbGFiBAkAbmFtZV9oYXNo/AT0e/Z9W7UDCgBuZXR3b3JrX2lk1yq11AoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:blackstone_slab", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmJsYWNrc3RvbmVfc2xhYgQJAG5hbWVfaGFzaF/DD4ZUlNgtAwoAbmV0d29ya19pZGy1DjwKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:polished_blackstone_slab", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfc2xhYgQJAG5hbWVfaGFzaDYnuUs86EWfAwoAbmV0d29ya19pZJj2bXIKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:polished_blackstone_brick_slab", - "block_state_b64": "CgAACAQAbmFtZSgAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tfc2xhYgQJAG5hbWVfaGFzaKySLqvHc4xXAwoAbmV0d29ya19pZOyWX94KBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:cut_copper_slab", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmN1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaDsNpb2qs4iBAwoAbmV0d29ya19pZOTm2nsKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:exposed_cut_copper_slab", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OmV4cG9zZWRfY3V0X2NvcHBlcl9zbGFiBAkAbmFtZV9oYXNoahQ5OwIQb7kDCgBuZXR3b3JrX2lkrUlZLwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:weathered_cut_copper_slab", - "block_state_b64": "CgAACAQAbmFtZSMAbWluZWNyYWZ0OndlYXRoZXJlZF9jdXRfY29wcGVyX3NsYWIECQBuYW1lX2hhc2hBIuGIOVVXogMKAG5ldHdvcmtfaWQgnaDiCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:oxidized_cut_copper_slab", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0Om94aWRpemVkX2N1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaOptj9ycfpaDAwoAbmV0d29ya19pZMzFSRgKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:waxed_cut_copper_slab", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OndheGVkX2N1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaAlx6DZOCTHzAwoAbmV0d29ya19pZFRBvDAKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:waxed_exposed_cut_copper_slab", - "block_state_b64": "CgAACAQAbmFtZScAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY3V0X2NvcHBlcl9zbGFiBAkAbmFtZV9oYXNo3KqS5OnhtRIDCgBuZXR3b3JrX2lkHTGcTgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:waxed_weathered_cut_copper_slab", - "block_state_b64": "CgAACAQAbmFtZSkAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jdXRfY29wcGVyX3NsYWIECQBuYW1lX2hhc2gzZ1oX0HCFtwMKAG5ldHdvcmtfaWSgJR+XCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:waxed_oxidized_cut_copper_slab", - "block_state_b64": "CgAACAQAbmFtZSgAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2N1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaMjjTnLu1KcqAwoAbmV0d29ya19pZIxsnFYKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:cobbled_deepslate_slab", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlX3NsYWIECQBuYW1lX2hhc2gwJIVWK1TM2QMKAG5ldHdvcmtfaWTYAoX5CgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:polished_deepslate_slab", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZV9zbGFiBAkAbmFtZV9oYXNoC/Adiz8k6RYDCgBuZXR3b3JrX2lkuFYMAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:deepslate_tile_slab", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlX3NsYWIECQBuYW1lX2hhc2hPydV6emzIXAMKAG5ldHdvcmtfaWQwlbFCCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:deepslate_brick_slab", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja19zbGFiBAkAbmFtZV9oYXNoSv62V7iw10UDCgBuZXR3b3JrX2lkWMoragoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:mud_brick_slab", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0Om11ZF9icmlja19zbGFiBAkAbmFtZV9oYXNoq/tGBQWkv08DCgBuZXR3b3JrX2lkl4nnMwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:brick_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmJyaWNrX2Jsb2NrBAkAbmFtZV9oYXNo5Qc2E005S3oDCgBuZXR3b3JrX2lkqeGWRgoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:chiseled_nether_bricks", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmNoaXNlbGVkX25ldGhlcl9icmlja3MECQBuYW1lX2hhc2g31SBPTcUK1QMKAG5ldHdvcmtfaWS8TJ+TCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:cracked_nether_bricks", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OmNyYWNrZWRfbmV0aGVyX2JyaWNrcwQJAG5hbWVfaGFzaAdC6eKzXT5tAwoAbmV0d29ya19pZIUSejwKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:quartz_bricks", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnF1YXJ0el9icmlja3MECQBuYW1lX2hhc2jSZO590dd8sAMKAG5ldHdvcmtfaWSc5xCLCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:stonebrick", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWQ5kni1CgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQcAZGVmYXVsdAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:stonebrick", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWTDw813CgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQUAbW9zc3kAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:stonebrick", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWSTvQGECgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQcAY3JhY2tlZAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:stonebrick", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWQIM0OwCgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQgAY2hpc2VsZWQAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:end_bricks", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmVuZF9icmlja3MECQBuYW1lX2hhc2hIUFfxNLZaFgMKAG5ldHdvcmtfaWQ/vDihCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:prismarine", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnByaXNtYXJpbmUECQBuYW1lX2hhc2jcnQCHi9CspQMKAG5ldHdvcmtfaWSH021WCgYAc3RhdGVzCBUAcHJpc21hcmluZV9ibG9ja190eXBlBgBicmlja3MAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:polished_blackstone_bricks", - "block_state_b64": "CgAACAQAbmFtZSQAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tzBAkAbmFtZV9oYXNoIHgsgIdzKXcDCgBuZXR3b3JrX2lkUw9b3woGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:cracked_polished_blackstone_bricks", - "block_state_b64": "CgAACAQAbmFtZSwAbWluZWNyYWZ0OmNyYWNrZWRfcG9saXNoZWRfYmxhY2tzdG9uZV9icmlja3MECQBuYW1lX2hhc2jQIO1GQDk80AMKAG5ldHdvcmtfaWQ3UlRYCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:gilded_blackstone", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmdpbGRlZF9ibGFja3N0b25lBAkAbmFtZV9oYXNoNoWt1ocG0HEDCgBuZXR3b3JrX2lktL8gUwoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:chiseled_polished_blackstone", - "block_state_b64": "CgAACAQAbmFtZSYAbWluZWNyYWZ0OmNoaXNlbGVkX3BvbGlzaGVkX2JsYWNrc3RvbmUECQBuYW1lX2hhc2gzFa+kEjCJgAMKAG5ldHdvcmtfaWR2NJX2CgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:deepslate_tiles", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlcwQJAG5hbWVfaGFzaGcLLx3NXAFvAwoAbmV0d29ya19pZI/G/xYKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:cracked_deepslate_tiles", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OmNyYWNrZWRfZGVlcHNsYXRlX3RpbGVzBAkAbmFtZV9oYXNo9zWgkFuMM1QDCgBuZXR3b3JrX2lkGwY6OgoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:deepslate_bricks", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja3MECQBuYW1lX2hhc2gucvFmPdZxigMKAG5ldHdvcmtfaWSH4HDPCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:cracked_deepslate_bricks", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OmNyYWNrZWRfZGVlcHNsYXRlX2JyaWNrcwQJAG5hbWVfaGFzaN40aqhh9WqHAwoAbmV0d29ya19pZO9GPBQKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:chiseled_deepslate", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmNoaXNlbGVkX2RlZXBzbGF0ZQQJAG5hbWVfaGFzaEU7/uRG8HSBAwoAbmV0d29ya19pZEqmI0EKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:cobblestone", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmNvYmJsZXN0b25lBAkAbmFtZV9oYXNoPoK7mGlSUz4DCgBuZXR3b3JrX2lkLm7RZwoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:mossy_cobblestone", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0Om1vc3N5X2NvYmJsZXN0b25lBAkAbmFtZV9oYXNoGJ67FCbkChMDCgBuZXR3b3JrX2lk/pYs1AoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:cobbled_deepslate", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlBAkAbmFtZV9oYXNoLUz9Y/ywmLwDCgBuZXR3b3JrX2lkNwzZ+AoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:smooth_stone", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnNtb290aF9zdG9uZQQJAG5hbWVfaGFzaMwf87/JaTNvAwoAbmV0d29ya19pZLkZICEKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:sandstone", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZB2wApMKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGUHAGRlZmF1bHQAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:sandstone", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZB7E+eQKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGULAGhlaXJvZ2x5cGhzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:sandstone", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZFQnDaEKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGUDAGN1dAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:sandstone", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZPO4A3IKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGUGAHNtb290aAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:red_sandstone", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWRhNYiFCgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlBwBkZWZhdWx0AAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:red_sandstone", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWTqXJr1CgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlCwBoZWlyb2dseXBocwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:red_sandstone", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWTQRGkFCgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlAwBjdXQAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:red_sandstone", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWTvAHWDCgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlBgBzbW9vdGgAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:coal_block", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmNvYWxfYmxvY2sECQBuYW1lX2hhc2jH8QQP3t5PiAMKAG5ldHdvcmtfaWRo+sR+CgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:dried_kelp_block", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmRyaWVkX2tlbHBfYmxvY2sECQBuYW1lX2hhc2iRoucexkrl8wMKAG5ldHdvcmtfaWQQCCrvCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:gold_block", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmdvbGRfYmxvY2sECQBuYW1lX2hhc2iYLshvjtXzFwMKAG5ldHdvcmtfaWTDJGBcCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:iron_block", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0Omlyb25fYmxvY2sECQBuYW1lX2hhc2jYINmJQbvV/gMKAG5ldHdvcmtfaWRf7AbICgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:copper_block", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmNvcHBlcl9ibG9jawQJAG5hbWVfaGFzaDVxnehsGaZ1AwoAbmV0d29ya19pZIiUodwKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:copper_door" - }, - { - "id": "minecraft:copper_trapdoor", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmNvcHBlcl90cmFwZG9vcgQJAG5hbWVfaGFzaO9fXio+svKVAwoAbmV0d29ya19pZMCoRjEKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:copper_grate", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmNvcHBlcl9ncmF0ZQQJAG5hbWVfaGFzaC/JEFOWnmEcAwoAbmV0d29ya19pZC6YiiMKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:exposed_copper", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmV4cG9zZWRfY29wcGVyBAkAbmFtZV9oYXNoQH3Fukmu3CEDCgBuZXR3b3JrX2lk72jFIwoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:exposed_copper_door" - }, - { - "id": "minecraft:exposed_copper_trapdoor", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OmV4cG9zZWRfY29wcGVyX3RyYXBkb29yBAkAbmFtZV9oYXNoYhDFUysN7qUDCgBuZXR3b3JrX2lkMzwGJgoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:exposed_copper_grate", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OmV4cG9zZWRfY29wcGVyX2dyYXRlBAkAbmFtZV9oYXNolFIBYLYU0IcDCgBuZXR3b3JrX2lk4UqptAoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:weathered_copper", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OndlYXRoZXJlZF9jb3BwZXIECQBuYW1lX2hhc2hJCQXbvobv+gMKAG5ldHdvcmtfaWQwM0lJCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:weathered_copper_door" - }, - { - "id": "minecraft:weathered_copper_trapdoor", - "block_state_b64": "CgAACAQAbmFtZSMAbWluZWNyYWZ0OndlYXRoZXJlZF9jb3BwZXJfdHJhcGRvb3IECQBuYW1lX2hhc2hFnEC282a1tgMKAG5ldHdvcmtfaWTk70oiCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAEPAHVwc2lkZV9kb3duX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:weathered_copper_grate", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OndlYXRoZXJlZF9jb3BwZXJfZ3JhdGUECQBuYW1lX2hhc2jB3o8enlv1RgMKAG5ldHdvcmtfaWRih2pOCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:oxidized_copper", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0Om94aWRpemVkX2NvcHBlcgQJAG5hbWVfaGFzaMDtJqR0G5Y7AwoAbmV0d29ya19pZGjN8bUKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:oxidized_copper_door" - }, - { - "id": "minecraft:oxidized_copper_trapdoor", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0Om94aWRpemVkX2NvcHBlcl90cmFwZG9vcgQJAG5hbWVfaGFzaOJpG/XFexVwAwoAbmV0d29ya19pZPhi0J4KBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:oxidized_copper_grate", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0Om94aWRpemVkX2NvcHBlcl9ncmF0ZQQJAG5hbWVfaGFzaBRfNhyndve7AwoAbmV0d29ya19pZKY2cnEKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:waxed_copper", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OndheGVkX2NvcHBlcgQJAG5hbWVfaGFzaPF+FG6Eh5fsAwoAbmV0d29ya19pZIjtz/0KBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:waxed_copper_door" - }, - { - "id": "minecraft:waxed_copper_trapdoor", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OndheGVkX2NvcHBlcl90cmFwZG9vcgQJAG5hbWVfaGFzaO0JUKUHqNU6AwoAbmV0d29ya19pZJC3ZuMKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:waxed_copper_grate", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OndheGVkX2NvcHBlcl9ncmF0ZQQJAG5hbWVfaGFzaDmC92M2RO+HAwoAbmV0d29ya19pZH4og2AKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:waxed_exposed_copper", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY29wcGVyBAkAbmFtZV9oYXNoig8IOc+SCikDCgBuZXR3b3JrX2lklz8yWQoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:waxed_exposed_copper_door" - }, - { - "id": "minecraft:waxed_exposed_copper_trapdoor", - "block_state_b64": "CgAACAQAbmFtZScAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY29wcGVyX3RyYXBkb29yBAkAbmFtZV9oYXNoBHHxCpkUzpgDCgBuZXR3b3JrX2lkw2XBGQoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:waxed_exposed_copper_grate", - "block_state_b64": "CgAACAQAbmFtZSQAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY29wcGVyX2dyYXRlBAkAbmFtZV9oYXNoWmd6B+hWwiEDCgBuZXR3b3JrX2lk8d4ZQwoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:waxed_weathered_copper", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jb3BwZXIECQBuYW1lX2hhc2gjtPq8MOdvKgMKAG5ldHdvcmtfaWSQ9Ln9CgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:waxed_weathered_copper_door" - }, - { - "id": "minecraft:waxed_weathered_copper_trapdoor", - "block_state_b64": "CgAACAQAbmFtZSkAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jb3BwZXJfdHJhcGRvb3IECQBuYW1lX2hhc2gH9Fi3JCF4egMKAG5ldHdvcmtfaWRkGU6TCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAEPAHVwc2lkZV9kb3duX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:waxed_weathered_copper_grate", - "block_state_b64": "CgAACAQAbmFtZSYAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jb3BwZXJfZ3JhdGUECQBuYW1lX2hhc2hXfilVFDAiYQMKAG5ldHdvcmtfaWQqTGC1CgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:waxed_oxidized_copper", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OndheGVkX294aWRpemVkX2NvcHBlcgQJAG5hbWVfaGFzaMaORhsO+LzjAwoAbmV0d29ya19pZJhGfLEKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:waxed_oxidized_copper_door" - }, - { - "id": "minecraft:waxed_oxidized_copper_trapdoor", - "block_state_b64": "CgAACAQAbmFtZSgAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2NvcHBlcl90cmFwZG9vcgQJAG5hbWVfaGFzaNA/q9qAy6Z9AwoAbmV0d29ya19pZDgExS8KBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:waxed_oxidized_copper_grate", - "block_state_b64": "CgAACAQAbmFtZSUAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2NvcHBlcl9ncmF0ZQQJAG5hbWVfaGFzaEbeMT605GP4AwoAbmV0d29ya19pZOZjpkkKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:cut_copper", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmN1dF9jb3BwZXIECQBuYW1lX2hhc2hAfN3NGax3eAMKAG5ldHdvcmtfaWTnFBtYCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:exposed_cut_copper", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmV4cG9zZWRfY3V0X2NvcHBlcgQJAG5hbWVfaGFzaA85G3yv/w6pAwoAbmV0d29ya19pZMQhr0QKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:weathered_cut_copper", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OndlYXRoZXJlZF9jdXRfY29wcGVyBAkAbmFtZV9oYXNoVgRV0fBaz88DCgBuZXR3b3JrX2lk/0cYugoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:oxidized_cut_copper", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0Om94aWRpemVkX2N1dF9jb3BwZXIECQBuYW1lX2hhc2iP8WmFWOkriwMKAG5ldHdvcmtfaWQPdce7CgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:waxed_cut_copper", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OndheGVkX2N1dF9jb3BwZXIECQBuYW1lX2hhc2jumiwOZIqv2AMKAG5ldHdvcmtfaWQvuxx9CgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:waxed_exposed_cut_copper", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY3V0X2NvcHBlcgQJAG5hbWVfaGFzaPE/OfK6IoVMAwoAbmV0d29ya19pZHy5HkcKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:waxed_weathered_cut_copper", - "block_state_b64": "CgAACAQAbmFtZSQAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jdXRfY29wcGVyBAkAbmFtZV9oYXNoCA1xDp11bnwDCgBuZXR3b3JrX2lkDyEDVQoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:waxed_oxidized_cut_copper", - "block_state_b64": "CgAACAQAbmFtZSMAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2N1dF9jb3BwZXIECQBuYW1lX2hhc2i1pZAsZYHLDAMKAG5ldHdvcmtfaWQ/wSkCCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:chiseled_copper", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmNoaXNlbGVkX2NvcHBlcgQJAG5hbWVfaGFzaIsW5pmpJEuQAwoAbmV0d29ya19pZHetwrkKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:exposed_chiseled_copper", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OmV4cG9zZWRfY2hpc2VsZWRfY29wcGVyBAkAbmFtZV9oYXNoOvrLJ0UowbgDCgBuZXR3b3JrX2lkZj7cPwoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:weathered_chiseled_copper", - "block_state_b64": "CgAACAQAbmFtZSMAbWluZWNyYWZ0OndlYXRoZXJlZF9jaGlzZWxlZF9jb3BwZXIECQBuYW1lX2hhc2hh+42XlsWvGAMKAG5ldHdvcmtfaWS7Cy59CgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:oxidized_chiseled_copper", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0Om94aWRpemVkX2NoaXNlbGVkX2NvcHBlcgQJAG5hbWVfaGFzaLpTIsnfluiCAwoAbmV0d29ya19pZB9/jS8KBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:waxed_chiseled_copper", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OndheGVkX2NoaXNlbGVkX2NvcHBlcgQJAG5hbWVfaGFzaFnXvXY5OinzAwoAbmV0d29ya19pZAcKtHsKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:waxed_exposed_chiseled_copper", - "block_state_b64": "CgAACAQAbmFtZScAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY2hpc2VsZWRfY29wcGVyBAkAbmFtZV9oYXNoHJdq+Pph6hMDCgBuZXR3b3JrX2lkdge7IAoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:waxed_oxidized_chiseled_copper", - "block_state_b64": "CgAACAQAbmFtZSgAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2NoaXNlbGVkX2NvcHBlcgQJAG5hbWVfaGFzaMj49OvlTpgCAwoAbmV0d29ya19pZN/r+roKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:waxed_weathered_chiseled_copper", - "block_state_b64": "CgAACAQAbmFtZSkAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jaGlzZWxlZF9jb3BwZXIECQBuYW1lX2hhc2hzuO+Sg9LYQwMKAG5ldHdvcmtfaWQ7AN7iCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:copper_bulb", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcHBlcl9idWxiBAkAbmFtZV9oYXNo41TimHOsMWcDCgBuZXR3b3JrX2lkJnZvAgoGAHN0YXRlcwEDAGxpdAABCwBwb3dlcmVkX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:exposed_copper_bulb", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OmV4cG9zZWRfY29wcGVyX2J1bGIECQBuYW1lX2hhc2g++f1wYLLCrAMKAG5ldHdvcmtfaWRLdMmGCgYAc3RhdGVzAQMAbGl0AAELAHBvd2VyZWRfYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:weathered_copper_bulb", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OndlYXRoZXJlZF9jb3BwZXJfYnVsYgQJAG5hbWVfaGFzaMEtsYfwRTXlAwoAbmV0d29ya19pZAp51LQKBgBzdGF0ZXMBAwBsaXQAAQsAcG93ZXJlZF9iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:oxidized_copper_bulb", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0Om94aWRpemVkX2NvcHBlcl9idWxiBAkAbmFtZV9oYXNovnrBQZs8nDIDCgBuZXR3b3JrX2lkPsj0AAoGAHN0YXRlcwEDAGxpdAABCwBwb3dlcmVkX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:waxed_copper_bulb", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OndheGVkX2NvcHBlcl9idWxiBAkAbmFtZV9oYXNoGTg6TYllMiIDCgBuZXR3b3JrX2lk9m0WhgoGAHN0YXRlcwEDAGxpdAABCwBwb3dlcmVkX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:waxed_exposed_copper_bulb", - "block_state_b64": "CgAACAQAbmFtZSMAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY29wcGVyX2J1bGIECQBuYW1lX2hhc2gI6xkPcvBDVwMKAG5ldHdvcmtfaWR7BRcACgYAc3RhdGVzAQMAbGl0AAELAHBvd2VyZWRfYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:waxed_weathered_copper_bulb", - "block_state_b64": "CgAACAQAbmFtZSUAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jb3BwZXJfYnVsYgQJAG5hbWVfaGFzaMsUnmp3/VqVAwoAbmV0d29ya19pZEoworoKBgBzdGF0ZXMBAwBsaXQAAQsAcG93ZXJlZF9iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:waxed_oxidized_copper_bulb", - "block_state_b64": "CgAACAQAbmFtZSQAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2NvcHBlcl9idWxiBAkAbmFtZV9oYXNoBFKxY3fjVq4DCgBuZXR3b3JrX2lkzrJ6aAoGAHN0YXRlcwEDAGxpdAABCwBwb3dlcmVkX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:emerald_block", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmVtZXJhbGRfYmxvY2sECQBuYW1lX2hhc2hK6QunqJznNAMKAG5ldHdvcmtfaWRk5+otCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:diamond_block", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmRpYW1vbmRfYmxvY2sECQBuYW1lX2hhc2iGKrxuvkytFQMKAG5ldHdvcmtfaWQQeQZXCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:lapis_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmxhcGlzX2Jsb2NrBAkAbmFtZV9oYXNoDZ44xdb2zVoDCgBuZXR3b3JrX2lktVy0BAoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:raw_iron_block", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OnJhd19pcm9uX2Jsb2NrBAkAbmFtZV9oYXNo9XyzNIQXxvwDCgBuZXR3b3JrX2lknms1QAoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:raw_copper_block", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OnJhd19jb3BwZXJfYmxvY2sECQBuYW1lX2hhc2hw1KG0TNUGgwMKAG5ldHdvcmtfaWS1vGo/CgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:raw_gold_block", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OnJhd19nb2xkX2Jsb2NrBAkAbmFtZV9oYXNo6YuwuLwfOBwDCgBuZXR3b3JrX2lkLiQ5gQoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:quartz_block", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZEupC1AKBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQcAZGVmYXVsdAgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:quartz_block", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZM97+l0KBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQUAbGluZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:quartz_block", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZCbTfssKBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQgAY2hpc2VsZWQICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:quartz_block", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZJss8V0KBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQYAc21vb3RoCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:prismarine", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnByaXNtYXJpbmUECQBuYW1lX2hhc2jcnQCHi9CspQMKAG5ldHdvcmtfaWRFIsoGCgYAc3RhdGVzCBUAcHJpc21hcmluZV9ibG9ja190eXBlBwBkZWZhdWx0AAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:prismarine", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnByaXNtYXJpbmUECQBuYW1lX2hhc2jcnQCHi9CspQMKAG5ldHdvcmtfaWTDNWOvCgYAc3RhdGVzCBUAcHJpc21hcmluZV9ibG9ja190eXBlBABkYXJrAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:slime", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OnNsaW1lBAkAbmFtZV9oYXNoHJiEEJx+JlkDCgBuZXR3b3JrX2lkfgfVzAoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:honey_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmhvbmV5X2Jsb2NrBAkAbmFtZV9oYXNo9zLYSUlelywDCgBuZXR3b3JrX2lko+dyWgoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:honeycomb_block", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmhvbmV5Y29tYl9ibG9jawQJAG5hbWVfaGFzaASIPuOCYd1oAwoAbmV0d29ya19pZKys4n4KBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:hay_block", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmhheV9ibG9jawQJAG5hbWVfaGFzaIB2VxKxX8EpAwoAbmV0d29ya19pZKuQSloKBgBzdGF0ZXMDCgBkZXByZWNhdGVkAAAAAAgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:bone_block", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmJvbmVfYmxvY2sECQBuYW1lX2hhc2i4ZX576W9AWgMKAG5ldHdvcmtfaWTWGacQCgYAc3RhdGVzAwoAZGVwcmVjYXRlZAAAAAAICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:nether_brick", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0Om5ldGhlcl9icmljawQJAG5hbWVfaGFzaMxcRiheU+nXAwoAbmV0d29ya19pZMkmzloKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:red_nether_brick", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OnJlZF9uZXRoZXJfYnJpY2sECQBuYW1lX2hhc2j8pRO4LfoECAMKAG5ldHdvcmtfaWRpdF0YCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:netherite_block", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0Om5ldGhlcml0ZV9ibG9jawQJAG5hbWVfaGFzaMghh6Zib/ZKAwoAbmV0d29ya19pZIz0mq0KBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:lodestone", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmxvZGVzdG9uZQQJAG5hbWVfaGFzaJ2gmHOTlXv8AwoAbmV0d29ya19pZEfgB4wKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:white_wool", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OndoaXRlX3dvb2wECQBuYW1lX2hhc2jRWB7vaIEDiQMKAG5ldHdvcmtfaWSO8paQCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:light_gray_wool", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfd29vbAQJAG5hbWVfaGFzaOpdQ1a2v4b3AwoAbmV0d29ya19pZIqZCYEKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:gray_wool", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmdyYXlfd29vbAQJAG5hbWVfaGFzaLsc1Lp1xdIOAwoAbmV0d29ya19pZFUs+HgKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:black_wool", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmJsYWNrX3dvb2wECQBuYW1lX2hhc2hP2HC6o0X4HAMKAG5ldHdvcmtfaWRUbORcCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:brown_wool", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmJyb3duX3dvb2wECQBuYW1lX2hhc2ig5IW89PrREwMKAG5ldHdvcmtfaWRjT9j8CgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:red_wool", - "block_state_b64": "CgAACAQAbmFtZRIAbWluZWNyYWZ0OnJlZF93b29sBAkAbmFtZV9oYXNoY4TBDq+mFgUDCgBuZXR3b3JrX2lktn9lcAoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:orange_wool", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Om9yYW5nZV93b29sBAkAbmFtZV9oYXNoFstfrTZfSCgDCgBuZXR3b3JrX2lk+rqywwoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:yellow_wool", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OnllbGxvd193b29sBAkAbmFtZV9oYXNoTFyus2RHegcDCgBuZXR3b3JrX2lkkKBhXAoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:lime_wool", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmxpbWVfd29vbAQJAG5hbWVfaGFzaNVnnzKiMxmeAwoAbmV0d29ya19pZG9b32kKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:green_wool", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmdyZWVuX3dvb2wECQBuYW1lX2hhc2i3mElRYHIcSQMKAG5ldHdvcmtfaWSssprwCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:cyan_wool", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmN5YW5fd29vbAQJAG5hbWVfaGFzaBNDfvHn8dqFAwoAbmV0d29ya19pZK0hAbgKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:light_blue_wool", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfd29vbAQJAG5hbWVfaGFzaLWFAUfyxFPNAwoAbmV0d29ya19pZL2oEugKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:blue_wool", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmJsdWVfd29vbAQJAG5hbWVfaGFzaLjHyxxbTWCLAwoAbmV0d29ya19pZPaLdFQKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:purple_wool", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OnB1cnBsZV93b29sBAkAbmFtZV9oYXNojvFtqzjAf/4DCgBuZXR3b3JrX2lklqASNQoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:magenta_wool", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0Om1hZ2VudGFfd29vbAQJAG5hbWVfaGFzaGuOHvf+Pd4yAwoAbmV0d29ya19pZI4UoDQKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:pink_wool", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OnBpbmtfd29vbAQJAG5hbWVfaGFzaPiVA2pFeoFLAwoAbmV0d29ya19pZOZRO6oKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:white_carpet", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OndoaXRlX2NhcnBldAQJAG5hbWVfaGFzaNeMHTI1fWPXAwoAbmV0d29ya19pZEahDFcKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:light_gray_carpet", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY2FycGV0BAkAbmFtZV9oYXNoHPw6ArBAsP0DCgBuZXR3b3JrX2lkQoAeUAoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:gray_carpet", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmdyYXlfY2FycGV0BAkAbmFtZV9oYXNoZVR0OI+1VRADCgBuZXR3b3JrX2lkETF4WwoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:black_carpet", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmJsYWNrX2NhcnBldAQJAG5hbWVfaGFzaOk7LP9NptyhAwoAbmV0d29ya19pZFjmXtIKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:brown_carpet", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmJyb3duX2NhcnBldAQJAG5hbWVfaGFzaNaXFyOsAvIvAwoAbmV0d29ya19pZHPjFuoKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:red_carpet", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9jYXJwZXQECQBuYW1lX2hhc2i9eSKBf6SO3wMKAG5ldHdvcmtfaWQuhI/KCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:orange_carpet", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0Om9yYW5nZV9jYXJwZXQECQBuYW1lX2hhc2hIUkO4HlAdygMKAG5ldHdvcmtfaWSyKV9OCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:yellow_carpet", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnllbGxvd19jYXJwZXQECQBuYW1lX2hhc2hSDKX3scCamwMKAG5ldHdvcmtfaWT8nq+ECgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:lime_carpet", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmxpbWVfY2FycGV0BAkAbmFtZV9oYXNo+6KFOpzsib4DCgBuZXR3b3JrX2lkT+DS4woGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:green_carpet", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmdyZWVuX2NhcnBldAQJAG5hbWVfaGFzaCHPMP9ltqFJAwoAbmV0d29ya19pZBgwAvAKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:cyan_carpet", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmN5YW5fY2FycGV0BAkAbmFtZV9oYXNobXf62dQBJj8DCgBuZXR3b3JrX2lkKVppLgoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:light_blue_carpet", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY2FycGV0BAkAbmFtZV9oYXNo20l4oktdZ3sDCgBuZXR3b3JrX2lkjdeMiwoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:blue_carpet", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmJsdWVfY2FycGV0BAkAbmFtZV9oYXNo3p3lsW0eQwsDCgBuZXR3b3JrX2lkAovdPQoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:purple_carpet", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnB1cnBsZV9jYXJwZXQECQBuYW1lX2hhc2jwIA9pW/qp7QMKAG5ldHdvcmtfaWTqJqhjCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:magenta_carpet", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0Om1hZ2VudGFfY2FycGV0BAkAbmFtZV9oYXNoFXT36YNNZhMDCgBuZXR3b3JrX2lk+tqsGAoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:pink_carpet", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OnBpbmtfY2FycGV0BAkAbmFtZV9oYXNoHll72oqk+OoDCgBuZXR3b3JrX2lkrnBYDwoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:white_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OndoaXRlX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaFUk9iXVjwV8AwoAbmV0d29ya19pZJPZY8AKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:light_gray_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZSQAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNo7EUk30hmUtYDCgBuZXR3b3JrX2lkh8jVIwoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:gray_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OmdyYXlfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoW77af6WihdwDCgBuZXR3b3JrX2lkSsqC1woGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:black_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OmJsYWNrX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaAfWYp0xtgcfAwoAbmV0d29ya19pZMWTC8EKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:brown_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OmJyb3duX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaB74EeiLO46XAwoAbmV0d29ya19pZEDHKqwKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:red_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OnJlZF9jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2gjFut6Z/VH1gMKAG5ldHdvcmtfaWSvcmwYCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:orange_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0Om9yYW5nZV9jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2gADDj2IJiw+gMKAG5ldHdvcmtfaWTHph0FCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:yellow_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OnllbGxvd19jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2iy6qKNn3ob5wMKAG5ldHdvcmtfaWQZAI39CgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:lime_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OmxpbWVfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNo4dYIPslbXPUDCgBuZXR3b3JrX2lk2O8X0AoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:green_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OmdyZWVuX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaM/c9x2aJh3HAwoAbmV0d29ya19pZA0VfBMKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:cyan_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OmN5YW5fY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNok+xKAe7XXjoDCgBuZXR3b3JrX2lkmkn6uwoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:light_blue_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZSQAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNogScpIQceyAEDCgBuZXR3b3JrX2lkOmVSbgoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:blue_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OmJsdWVfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoFp7mmeL86r0DCgBuZXR3b3JrX2lkS3b3RQoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:purple_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OnB1cnBsZV9jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2iYcVU04hoStwMKAG5ldHdvcmtfaWQXimEjCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:magenta_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0Om1hZ2VudGFfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoy/70q6VPsWgDCgBuZXR3b3JrX2lkf9mxQwoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:pink_concrete_powder", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OnBpbmtfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoVikSAf8DwV0DCgBuZXR3b3JrX2lku2MivwoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:white_concrete", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OndoaXRlX2NvbmNyZXRlBAkAbmFtZV9oYXNo6zAp7lsLlvkDCgBuZXR3b3JrX2lk3MAYQAoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:light_gray_concrete", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY29uY3JldGUECQBuYW1lX2hhc2hEtet5wuDIKAMKAG5ldHdvcmtfaWQISs02CgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:gray_concrete", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmdyYXlfY29uY3JldGUECQBuYW1lX2hhc2j92INnb0a83AMKAG5ldHdvcmtfaWQj8RHwCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:black_concrete", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmJsYWNrX2NvbmNyZXRlBAkAbmFtZV9oYXNo2X7NDIQmZ70DCgBuZXR3b3JrX2lk2uiVDQoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:brown_concrete", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmJyb3duX2NvbmNyZXRlBAkAbmFtZV9oYXNoeka02BwXf6oDCgBuZXR3b3JrX2lkYf+xDQoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:red_concrete", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnJlZF9jb25jcmV0ZQQJAG5hbWVfaGFzaPWmNowLGubqAwoAbmV0d29ya19pZKwyx58KBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:orange_concrete", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0Om9yYW5nZV9jb25jcmV0ZQQJAG5hbWVfaGFzaAgE8XmaAi6+AwoAbmV0d29ya19pZMDQNz8KBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:yellow_concrete", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OnllbGxvd19jb25jcmV0ZQQJAG5hbWVfaGFzaE6ONfJPBd0+AwoAbmV0d29ya19pZMarutwKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:lime_concrete", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmxpbWVfY29uY3JldGUECQBuYW1lX2hhc2gnd8JW6wmJcAMKAG5ldHdvcmtfaWTd47aoCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:green_concrete", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmdyZWVuX2NvbmNyZXRlBAkAbmFtZV9oYXNokbFxRKchQZkDCgBuZXR3b3JrX2lkmhZWUgoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:cyan_concrete", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmN5YW5fY29uY3JldGUECQBuYW1lX2hhc2hFRrWJ33qj1wMKAG5ldHdvcmtfaWQbi5b8CgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:light_blue_concrete", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY29uY3JldGUECQBuYW1lX2hhc2gHAe0kl0SE4AMKAG5ldHdvcmtfaWRL/GbSCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:blue_concrete", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmJsdWVfY29uY3JldGUECQBuYW1lX2hhc2hiay301nnj1wMKAG5ldHdvcmtfaWRMvFXNCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:purple_concrete", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OnB1cnBsZV9jb25jcmV0ZQQJAG5hbWVfaGFzaHBHflsPIwdXAwoAbmV0d29ya19pZCyKA5gKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:magenta_concrete", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0Om1hZ2VudGFfY29uY3JldGUECQBuYW1lX2hhc2gN7LuB/OvdZAMKAG5ldHdvcmtfaWTc6ZOdCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:pink_concrete", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnBpbmtfY29uY3JldGUECQBuYW1lX2hhc2ii2G5F0u3SOAMKAG5ldHdvcmtfaWSszGgrCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:clay", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0OmNsYXkECQBuYW1lX2hhc2j/S6sKXRcpzwMKAG5ldHdvcmtfaWRmsb8nCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:hardened_clay", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmhhcmRlbmVkX2NsYXkECQBuYW1lX2hhc2jrnRwCJ0krJAMKAG5ldHdvcmtfaWRBCOrrCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:white_terracotta", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OndoaXRlX3RlcnJhY290dGEECQBuYW1lX2hhc2j3RSdgmnAIewMKAG5ldHdvcmtfaWSimKw+CgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:light_gray_terracotta", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OmxpZ2h0X2dyYXlfdGVycmFjb3R0YQQJAG5hbWVfaGFzaAz1Ri3wIxomAwoAbmV0d29ya19pZH5qgOcKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:gray_terracotta", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmdyYXlfdGVycmFjb3R0YQQJAG5hbWVfaGFzaAXdSLAaNZ9vAwoAbmV0d29ya19pZM1QDV0KBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:black_terracotta", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmJsYWNrX3RlcnJhY290dGEECQBuYW1lX2hhc2jxssdv5vlbpgMKAG5ldHdvcmtfaWRE3Ru/CgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:brown_terracotta", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmJyb3duX3RlcnJhY290dGEECQBuYW1lX2hhc2gG4kPenmOF9gMKAG5ldHdvcmtfaWQ/i0iNCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:red_terracotta", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OnJlZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNo7fX56HXFejEDCgBuZXR3b3JrX2lk8tTF8QoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:orange_terracotta", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0Om9yYW5nZV90ZXJyYWNvdHRhBAkAbmFtZV9oYXNo0Hjmql3sruMDCgBuZXR3b3JrX2lklmqmkAoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:yellow_terracotta", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnllbGxvd190ZXJyYWNvdHRhBAkAbmFtZV9oYXNoqkyKKrmA3VcDCgBuZXR3b3JrX2lkaM/orAoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:lime_terracotta", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmxpbWVfdGVycmFjb3R0YQQJAG5hbWVfaGFzaANjADFOF9v7AwoAbmV0d29ya19pZJt0XsgKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:green_terracotta", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmdyZWVuX3RlcnJhY290dGEECQBuYW1lX2hhc2j5Ybq36yYwRQMKAG5ldHdvcmtfaWQ8kGdHCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:cyan_terracotta", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmN5YW5fdGVycmFjb3R0YQQJAG5hbWVfaGFzaN09COzMuHwAAwoAbmV0d29ya19pZIWPCzoKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:light_blue_terracotta", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OmxpZ2h0X2JsdWVfdGVycmFjb3R0YQQJAG5hbWVfaGFzaOMytez7cOZiAwoAbmV0d29ya19pZFHK1UsKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:blue_terracotta", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmJsdWVfdGVycmFjb3R0YQQJAG5hbWVfaGFzaF6inyTK5RpAAwoAbmV0d29ya19pZF5mVZIKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:purple_terracotta", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnB1cnBsZV90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoKF7YG61yTbEDCgBuZXR3b3JrX2lkhtRDlwoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:magenta_terracotta", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0Om1hZ2VudGFfdGVycmFjb3R0YQQJAG5hbWVfaGFzaLWvtpAVtztyAwoAbmV0d29ya19pZN5SoakKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:pink_terracotta", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OnBpbmtfdGVycmFjb3R0YQQJAG5hbWVfaGFzaJ7mzvyzSQZTAwoAbmV0d29ya19pZDJWe4YKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:white_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OndoaXRlX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoiVzCdoHAJo0DCgBuZXR3b3JrX2lkIlj9AAoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:silver_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OnNpbHZlcl9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaAVsA0CnhzA4AwoAbmV0d29ya19pZPnxtJEKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:gray_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmdyYXlfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2jvLZt9u/lF/AMKAG5ldHdvcmtfaWQVU8eFCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:black_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OmJsYWNrX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoe8I4xAXbO5UDCgBuZXR3b3JrX2lk2Icb9AoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:brown_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OmJyb3duX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoSiNZOobbpjoDCgBuZXR3b3JrX2lkJy0jwgoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:red_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OnJlZF9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaBdWFGLmCLFVAwoAbmV0d29ya19pZMYBJSEKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:orange_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0Om9yYW5nZV9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaMyJMrnPr7szAwoAbmV0d29ya19pZN6+7TUKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:yellow_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OnllbGxvd19nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaN6NaIhf6m0uAwoAbmV0d29ya19pZKRHXeoKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:lime_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmxpbWVfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2iF3E68/rB2EAMKAG5ldHdvcmtfaWSP7qQWCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:green_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OmdyZWVuX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNow5mo8aQDFboDCgBuZXR3b3JrX2lkoF11kgoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:cyan_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmN5YW5fZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2gnNB+cCFRJhwMKAG5ldHdvcmtfaWT9buMtCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:light_blue_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSYAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2gladnCDBKCigMKAG5ldHdvcmtfaWS5CszFCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:blue_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmJsdWVfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2giOZK+2nB1igMKAG5ldHdvcmtfaWR+e22CCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:purple_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSIAbWluZWNyYWZ0OnB1cnBsZV9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaIQU03txeAfHAwoAbmV0d29ya19pZLKbSE4KBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:magenta_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSMAbWluZWNyYWZ0Om1hZ2VudGFfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2i/SNqDJbfjMgMKAG5ldHdvcmtfaWQKf9UvCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:pink_glazed_terracotta", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OnBpbmtfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2hik8DVt4g+twMKAG5ldHdvcmtfaWTKzav2CgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:purpur_block", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnB1cnB1cl9ibG9jawQJAG5hbWVfaGFzaAgLwnUZGlzsAwoAbmV0d29ya19pZLD8ox4KBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQcAZGVmYXVsdAgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:purpur_block", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnB1cnB1cl9ibG9jawQJAG5hbWVfaGFzaAgLwnUZGlzsAwoAbmV0d29ya19pZPSAFFsKBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQUAbGluZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:packed_mud", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnBhY2tlZF9tdWQECQBuYW1lX2hhc2gHOMa121h4FgMKAG5ldHdvcmtfaWTUb6LyCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:mud_bricks", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0Om11ZF9icmlja3MECQBuYW1lX2hhc2iDL/SVl/PewQMKAG5ldHdvcmtfaWSkBjaDCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:nether_wart_block", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0Om5ldGhlcl93YXJ0X2Jsb2NrBAkAbmFtZV9oYXNo9XGS4GNnlV4DCgBuZXR3b3JrX2lkh3apIgoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:warped_wart_block", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OndhcnBlZF93YXJ0X2Jsb2NrBAkAbmFtZV9oYXNo9IqDS9yUPJoDCgBuZXR3b3JrX2lkMpKAbAoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:shroomlight", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OnNocm9vbWxpZ2h0BAkAbmFtZV9oYXNoZHCHcHX/HYADCgBuZXR3b3JrX2lkLG2JiwoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:crimson_nylium", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fbnlsaXVtBAkAbmFtZV9oYXNoOr6DJYW2bFYDCgBuZXR3b3JrX2lkuWpRDgoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:warped_nylium", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9ueWxpdW0ECQBuYW1lX2hhc2g0Zf89cfr3rwMKAG5ldHdvcmtfaWSu/kekCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:netherrack", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0Om5ldGhlcnJhY2sECQBuYW1lX2hhc2i/r5ZyRsvPyQMKAG5ldHdvcmtfaWTAiTOACgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:basalt", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OmJhc2FsdAQJAG5hbWVfaGFzaH+UQO2yWodiAwoAbmV0d29ya19pZBPNSV4KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:polished_basalt", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OnBvbGlzaGVkX2Jhc2FsdAQJAG5hbWVfaGFzaMS+L0gMnRcBAwoAbmV0d29ya19pZF+/mHwKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:smooth_basalt", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnNtb290aF9iYXNhbHQECQBuYW1lX2hhc2jKPUdz89kuNAMKAG5ldHdvcmtfaWTkb/oVCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:soul_soil", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OnNvdWxfc29pbAQJAG5hbWVfaGFzaC1/87ccutuTAwoAbmV0d29ya19pZKc63SMKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:dirt", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0OmRpcnQECQBuYW1lX2hhc2hXp6jnXAe+kQMKAG5ldHdvcmtfaWQmkQtoCgYAc3RhdGVzCAkAZGlydF90eXBlBgBub3JtYWwAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:dirt", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0OmRpcnQECQBuYW1lX2hhc2hXp6jnXAe+kQMKAG5ldHdvcmtfaWQId9pLCgYAc3RhdGVzCAkAZGlydF90eXBlBgBjb2Fyc2UAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:farmland", - "block_state_b64": "CgAACAQAbmFtZRIAbWluZWNyYWZ0OmZhcm1sYW5kBAkAbmFtZV9oYXNoxyQ5ag7LolADCgBuZXR3b3JrX2lkX618FQoGAHN0YXRlcwMSAG1vaXN0dXJpemVkX2Ftb3VudAAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:grass", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OmdyYXNzBAkAbmFtZV9oYXNosppASPWFlsUDCgBuZXR3b3JrX2lkhLLQkQoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:grass_path", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmdyYXNzX3BhdGgECQBuYW1lX2hhc2i0/KZV8Qsy+gMKAG5ldHdvcmtfaWT7CcdzCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:podzol", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OnBvZHpvbAQJAG5hbWVfaGFzaBzqokRjH4Z1AwoAbmV0d29ya19pZPPS/GUKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:mycelium", - "block_state_b64": "CgAACAQAbmFtZRIAbWluZWNyYWZ0Om15Y2VsaXVtBAkAbmFtZV9oYXNojTN09cKickIDCgBuZXR3b3JrX2lkLNPxXQoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:mud", - "block_state_b64": "CgAACAQAbmFtZQ0AbWluZWNyYWZ0Om11ZAQJAG5hbWVfaGFzaPb/3P+uLy+9AwoAbmV0d29ya19pZPIUlUkKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:stone", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OnN0b25lBAkAbmFtZV9oYXNoE3mqhJxzJycDCgBuZXR3b3JrX2lkIQ4xgAoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:iron_ore", - "block_state_b64": "CgAACAQAbmFtZRIAbWluZWNyYWZ0Omlyb25fb3JlBAkAbmFtZV9oYXNoS7BYtLnfx3gDCgBuZXR3b3JrX2lk3loneQoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:gold_ore", - "block_state_b64": "CgAACAQAbmFtZRIAbWluZWNyYWZ0OmdvbGRfb3JlBAkAbmFtZV9oYXNoC5Y+DUGXLC4DCgBuZXR3b3JrX2lkNhvMfwoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:diamond_ore", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmRpYW1vbmRfb3JlBAkAbmFtZV9oYXNokUOJ2wZZrGQDCgBuZXR3b3JrX2lk/dChVAoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:lapis_ore", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmxhcGlzX29yZQQJAG5hbWVfaGFzaMrmrUrSzb7qAwoAbmV0d29ya19pZMg+qK4KBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:redstone_ore", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnJlZHN0b25lX29yZQQJAG5hbWVfaGFzaFHVnp8Wc4JbAwoAbmV0d29ya19pZKDYvQoKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:coal_ore", - "block_state_b64": "CgAACAQAbmFtZRIAbWluZWNyYWZ0OmNvYWxfb3JlBAkAbmFtZV9oYXNo1OjA+Iuy51oDCgBuZXR3b3JrX2lk+R/aKAoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:copper_ore", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmNvcHBlcl9vcmUECQBuYW1lX2hhc2iSZduSntOzOwMKAG5ldHdvcmtfaWQtIuCnCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:emerald_ore", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmVtZXJhbGRfb3JlBAkAbmFtZV9oYXNoJTovr+VgINsDCgBuZXR3b3JrX2lknbkqCgoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:quartz_ore", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnF1YXJ0el9vcmUECQBuYW1lX2hhc2g0yNHLMK9TaQMKAG5ldHdvcmtfaWSzN7nzCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:nether_gold_ore", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0Om5ldGhlcl9nb2xkX29yZQQJAG5hbWVfaGFzaEJZ7segIBgBAwoAbmV0d29ya19pZNI9pDgKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:ancient_debris", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmFuY2llbnRfZGVicmlzBAkAbmFtZV9oYXNoNrbxMc9AwKcDCgBuZXR3b3JrX2lkrSNjEAoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:deepslate_iron_ore", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmRlZXBzbGF0ZV9pcm9uX29yZQQJAG5hbWVfaGFzaB/fDL9pgvXXAwoAbmV0d29ya19pZFA0bz4KBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:deepslate_gold_ore", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmRlZXBzbGF0ZV9nb2xkX29yZQQJAG5hbWVfaGFzaF9G7WYhKFinAwoAbmV0d29ya19pZHQTfBUKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:deepslate_diamond_ore", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OmRlZXBzbGF0ZV9kaWFtb25kX29yZQQJAG5hbWVfaGFzaEUH5USh+iD3AwoAbmV0d29ya19pZHP6VzAKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:deepslate_lapis_ore", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OmRlZXBzbGF0ZV9sYXBpc19vcmUECQBuYW1lX2hhc2j+yFxU/KZs1gMKAG5ldHdvcmtfaWRKINzICgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:deepslate_redstone_ore", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmRlZXBzbGF0ZV9yZWRzdG9uZV9vcmUECQBuYW1lX2hhc2iVgM3wWWD6ugMKAG5ldHdvcmtfaWReBdYRCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:deepslate_emerald_ore", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OmRlZXBzbGF0ZV9lbWVyYWxkX29yZQQJAG5hbWVfaGFzaNlfo5HTwS6wAwoAbmV0d29ya19pZNeie6sKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:deepslate_coal_ore", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmRlZXBzbGF0ZV9jb2FsX29yZQQJAG5hbWVfaGFzaIjikmcbRrPPAwoAbmV0d29ya19pZD9TiygKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:deepslate_copper_ore", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OmRlZXBzbGF0ZV9jb3BwZXJfb3JlBAkAbmFtZV9oYXNottjV4Ev5LAQDCgBuZXR3b3JrX2lkP23rgQoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:gravel", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OmdyYXZlbAQJAG5hbWVfaGFzaOFxz8XJd2r/AwoAbmV0d29ya19pZBpfI1sKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:granite", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OmdyYW5pdGUECQBuYW1lX2hhc2iq+Dur2pw4AwMKAG5ldHdvcmtfaWT2NMfJCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:diorite", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OmRpb3JpdGUECQBuYW1lX2hhc2iaFsq2iinZBQMKAG5ldHdvcmtfaWQqGE6XCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:andesite", - "block_state_b64": "CgAACAQAbmFtZRIAbWluZWNyYWZ0OmFuZGVzaXRlBAkAbmFtZV9oYXNosaLIEnQQoSYDCgBuZXR3b3JrX2lkEApRZAoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:blackstone", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmJsYWNrc3RvbmUECQBuYW1lX2hhc2iMFYziD80D6QMKAG5ldHdvcmtfaWSrUryHCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:deepslate", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmRlZXBzbGF0ZQQJAG5hbWVfaGFzaKX5pAblxz8TAwoAbmV0d29ya19pZOJoQjsKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:polished_granite", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OnBvbGlzaGVkX2dyYW5pdGUECQBuYW1lX2hhc2iLiEfys8pFIAMKAG5ldHdvcmtfaWTCxxcHCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:polished_diorite", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OnBvbGlzaGVkX2Rpb3JpdGUECQBuYW1lX2hhc2hTxY4fKmNmlAMKAG5ldHdvcmtfaWTmtjdRCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:polished_andesite", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnBvbGlzaGVkX2FuZGVzaXRlBAkAbmFtZV9oYXNovl28uFk4HuQDCgBuZXR3b3JrX2lklFjuCwoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:polished_blackstone", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmUECQBuYW1lX2hhc2jT9fHCl6vWQQMKAG5ldHdvcmtfaWR/Ho6oCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:polished_deepslate", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZQQJAG5hbWVfaGFzaHC1edoaWF3uAwoAbmV0d29ya19pZCPeQsEKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:sand", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0OnNhbmQECQBuYW1lX2hhc2i6lthXXbAyWAMKAG5ldHdvcmtfaWTekU/mCgYAc3RhdGVzCAkAc2FuZF90eXBlBgBub3JtYWwAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:sand", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0OnNhbmQECQBuYW1lX2hhc2i6lthXXbAyWAMKAG5ldHdvcmtfaWSTgcqmCgYAc3RhdGVzCAkAc2FuZF90eXBlAwByZWQAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:cactus", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OmNhY3R1cwQJAG5hbWVfaGFzaCG9zL0N4wvGAwoAbmV0d29ya19pZDeCERAKBgBzdGF0ZXMDAwBhZ2UAAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:oak_log", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0Om9ha19sb2cECQBuYW1lX2hhc2ho6TS+K7PZFQMKAG5ldHdvcmtfaWQjfjoxCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:stripped_oak_log", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OnN0cmlwcGVkX29ha19sb2cECQBuYW1lX2hhc2h8dqh+OOHU4wMKAG5ldHdvcmtfaWSYKjdrCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:spruce_log", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnNwcnVjZV9sb2cECQBuYW1lX2hhc2hZ03qaLoF3WgMKAG5ldHdvcmtfaWRlFD8eCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:stripped_spruce_log", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX3NwcnVjZV9sb2cECQBuYW1lX2hhc2iNrhKjS5IyrgMKAG5ldHdvcmtfaWRQcEC3CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:birch_log", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmJpcmNoX2xvZwQJAG5hbWVfaGFzaBUzT3NxsZAnAwoAbmV0d29ya19pZBKN3VQKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:stripped_birch_log", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OnN0cmlwcGVkX2JpcmNoX2xvZwQJAG5hbWVfaGFzaCFKS4AeuSidAwoAbmV0d29ya19pZN0IONIKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:jungle_log", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0Omp1bmdsZV9sb2cECQBuYW1lX2hhc2gkwW0KNulqDgMKAG5ldHdvcmtfaWQaziU/CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:stripped_jungle_log", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2p1bmdsZV9sb2cECQBuYW1lX2hhc2hAwMsgOk02JAMKAG5ldHdvcmtfaWQvls0eCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:acacia_log", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmFjYWNpYV9sb2cECQBuYW1lX2hhc2iV48VpYhjoYQMKAG5ldHdvcmtfaWRxEqe0CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:stripped_acacia_log", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2FjYWNpYV9sb2cECQBuYW1lX2hhc2hJb0lQqnEqlgMKAG5ldHdvcmtfaWRg3IdRCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:dark_oak_log", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmRhcmtfb2FrX2xvZwQJAG5hbWVfaGFzaIWfVRd0XUo3AwoAbmV0d29ya19pZPMM7LYKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:stripped_dark_oak_log", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX2Rhcmtfb2FrX2xvZwQJAG5hbWVfaGFzaPFTdxRdPwkOAwoAbmV0d29ya19pZDIzenIKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:mangrove_log", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0Om1hbmdyb3ZlX2xvZwQJAG5hbWVfaGFzaHZe6DzPZBobAwoAbmV0d29ya19pZG6DuYkKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:stripped_mangrove_log", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX21hbmdyb3ZlX2xvZwQJAG5hbWVfaGFzaLqIBo4hwA//AwoAbmV0d29ya19pZPtRn7UKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:cherry_log", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmNoZXJyeV9sb2cECQBuYW1lX2hhc2hwFlaioppB1wMKAG5ldHdvcmtfaWS2sdXECgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:stripped_cherry_log", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2NoZXJyeV9sb2cECQBuYW1lX2hhc2i85H6G+WhXaAMKAG5ldHdvcmtfaWRjzoglCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:crimson_stem", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmNyaW1zb25fc3RlbQQJAG5hbWVfaGFzaM0FzfL0UTKZAwoAbmV0d29ya19pZKvzID0KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:stripped_crimson_stem", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX2NyaW1zb25fc3RlbQQJAG5hbWVfaGFzaDlA6nood57EAwoAbmV0d29ya19pZHrIqjIKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:warped_stem", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OndhcnBlZF9zdGVtBAkAbmFtZV9oYXNon7cKfPZxdrUDCgBuZXR3b3JrX2lkerWyMwoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:stripped_warped_stem", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX3dhcnBlZF9zdGVtBAkAbmFtZV9oYXNoEw+y0dDPSd8DCgBuZXR3b3JrX2lkIQ9vBAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWSYGFlqCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQACAkAd29vZF90eXBlAwBvYWsAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWSxnUzvCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQBCAkAd29vZF90eXBlAwBvYWsAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWToyw4RCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQACAkAd29vZF90eXBlBgBzcHJ1Y2UAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWTL0a3ZCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQBCAkAd29vZF90eXBlBgBzcHJ1Y2UAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWQV99vJCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQACAkAd29vZF90eXBlBQBiaXJjaAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWQYDJk1CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQBCAkAd29vZF90eXBlBQBiaXJjaAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWSfH48gCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQACAkAd29vZF90eXBlBgBqdW5nbGUAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWQ44auiCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQBCAkAd29vZF90eXBlBgBqdW5nbGUAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWSogpPYCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQACAkAd29vZF90eXBlBgBhY2FjaWEAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWSD7hT1CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQBCAkAd29vZF90eXBlBgBhY2FjaWEAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWQagb3gCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQACAkAd29vZF90eXBlCABkYXJrX29hawADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWQdnWU+CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQBCAkAd29vZF90eXBlCABkYXJrX29hawADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:mangrove_wood", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0Om1hbmdyb3ZlX3dvb2QECQBuYW1lX2hhc2iXVxG0JG2fVAMKAG5ldHdvcmtfaWTok1JCCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:stripped_mangrove_wood", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OnN0cmlwcGVkX21hbmdyb3ZlX3dvb2QECQBuYW1lX2hhc2h7CkbaBF7/WAMKAG5ldHdvcmtfaWQLAX88CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:cherry_wood", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmNoZXJyeV93b29kBAkAbmFtZV9oYXNoAW8srlmpBM8DCgBuZXR3b3JrX2lkEALMfAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AQwAc3RyaXBwZWRfYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:stripped_cherry_wood", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX2NoZXJyeV93b29kBAkAbmFtZV9oYXNo/e7KXv+CB38DCgBuZXR3b3JrX2lkg5aVtQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:crimson_hyphae", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25faHlwaGFlBAkAbmFtZV9oYXNouRmKmfSqEWADCgBuZXR3b3JrX2lk+Tm5rQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:stripped_crimson_hyphae", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OnN0cmlwcGVkX2NyaW1zb25faHlwaGFlBAkAbmFtZV9oYXNoFffwmABq4LUDCgBuZXR3b3JrX2lkZAlUbgoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:warped_hyphae", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9oeXBoYWUECQBuYW1lX2hhc2hn8plQUr6pmQMKAG5ldHdvcmtfaWRU2AIBCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:stripped_warped_hyphae", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OnN0cmlwcGVkX3dhcnBlZF9oeXBoYWUECQBuYW1lX2hhc2irKq+HYPSgjQMKAG5ldHdvcmtfaWSbrOPDCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:bamboo_block", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmJhbWJvb19ibG9jawQJAG5hbWVfaGFzaAbDeur6stIBAwoAbmV0d29ya19pZCJAwn0KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:stripped_bamboo_block", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX2JhbWJvb19ibG9jawQJAG5hbWVfaGFzaJpwytpZOZM9AwoAbmV0d29ya19pZKuRbNEKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:leaves", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OmxlYXZlcwQJAG5hbWVfaGFzaACPIsusW0mnAwoAbmV0d29ya19pZOmqtzMKBgBzdGF0ZXMIDQBvbGRfbGVhZl90eXBlAwBvYWsBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:leaves", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OmxlYXZlcwQJAG5hbWVfaGFzaACPIsusW0mnAwoAbmV0d29ya19pZFMVNEQKBgBzdGF0ZXMIDQBvbGRfbGVhZl90eXBlBgBzcHJ1Y2UBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:leaves", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OmxlYXZlcwQJAG5hbWVfaGFzaACPIsusW0mnAwoAbmV0d29ya19pZKCZEm8KBgBzdGF0ZXMIDQBvbGRfbGVhZl90eXBlBQBiaXJjaAEOAHBlcnNpc3RlbnRfYml0AAEKAHVwZGF0ZV9iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:leaves", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OmxlYXZlcwQJAG5hbWVfaGFzaACPIsusW0mnAwoAbmV0d29ya19pZABprGgKBgBzdGF0ZXMIDQBvbGRfbGVhZl90eXBlBgBqdW5nbGUBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:leaves2", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OmxlYXZlczIECQBuYW1lX2hhc2gy/bgrncY1ZAMKAG5ldHdvcmtfaWSFh3olCgYAc3RhdGVzCA0AbmV3X2xlYWZfdHlwZQYAYWNhY2lhAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:leaves2", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OmxlYXZlczIECQBuYW1lX2hhc2gy/bgrncY1ZAMKAG5ldHdvcmtfaWTvEAyeCgYAc3RhdGVzCA0AbmV3X2xlYWZfdHlwZQgAZGFya19vYWsBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:mangrove_leaves", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX2xlYXZlcwQJAG5hbWVfaGFzaKyI/dWvhEG8AwoAbmV0d29ya19pZPQxCZ8KBgBzdGF0ZXMBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:cherry_leaves", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9sZWF2ZXMECQBuYW1lX2hhc2giTs9ChhYBlQMKAG5ldHdvcmtfaWR8bPpwCgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:azalea_leaves", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmF6YWxlYV9sZWF2ZXMECQBuYW1lX2hhc2iXFhD57wFS7AMKAG5ldHdvcmtfaWTNB/9ECgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:azalea_leaves_flowered", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmF6YWxlYV9sZWF2ZXNfZmxvd2VyZWQECQBuYW1lX2hhc2gs8jxlS/pMrwMKAG5ldHdvcmtfaWQ7W4PyCgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:sapling", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWQmoOEvCgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUDAG9hawADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:sapling", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWQO8pAmCgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUGAHNwcnVjZQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:sapling", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWQDHhokCgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUFAGJpcmNoAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:sapling", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWTdQrcyCgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUGAGp1bmdsZQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:sapling", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWRCDffNCgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUGAGFjYWNpYQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:sapling", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWR0BRzPCgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUIAGRhcmtfb2FrAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:mangrove_propagule", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0Om1hbmdyb3ZlX3Byb3BhZ3VsZQQJAG5hbWVfaGFzaJGeox6hkfLFAwoAbmV0d29ya19pZAIpvpYKBgBzdGF0ZXMBBwBoYW5naW5nAAMPAHByb3BhZ3VsZV9zdGFnZQAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:cherry_sapling", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNoZXJyeV9zYXBsaW5nBAkAbmFtZV9oYXNoGrPpNMf1LtcDCgBuZXR3b3JrX2lkypakXQoGAHN0YXRlcwEHAGFnZV9iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:bee_nest", - "block_state_b64": "CgAACAQAbmFtZRIAbWluZWNyYWZ0OmJlZV9uZXN0BAkAbmFtZV9oYXNo2R2WBxUHEZIDCgBuZXR3b3JrX2lkiXWLEAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAADCwBob25leV9sZXZlbAAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:wheat_seeds" - }, - { - "id": "minecraft:pumpkin_seeds" - }, - { - "id": "minecraft:melon_seeds" - }, - { - "id": "minecraft:beetroot_seeds" - }, - { - "id": "minecraft:torchflower_seeds" - }, - { - "id": "minecraft:pitcher_pod" - }, - { - "id": "minecraft:wheat" - }, - { - "id": "minecraft:beetroot" - }, - { - "id": "minecraft:potato" - }, - { - "id": "minecraft:poisonous_potato" - }, - { - "id": "minecraft:carrot" - }, - { - "id": "minecraft:golden_carrot" - }, - { - "id": "minecraft:apple" - }, - { - "id": "minecraft:golden_apple" - }, - { - "id": "minecraft:enchanted_golden_apple" - }, - { - "id": "minecraft:melon_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Om1lbG9uX2Jsb2NrBAkAbmFtZV9oYXNoXxSm0iYpAx8DCgBuZXR3b3JrX2lkC9rqygoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:melon_slice" - }, - { - "id": "minecraft:glistering_melon_slice" - }, - { - "id": "minecraft:sweet_berries" - }, - { - "id": "minecraft:glow_berries" - }, - { - "id": "minecraft:pumpkin", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OnB1bXBraW4ECQBuYW1lX2hhc2gc8A3jaSzWbgMKAG5ldHdvcmtfaWRFGA+xCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:carved_pumpkin", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNhcnZlZF9wdW1wa2luBAkAbmFtZV9oYXNoPu1T0MJuG90DCgBuZXR3b3JrX2lkXNNn5QoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:lit_pumpkin", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmxpdF9wdW1wa2luBAkAbmFtZV9oYXNo7gWtEm2uPL0DCgBuZXR3b3JrX2lki8sU4AoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:honeycomb" - }, - { - "id": "minecraft:tallgrass", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OnRhbGxncmFzcwQJAG5hbWVfaGFzaC3PXpAXXYswAwoAbmV0d29ya19pZOh33DMKBgBzdGF0ZXMIDwB0YWxsX2dyYXNzX3R5cGUEAGZlcm4AAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:double_plant", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZMx1sfgKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQQAZmVybgEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:tallgrass", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OnRhbGxncmFzcwQJAG5hbWVfaGFzaC3PXpAXXYswAwoAbmV0d29ya19pZErptfIKBgBzdGF0ZXMIDwB0YWxsX2dyYXNzX3R5cGUEAHRhbGwAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:double_plant", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZAbadmIKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQUAZ3Jhc3MBDwB1cHBlcl9ibG9ja19iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:nether_sprouts" - }, - { - "id": "minecraft:fire_coral", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmZpcmVfY29yYWwECQBuYW1lX2hhc2hOHyyECVQVJwMKAG5ldHdvcmtfaWS9vF0UCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:brain_coral", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmJyYWluX2NvcmFsBAkAbmFtZV9oYXNoRiWlLCwA2ycDCgBuZXR3b3JrX2lkrjAuhgoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:bubble_coral", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmJ1YmJsZV9jb3JhbAQJAG5hbWVfaGFzaJz6rWnl+v2qAwoAbmV0d29ya19pZImIWy0KBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:tube_coral", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnR1YmVfY29yYWwECQBuYW1lX2hhc2iYa8oO/tgk7wMKAG5ldHdvcmtfaWRTfND5CgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:horn_coral", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0Omhvcm5fY29yYWwECQBuYW1lX2hhc2iZnRHjZbnLPgMKAG5ldHdvcmtfaWR+GGp8CgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:dead_fire_coral", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmRlYWRfZmlyZV9jb3JhbAQJAG5hbWVfaGFzaEPU6tFy/latAwoAbmV0d29ya19pZNMa7V4KBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:dead_brain_coral", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmRlYWRfYnJhaW5fY29yYWwECQBuYW1lX2hhc2j5L6QJCISvzwMKAG5ldHdvcmtfaWQkKzeiCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:dead_bubble_coral", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmRlYWRfYnViYmxlX2NvcmFsBAkAbmFtZV9oYXNoSTOZ/8wpeNYDCgBuZXR3b3JrX2lka6w9DAoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:dead_tube_coral", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmRlYWRfdHViZV9jb3JhbAQJAG5hbWVfaGFzaJGjNWhlaIJeAwoAbmV0d29ya19pZO3Z0ygKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:dead_horn_coral", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmRlYWRfaG9ybl9jb3JhbAQJAG5hbWVfaGFzaJBkz3qt+g2cAwoAbmV0d29ya19pZBAN+eYKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:coral_fan", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmNvcmFsX2ZhbgQJAG5hbWVfaGFzaAFROjbTm8JzAwoAbmV0d29ya19pZOg7iS4KBgBzdGF0ZXMICwBjb3JhbF9jb2xvcgMAcmVkAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:coral_fan", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmNvcmFsX2ZhbgQJAG5hbWVfaGFzaAFROjbTm8JzAwoAbmV0d29ya19pZIDj8HMKBgBzdGF0ZXMICwBjb3JhbF9jb2xvcgQAcGluawMTAGNvcmFsX2Zhbl9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:coral_fan", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmNvcmFsX2ZhbgQJAG5hbWVfaGFzaAFROjbTm8JzAwoAbmV0d29ya19pZLCJP0kKBgBzdGF0ZXMICwBjb3JhbF9jb2xvcgYAcHVycGxlAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:coral_fan", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmNvcmFsX2ZhbgQJAG5hbWVfaGFzaAFROjbTm8JzAwoAbmV0d29ya19pZFz2ly4KBgBzdGF0ZXMICwBjb3JhbF9jb2xvcgQAYmx1ZQMTAGNvcmFsX2Zhbl9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:coral_fan", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmNvcmFsX2ZhbgQJAG5hbWVfaGFzaAFROjbTm8JzAwoAbmV0d29ya19pZE4TgnYKBgBzdGF0ZXMICwBjb3JhbF9jb2xvcgYAeWVsbG93AxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:coral_fan_dead", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNvcmFsX2Zhbl9kZWFkBAkAbmFtZV9oYXNo3kgokLV4uQIDCgBuZXR3b3JrX2lkdhLQzwoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yAwByZWQDEwBjb3JhbF9mYW5fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:coral_fan_dead", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNvcmFsX2Zhbl9kZWFkBAkAbmFtZV9oYXNo3kgokLV4uQIDCgBuZXR3b3JrX2lkSi6srQoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABwaW5rAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:coral_fan_dead", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNvcmFsX2Zhbl9kZWFkBAkAbmFtZV9oYXNo3kgokLV4uQIDCgBuZXR3b3JrX2lkGiGSzAoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgBwdXJwbGUDEwBjb3JhbF9mYW5fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:coral_fan_dead", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNvcmFsX2Zhbl9kZWFkBAkAbmFtZV9oYXNo3kgokLV4uQIDCgBuZXR3b3JrX2lkmvZKOgoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABibHVlAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:coral_fan_dead", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNvcmFsX2Zhbl9kZWFkBAkAbmFtZV9oYXNo3kgokLV4uQIDCgBuZXR3b3JrX2lknLw+4QoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgB5ZWxsb3cDEwBjb3JhbF9mYW5fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:crimson_roots", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmNyaW1zb25fcm9vdHMECQBuYW1lX2hhc2j1fWgQLViv5QMKAG5ldHdvcmtfaWRLh5DXCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:warped_roots", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OndhcnBlZF9yb290cwQJAG5hbWVfaGFzaBc3WvbJOLlkAwoAbmV0d29ya19pZNLgDnAKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:yellow_flower", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnllbGxvd19mbG93ZXIECQBuYW1lX2hhc2jWbU1pF0OUGAMKAG5ldHdvcmtfaWQgO3hpCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWSqsqQGCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUFAHBvcHB5AAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWTqDajjCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUGAG9yY2hpZAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWT5CjveCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUGAGFsbGl1bQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWTORIBJCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUJAGhvdXN0b25pYQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWTuNhmYCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUJAHR1bGlwX3JlZAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWT0O4nfCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUMAHR1bGlwX29yYW5nZQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWTqkthyCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGULAHR1bGlwX3doaXRlAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWRMbBA7CgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUKAHR1bGlwX3BpbmsAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWRexMAuCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUFAG94ZXllAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWQgs7BECgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUKAGNvcm5mbG93ZXIAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWRvDuNbCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUSAGxpbHlfb2ZfdGhlX3ZhbGxleQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:double_plant", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZOemRt4KBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQkAc3VuZmxvd2VyAQ8AdXBwZXJfYmxvY2tfYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:double_plant", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZOFugoEKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQcAc3lyaW5nYQEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:double_plant", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZN4O+/gKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQQAcm9zZQEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:double_plant", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZI3w4GMKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQcAcGFlb25pYQEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:pitcher_plant", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnBpdGNoZXJfcGxhbnQECQBuYW1lX2hhc2hRJHzsbDH+SQMKAG5ldHdvcmtfaWRnY76VCgYAc3RhdGVzAQ8AdXBwZXJfYmxvY2tfYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:pink_petals", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OnBpbmtfcGV0YWxzBAkAbmFtZV9oYXNo6DQwN9SwV3QDCgBuZXR3b3JrX2lkNWneGgoGAHN0YXRlcwMGAGdyb3d0aAAAAAAIHABtaW5lY3JhZnQ6Y2FyZGluYWxfZGlyZWN0aW9uBQBzb3V0aAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:wither_rose", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OndpdGhlcl9yb3NlBAkAbmFtZV9oYXNoaSKxl3I516gDCgBuZXR3b3JrX2lkATXLPwoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:torchflower", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OnRvcmNoZmxvd2VyBAkAbmFtZV9oYXNoL+mHtElwbqQDCgBuZXR3b3JrX2lkI34O+AoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:white_dye" - }, - { - "id": "minecraft:light_gray_dye" - }, - { - "id": "minecraft:gray_dye" - }, - { - "id": "minecraft:black_dye" - }, - { - "id": "minecraft:brown_dye" - }, - { - "id": "minecraft:red_dye" - }, - { - "id": "minecraft:orange_dye" - }, - { - "id": "minecraft:yellow_dye" - }, - { - "id": "minecraft:lime_dye" - }, - { - "id": "minecraft:green_dye" - }, - { - "id": "minecraft:cyan_dye" - }, - { - "id": "minecraft:light_blue_dye" - }, - { - "id": "minecraft:blue_dye" - }, - { - "id": "minecraft:purple_dye" - }, - { - "id": "minecraft:magenta_dye" - }, - { - "id": "minecraft:pink_dye" - }, - { - "id": "minecraft:ink_sac" - }, - { - "id": "minecraft:glow_ink_sac" - }, - { - "id": "minecraft:cocoa_beans" - }, - { - "id": "minecraft:lapis_lazuli" - }, - { - "id": "minecraft:bone_meal" - }, - { - "id": "minecraft:vine", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0OnZpbmUECQBuYW1lX2hhc2j0Sj8/XeXOLAMKAG5ldHdvcmtfaWSUkDtbCgYAc3RhdGVzAxMAdmluZV9kaXJlY3Rpb25fYml0cwAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:weeping_vines", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OndlZXBpbmdfdmluZXMECQBuYW1lX2hhc2jrLgLHkQygiwMKAG5ldHdvcmtfaWQ8NHSJCgYAc3RhdGVzAxEAd2VlcGluZ192aW5lc19hZ2UAAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:twisting_vines", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OnR3aXN0aW5nX3ZpbmVzBAkAbmFtZV9oYXNoDYR5QgVUQJADCgBuZXR3b3JrX2lk5kYVIQoGAHN0YXRlcwMSAHR3aXN0aW5nX3ZpbmVzX2FnZQAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:waterlily", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OndhdGVybGlseQQJAG5hbWVfaGFzaEHgC4c1SXg0AwoAbmV0d29ya19pZOOerp8KBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:seagrass", - "block_state_b64": "CgAACAQAbmFtZRIAbWluZWNyYWZ0OnNlYWdyYXNzBAkAbmFtZV9oYXNoHSBFtoHdWxIDCgBuZXR3b3JrX2lkd3lhEAoGAHN0YXRlcwgOAHNlYV9ncmFzc190eXBlBwBkZWZhdWx0AAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:kelp" - }, - { - "id": "minecraft:deadbush", - "block_state_b64": "CgAACAQAbmFtZRIAbWluZWNyYWZ0OmRlYWRidXNoBAkAbmFtZV9oYXNoPFODe4IScnYDCgBuZXR3b3JrX2lkVfnl+goGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:bamboo", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OmJhbWJvbwQJAG5hbWVfaGFzaBgpGmyzhedCAwoAbmV0d29ya19pZIZv1nYKBgBzdGF0ZXMBBwBhZ2VfYml0AAgQAGJhbWJvb19sZWFmX3NpemUJAG5vX2xlYXZlcwgWAGJhbWJvb19zdGFsa190aGlja25lc3MEAHRoaW4AAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:snow", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0OnNub3cECQBuYW1lX2hhc2gVHr5XXdETWAMKAG5ldHdvcmtfaWQ0zCeHCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:ice", - "block_state_b64": "CgAACAQAbmFtZQ0AbWluZWNyYWZ0OmljZQQJAG5hbWVfaGFzaNF26f+uUT29AwoAbmV0d29ya19pZOUMaQYKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:packed_ice", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnBhY2tlZF9pY2UECQBuYW1lX2hhc2hk4bu123ZrFgMKAG5ldHdvcmtfaWTr/ooaCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:blue_ice", - "block_state_b64": "CgAACAQAbmFtZRIAbWluZWNyYWZ0OmJsdWVfaWNlBAkAbmFtZV9oYXNo+EKxYgFhKcgDCgBuZXR3b3JrX2lkxfsA8goGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:snow_layer", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnNub3dfbGF5ZXIECQBuYW1lX2hhc2hXka6atMYUCQMKAG5ldHdvcmtfaWRCrIPcCgYAc3RhdGVzAQsAY292ZXJlZF9iaXQAAwYAaGVpZ2h0AAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:pointed_dripstone", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnBvaW50ZWRfZHJpcHN0b25lBAkAbmFtZV9oYXNoJMISzmHQgt8DCgBuZXR3b3JrX2lkbWrtYgoGAHN0YXRlcwgTAGRyaXBzdG9uZV90aGlja25lc3MDAHRpcAEHAGhhbmdpbmcBAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:dripstone_block", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmRyaXBzdG9uZV9ibG9jawQJAG5hbWVfaGFzaIIXnEqY77YsAwoAbmV0d29ya19pZMZi2kwKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:moss_carpet", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Om1vc3NfY2FycGV0BAkAbmFtZV9oYXNo/NEDxRPTshYDCgBuZXR3b3JrX2lkaGG3QwoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:moss_block", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0Om1vc3NfYmxvY2sECQBuYW1lX2hhc2iovcsPUYX2tgMKAG5ldHdvcmtfaWT3JSbfCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:dirt_with_roots", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmRpcnRfd2l0aF9yb290cwQJAG5hbWVfaGFzaLCNDYPviDCIAwoAbmV0d29ya19pZNCkwzoKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:hanging_roots", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0Omhhbmdpbmdfcm9vdHMECQBuYW1lX2hhc2jaXn+Y5UZpDAMKAG5ldHdvcmtfaWRU4c2vCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:mangrove_roots", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0Om1hbmdyb3ZlX3Jvb3RzBAkAbmFtZV9oYXNoa786PzQGZ6kDCgBuZXR3b3JrX2lklA0AHgoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:muddy_mangrove_roots", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0Om11ZGR5X21hbmdyb3ZlX3Jvb3RzBAkAbmFtZV9oYXNo9YApdHpo1RkDCgBuZXR3b3JrX2lkH0Oc4woGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:big_dripleaf", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmJpZ19kcmlwbGVhZgQJAG5hbWVfaGFzaGBEhXjo6qSdAwoAbmV0d29ya19pZMETsb8KBgBzdGF0ZXMBEQBiaWdfZHJpcGxlYWZfaGVhZAEIEQBiaWdfZHJpcGxlYWZfdGlsdAQAbm9uZQgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:small_dripleaf_block", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OnNtYWxsX2RyaXBsZWFmX2Jsb2NrBAkAbmFtZV9oYXNojxRAgXP9uWADCgBuZXR3b3JrX2lkozbVPwoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24EAGVhc3QBDwB1cHBlcl9ibG9ja19iaXQBAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:spore_blossom", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnNwb3JlX2Jsb3Nzb20ECQBuYW1lX2hhc2il3U72Gbco2gMKAG5ldHdvcmtfaWSbbbgcCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:azalea", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OmF6YWxlYQQJAG5hbWVfaGFzaNyUl+BW9JrBAwoAbmV0d29ya19pZO/XZtQKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:flowering_azalea", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmZsb3dlcmluZ19hemFsZWEECQBuYW1lX2hhc2ie9r33wz8kiwMKAG5ldHdvcmtfaWQ3ij0VCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:glow_lichen", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Omdsb3dfbGljaGVuBAkAbmFtZV9oYXNobyPUrIYlo44DCgBuZXR3b3JrX2lkCh8lSAoGAHN0YXRlcwMZAG11bHRpX2ZhY2VfZGlyZWN0aW9uX2JpdHM/AAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:amethyst_block", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmFtZXRoeXN0X2Jsb2NrBAkAbmFtZV9oYXNob+JK1iiAthcDCgBuZXR3b3JrX2lk8HtpzgoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:budding_amethyst", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmJ1ZGRpbmdfYW1ldGh5c3QECQBuYW1lX2hhc2gJvAwfI14fxgMKAG5ldHdvcmtfaWTQYqfACgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:amethyst_cluster", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmFtZXRoeXN0X2NsdXN0ZXIECQBuYW1lX2hhc2jK82S88Jgm8wMKAG5ldHdvcmtfaWSCPMPGCgYAc3RhdGVzCBQAbWluZWNyYWZ0OmJsb2NrX2ZhY2UCAHVwAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:large_amethyst_bud", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmxhcmdlX2FtZXRoeXN0X2J1ZAQJAG5hbWVfaGFzaAHhdpWD+sd5AwoAbmV0d29ya19pZKkQxOcKBgBzdGF0ZXMIFABtaW5lY3JhZnQ6YmxvY2tfZmFjZQIAdXAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:medium_amethyst_bud", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0Om1lZGl1bV9hbWV0aHlzdF9idWQECQBuYW1lX2hhc2g5lBGtC0DzZQMKAG5ldHdvcmtfaWSYiP4gCgYAc3RhdGVzCBQAbWluZWNyYWZ0OmJsb2NrX2ZhY2UCAHVwAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:small_amethyst_bud", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OnNtYWxsX2FtZXRoeXN0X2J1ZAQJAG5hbWVfaGFzaEnb4+q9PO4YAwoAbmV0d29ya19pZGWzxrQKBgBzdGF0ZXMIFABtaW5lY3JhZnQ6YmxvY2tfZmFjZQIAdXAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:tuff", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0OnR1ZmYECQBuYW1lX2hhc2h1Rwc1XYsBGwMKAG5ldHdvcmtfaWRwQGn0CgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:tuff_stairs", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OnR1ZmZfc3RhaXJzBAkAbmFtZV9oYXNoKjyNUBjcfZsDCgBuZXR3b3JrX2lk+LsycgoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:tuff_slab", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OnR1ZmZfc2xhYgQJAG5hbWVfaGFzaIhCGdlIsnMUAwoAbmV0d29ya19pZN1dUL4KBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:tuff_wall", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OnR1ZmZfd2FsbAQJAG5hbWVfaGFzaMyeeu1IRf03AwoAbmV0d29ya19pZDkIrosKBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:chiseled_tuff", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmNoaXNlbGVkX3R1ZmYECQBuYW1lX2hhc2iVliOT8OTQ9AMKAG5ldHdvcmtfaWTLNKOiCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:polished_tuff", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnBvbGlzaGVkX3R1ZmYECQBuYW1lX2hhc2hyaLe/KEVZ0gMKAG5ldHdvcmtfaWTcX3NrCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:polished_tuff_stairs", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OnBvbGlzaGVkX3R1ZmZfc3RhaXJzBAkAbmFtZV9oYXNo8yuah8QI1dcDCgBuZXR3b3JrX2lkjLoU4AoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:polished_tuff_slab", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OnBvbGlzaGVkX3R1ZmZfc2xhYgQJAG5hbWVfaGFzaLXdb48YvAsHAwoAbmV0d29ya19pZAnJ7W0KBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:polished_tuff_wall", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OnBvbGlzaGVkX3R1ZmZfd2FsbAQJAG5hbWVfaGFzaJVZj6QYWXUrAwoAbmV0d29ya19pZLU7dooKBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:tuff_bricks", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OnR1ZmZfYnJpY2tzBAkAbmFtZV9oYXNo/hbQ+mXSK7wDCgBuZXR3b3JrX2lk6gmIwQoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:tuff_brick_stairs", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnR1ZmZfYnJpY2tfc3RhaXJzBAkAbmFtZV9oYXNoWJpkAurUfKwDCgBuZXR3b3JrX2lkUMcjiwoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:tuff_brick_slab", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OnR1ZmZfYnJpY2tfc2xhYgQJAG5hbWVfaGFzaLqPMjVCv5dIAwoAbmV0d29ya19pZOmeRhcKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:tuff_brick_wall", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OnR1ZmZfYnJpY2tfd2FsbAQJAG5hbWVfaGFzaIL0IyNCOsonAwoAbmV0d29ya19pZJW4T5UKBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:chiseled_tuff_bricks", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OmNoaXNlbGVkX3R1ZmZfYnJpY2tzBAkAbmFtZV9oYXNo3oQw6gmxYuADCgBuZXR3b3JrX2lkm3D8AgoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:calcite", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OmNhbGNpdGUECQBuYW1lX2hhc2ixKLu8ZIdzDQMKAG5ldHdvcmtfaWQlSbJDCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:chicken" - }, - { - "id": "minecraft:porkchop" - }, - { - "id": "minecraft:beef" - }, - { - "id": "minecraft:mutton" - }, - { - "id": "minecraft:rabbit" - }, - { - "id": "minecraft:cod" - }, - { - "id": "minecraft:salmon" - }, - { - "id": "minecraft:tropical_fish" - }, - { - "id": "minecraft:pufferfish" - }, - { - "id": "minecraft:brown_mushroom", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmJyb3duX211c2hyb29tBAkAbmFtZV9oYXNonYw/FO78WDoDCgBuZXR3b3JrX2lkLh1OXAoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:red_mushroom", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnJlZF9tdXNocm9vbQQJAG5hbWVfaGFzaPpzJua7669xAwoAbmV0d29ya19pZCvWPYkKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:crimson_fungus", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fZnVuZ3VzBAkAbmFtZV9oYXNolIcCUuFM2u0DCgBuZXR3b3JrX2lkD2NN0QoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:warped_fungus", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9mdW5ndXMECQBuYW1lX2hhc2gq8bSnRVTAFgMKAG5ldHdvcmtfaWTkwS+rCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:brown_mushroom_block", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OmJyb3duX211c2hyb29tX2Jsb2NrBAkAbmFtZV9oYXNoIyjnbI6xy9sDCgBuZXR3b3JrX2lkdOMhDAoGAHN0YXRlcwMSAGh1Z2VfbXVzaHJvb21fYml0cw4AAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:red_mushroom_block", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OnJlZF9tdXNocm9vbV9ibG9jawQJAG5hbWVfaGFzaJTTyJbth9M9AwoAbmV0d29ya19pZM+AyboKBgBzdGF0ZXMDEgBodWdlX211c2hyb29tX2JpdHMOAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:brown_mushroom_block", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OmJyb3duX211c2hyb29tX2Jsb2NrBAkAbmFtZV9oYXNoIyjnbI6xy9sDCgBuZXR3b3JrX2lkbdt3CAoGAHN0YXRlcwMSAGh1Z2VfbXVzaHJvb21fYml0cw8AAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:brown_mushroom_block", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OmJyb3duX211c2hyb29tX2Jsb2NrBAkAbmFtZV9oYXNoIyjnbI6xy9sDCgBuZXR3b3JrX2lkSrMl9goGAHN0YXRlcwMSAGh1Z2VfbXVzaHJvb21fYml0cwAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:egg" - }, - { - "id": "minecraft:sugar_cane" - }, - { - "id": "minecraft:sugar" - }, - { - "id": "minecraft:rotten_flesh" - }, - { - "id": "minecraft:bone" - }, - { - "id": "minecraft:web", - "block_state_b64": "CgAACAQAbmFtZQ0AbWluZWNyYWZ0OndlYgQJAG5hbWVfaGFzaA4GKQCvG4i9AwoAbmV0d29ya19pZApt+jgKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:spider_eye" - }, - { - "id": "minecraft:mob_spawner", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Om1vYl9zcGF3bmVyBAkAbmFtZV9oYXNoNwGrCV/Fkh8DCgBuZXR3b3JrX2lkM1wTmgoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:monster_egg", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkqXH7RgoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGUFAHN0b25lAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:monster_egg", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkeIBb6QoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGULAGNvYmJsZXN0b25lAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:monster_egg", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkDZ2cFQoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGULAHN0b25lX2JyaWNrAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:monster_egg", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkOR/cTAoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGURAG1vc3N5X3N0b25lX2JyaWNrAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:monster_egg", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkqdwlHAoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGUTAGNyYWNrZWRfc3RvbmVfYnJpY2sAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:monster_egg", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkFqqPggoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGUUAGNoaXNlbGVkX3N0b25lX2JyaWNrAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:infested_deepslate", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmluZmVzdGVkX2RlZXBzbGF0ZQQJAG5hbWVfaGFzaICF2VYccxF1AwoAbmV0d29ya19pZDa/624KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:dragon_egg", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmRyYWdvbl9lZ2cECQBuYW1lX2hhc2inMzXrV+/e1wMKAG5ldHdvcmtfaWTgO1yRCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:turtle_egg", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnR1cnRsZV9lZ2cECQBuYW1lX2hhc2iwSRcxOJIJ9gMKAG5ldHdvcmtfaWSIRNUhCgYAc3RhdGVzCA0AY3JhY2tlZF9zdGF0ZQkAbm9fY3JhY2tzCBAAdHVydGxlX2VnZ19jb3VudAcAb25lX2VnZwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:sniffer_egg", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OnNuaWZmZXJfZWdnBAkAbmFtZV9oYXNoY1lozc8lPcYDCgBuZXR3b3JrX2lk7yb/2QoGAHN0YXRlcwgNAGNyYWNrZWRfc3RhdGUJAG5vX2NyYWNrcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:frog_spawn", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmZyb2dfc3Bhd24ECQBuYW1lX2hhc2iWmd7idp3ZZwMKAG5ldHdvcmtfaWRFzJudCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:pearlescent_froglight", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OnBlYXJsZXNjZW50X2Zyb2dsaWdodAQJAG5hbWVfaGFzaKkcFRyycYGyAwoAbmV0d29ya19pZJqYakAKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:verdant_froglight", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnZlcmRhbnRfZnJvZ2xpZ2h0BAkAbmFtZV9oYXNoA+eXuTBohrQDCgBuZXR3b3JrX2lkDIVnsQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:ochre_froglight", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0Om9jaHJlX2Zyb2dsaWdodAQJAG5hbWVfaGFzaMY59kjPe+c3AwoAbmV0d29ya19pZO2TD50KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:chicken_spawn_egg" - }, - { - "id": "minecraft:bee_spawn_egg" - }, - { - "id": "minecraft:cow_spawn_egg" - }, - { - "id": "minecraft:pig_spawn_egg" - }, - { - "id": "minecraft:sheep_spawn_egg" - }, - { - "id": "minecraft:wolf_spawn_egg" - }, - { - "id": "minecraft:polar_bear_spawn_egg" - }, - { - "id": "minecraft:ocelot_spawn_egg" - }, - { - "id": "minecraft:cat_spawn_egg" - }, - { - "id": "minecraft:mooshroom_spawn_egg" - }, - { - "id": "minecraft:bat_spawn_egg" - }, - { - "id": "minecraft:parrot_spawn_egg" - }, - { - "id": "minecraft:rabbit_spawn_egg" - }, - { - "id": "minecraft:llama_spawn_egg" - }, - { - "id": "minecraft:horse_spawn_egg" - }, - { - "id": "minecraft:donkey_spawn_egg" - }, - { - "id": "minecraft:mule_spawn_egg" - }, - { - "id": "minecraft:skeleton_horse_spawn_egg" - }, - { - "id": "minecraft:zombie_horse_spawn_egg" - }, - { - "id": "minecraft:tropical_fish_spawn_egg" - }, - { - "id": "minecraft:cod_spawn_egg" - }, - { - "id": "minecraft:pufferfish_spawn_egg" - }, - { - "id": "minecraft:salmon_spawn_egg" - }, - { - "id": "minecraft:dolphin_spawn_egg" - }, - { - "id": "minecraft:turtle_spawn_egg" - }, - { - "id": "minecraft:panda_spawn_egg" - }, - { - "id": "minecraft:fox_spawn_egg" - }, - { - "id": "minecraft:creeper_spawn_egg" - }, - { - "id": "minecraft:enderman_spawn_egg" - }, - { - "id": "minecraft:silverfish_spawn_egg" - }, - { - "id": "minecraft:skeleton_spawn_egg" - }, - { - "id": "minecraft:wither_skeleton_spawn_egg" - }, - { - "id": "minecraft:stray_spawn_egg" - }, - { - "id": "minecraft:slime_spawn_egg" - }, - { - "id": "minecraft:spider_spawn_egg" - }, - { - "id": "minecraft:zombie_spawn_egg" - }, - { - "id": "minecraft:zombie_pigman_spawn_egg" - }, - { - "id": "minecraft:husk_spawn_egg" - }, - { - "id": "minecraft:drowned_spawn_egg" - }, - { - "id": "minecraft:squid_spawn_egg" - }, - { - "id": "minecraft:glow_squid_spawn_egg" - }, - { - "id": "minecraft:cave_spider_spawn_egg" - }, - { - "id": "minecraft:witch_spawn_egg" - }, - { - "id": "minecraft:guardian_spawn_egg" - }, - { - "id": "minecraft:elder_guardian_spawn_egg" - }, - { - "id": "minecraft:endermite_spawn_egg" - }, - { - "id": "minecraft:magma_cube_spawn_egg" - }, - { - "id": "minecraft:strider_spawn_egg" - }, - { - "id": "minecraft:hoglin_spawn_egg" - }, - { - "id": "minecraft:piglin_spawn_egg" - }, - { - "id": "minecraft:zoglin_spawn_egg" - }, - { - "id": "minecraft:piglin_brute_spawn_egg" - }, - { - "id": "minecraft:goat_spawn_egg" - }, - { - "id": "minecraft:axolotl_spawn_egg" - }, - { - "id": "minecraft:warden_spawn_egg" - }, - { - "id": "minecraft:allay_spawn_egg" - }, - { - "id": "minecraft:frog_spawn_egg" - }, - { - "id": "minecraft:tadpole_spawn_egg" - }, - { - "id": "minecraft:trader_llama_spawn_egg" - }, - { - "id": "minecraft:camel_spawn_egg" - }, - { - "id": "minecraft:ghast_spawn_egg" - }, - { - "id": "minecraft:blaze_spawn_egg" - }, - { - "id": "minecraft:shulker_spawn_egg" - }, - { - "id": "minecraft:vindicator_spawn_egg" - }, - { - "id": "minecraft:evoker_spawn_egg" - }, - { - "id": "minecraft:vex_spawn_egg" - }, - { - "id": "minecraft:villager_spawn_egg" - }, - { - "id": "minecraft:wandering_trader_spawn_egg" - }, - { - "id": "minecraft:zombie_villager_spawn_egg" - }, - { - "id": "minecraft:phantom_spawn_egg" - }, - { - "id": "minecraft:pillager_spawn_egg" - }, - { - "id": "minecraft:ravager_spawn_egg" - }, - { - "id": "minecraft:iron_golem_spawn_egg" - }, - { - "id": "minecraft:snow_golem_spawn_egg" - }, - { - "id": "minecraft:sniffer_spawn_egg" - }, - { - "id": "minecraft:obsidian", - "block_state_b64": "CgAACAQAbmFtZRIAbWluZWNyYWZ0Om9ic2lkaWFuBAkAbmFtZV9oYXNoiz4qrb8QjyEDCgBuZXR3b3JrX2lkuqnPpQoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:crying_obsidian", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmNyeWluZ19vYnNpZGlhbgQJAG5hbWVfaGFzaKT0JlA7Z1K+AwoAbmV0d29ya19pZCjbPV4KBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:bedrock", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OmJlZHJvY2sECQBuYW1lX2hhc2hWfFrh4LVtxwMKAG5ldHdvcmtfaWT7fKz1CgYAc3RhdGVzAQ4AaW5maW5pYnVybl9iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:soul_sand", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OnNvdWxfc2FuZAQJAG5hbWVfaGFzaMaf+bccu+KTAwoAbmV0d29ya19pZBQSHrMKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:magma", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0Om1hZ21hBAkAbmFtZV9oYXNoqyTjKaIsWfYDCgBuZXR3b3JrX2lkyfWAZgoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:nether_wart" - }, - { - "id": "minecraft:end_stone", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmVuZF9zdG9uZQQJAG5hbWVfaGFzaH1J9jA39GJNAwoAbmV0d29ya19pZFeFQ7UKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:chorus_flower", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmNob3J1c19mbG93ZXIECQBuYW1lX2hhc2iMpSodli5uawMKAG5ldHdvcmtfaWRnd1ZWCgYAc3RhdGVzAwMAYWdlAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:chorus_plant", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmNob3J1c19wbGFudAQJAG5hbWVfaGFzaJhSrmNGKwaMAwoAbmV0d29ya19pZA3uVqMKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:chorus_fruit" - }, - { - "id": "minecraft:popped_chorus_fruit" - }, - { - "id": "minecraft:sponge", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OnNwb25nZQQJAG5hbWVfaGFzaLrd2ScYRDMiAwoAbmV0d29ya19pZF01rO0KBgBzdGF0ZXMICwBzcG9uZ2VfdHlwZQMAZHJ5AAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:sponge", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OnNwb25nZQQJAG5hbWVfaGFzaLrd2ScYRDMiAwoAbmV0d29ya19pZPiOc4QKBgBzdGF0ZXMICwBzcG9uZ2VfdHlwZQMAd2V0AAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkGnlaAwoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABibHVlAQgAZGVhZF9iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkSnHuagoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABwaW5rAQgAZGVhZF9iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkmkHyegoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgBwdXJwbGUBCABkZWFkX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkdpUDxgoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yAwByZWQBCABkZWFkX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkYNWvYgoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgB5ZWxsb3cBCABkZWFkX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkZSxBQgoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABibHVlAQgAZGVhZF9iaXQBAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lklSTVqQoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABwaW5rAQgAZGVhZF9iaXQBAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lk5fTYuQoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgBwdXJwbGUBCABkZWFkX2JpdAEAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkwUjqBAoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yAwByZWQBCABkZWFkX2JpdAEAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkq4iWoQoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgB5ZWxsb3cBCABkZWFkX2JpdAEAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:sculk", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OnNjdWxrBAkAbmFtZV9oYXNo2Lq7T5yQF8kDCgBuZXR3b3JrX2lkyqUPPgoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:sculk_vein", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnNjdWxrX3ZlaW4ECQBuYW1lX2hhc2gJUdhVooV4zwMKAG5ldHdvcmtfaWSUfn1XCgYAc3RhdGVzAxkAbXVsdGlfZmFjZV9kaXJlY3Rpb25fYml0cwAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:sculk_catalyst", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OnNjdWxrX2NhdGFseXN0BAkAbmFtZV9oYXNo+gCpbrCHST4DCgBuZXR3b3JrX2lkMJ2n/woGAHN0YXRlcwEFAGJsb29tAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:sculk_shrieker", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OnNjdWxrX3Nocmlla2VyBAkAbmFtZV9oYXNo5OXtyObniQ4DCgBuZXR3b3JrX2lkxapoNAoGAHN0YXRlcwEGAGFjdGl2ZQABCgBjYW5fc3VtbW9uAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:sculk_sensor", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnNjdWxrX3NlbnNvcgQJAG5hbWVfaGFzaCkmHreeTgNnAwoAbmV0d29ya19pZLj2WPcKBgBzdGF0ZXMDEgBzY3Vsa19zZW5zb3JfcGhhc2UAAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:calibrated_sculk_sensor", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OmNhbGlicmF0ZWRfc2N1bGtfc2Vuc29yBAkAbmFtZV9oYXNoffAcXXN/iJUDCgBuZXR3b3JrX2lkwOx3QQoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAxIAc2N1bGtfc2Vuc29yX3BoYXNlAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:reinforced_deepslate", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OnJlaW5mb3JjZWRfZGVlcHNsYXRlBAkAbmFtZV9oYXNoldDmj91EapQDCgBuZXR3b3JrX2lkHIt+aQoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:leather_helmet" - }, - { - "id": "minecraft:chainmail_helmet" - }, - { - "id": "minecraft:iron_helmet" - }, - { - "id": "minecraft:golden_helmet" - }, - { - "id": "minecraft:diamond_helmet" - }, - { - "id": "minecraft:netherite_helmet" - }, - { - "id": "minecraft:leather_chestplate" - }, - { - "id": "minecraft:chainmail_chestplate" - }, - { - "id": "minecraft:iron_chestplate" - }, - { - "id": "minecraft:golden_chestplate" - }, - { - "id": "minecraft:diamond_chestplate" - }, - { - "id": "minecraft:netherite_chestplate" - }, - { - "id": "minecraft:leather_leggings" - }, - { - "id": "minecraft:chainmail_leggings" - }, - { - "id": "minecraft:iron_leggings" - }, - { - "id": "minecraft:golden_leggings" - }, - { - "id": "minecraft:diamond_leggings" - }, - { - "id": "minecraft:netherite_leggings" - }, - { - "id": "minecraft:leather_boots" - }, - { - "id": "minecraft:chainmail_boots" - }, - { - "id": "minecraft:iron_boots" - }, - { - "id": "minecraft:golden_boots" - }, - { - "id": "minecraft:diamond_boots" - }, - { - "id": "minecraft:netherite_boots" - }, - { - "id": "minecraft:wooden_sword" - }, - { - "id": "minecraft:stone_sword" - }, - { - "id": "minecraft:iron_sword" - }, - { - "id": "minecraft:golden_sword" - }, - { - "id": "minecraft:diamond_sword" - }, - { - "id": "minecraft:netherite_sword" - }, - { - "id": "minecraft:wooden_axe" - }, - { - "id": "minecraft:stone_axe" - }, - { - "id": "minecraft:iron_axe" - }, - { - "id": "minecraft:golden_axe" - }, - { - "id": "minecraft:diamond_axe" - }, - { - "id": "minecraft:netherite_axe" - }, - { - "id": "minecraft:wooden_pickaxe" - }, - { - "id": "minecraft:stone_pickaxe" - }, - { - "id": "minecraft:iron_pickaxe" - }, - { - "id": "minecraft:golden_pickaxe" - }, - { - "id": "minecraft:diamond_pickaxe" - }, - { - "id": "minecraft:netherite_pickaxe" - }, - { - "id": "minecraft:wooden_shovel" - }, - { - "id": "minecraft:stone_shovel" - }, - { - "id": "minecraft:iron_shovel" - }, - { - "id": "minecraft:golden_shovel" - }, - { - "id": "minecraft:diamond_shovel" - }, - { - "id": "minecraft:netherite_shovel" - }, - { - "id": "minecraft:wooden_hoe" - }, - { - "id": "minecraft:stone_hoe" - }, - { - "id": "minecraft:iron_hoe" - }, - { - "id": "minecraft:golden_hoe" - }, - { - "id": "minecraft:diamond_hoe" - }, - { - "id": "minecraft:netherite_hoe" - }, - { - "id": "minecraft:bow" - }, - { - "id": "minecraft:crossbow" - }, - { - "id": "minecraft:arrow" - }, - { - "id": "minecraft:arrow", - "damage": 6 - }, - { - "id": "minecraft:arrow", - "damage": 7 - }, - { - "id": "minecraft:arrow", - "damage": 8 - }, - { - "id": "minecraft:arrow", - "damage": 9 - }, - { - "id": "minecraft:arrow", - "damage": 10 - }, - { - "id": "minecraft:arrow", - "damage": 11 - }, - { - "id": "minecraft:arrow", - "damage": 12 - }, - { - "id": "minecraft:arrow", - "damage": 13 - }, - { - "id": "minecraft:arrow", - "damage": 14 - }, - { - "id": "minecraft:arrow", - "damage": 15 - }, - { - "id": "minecraft:arrow", - "damage": 16 - }, - { - "id": "minecraft:arrow", - "damage": 17 - }, - { - "id": "minecraft:arrow", - "damage": 18 - }, - { - "id": "minecraft:arrow", - "damage": 19 - }, - { - "id": "minecraft:arrow", - "damage": 20 - }, - { - "id": "minecraft:arrow", - "damage": 21 - }, - { - "id": "minecraft:arrow", - "damage": 22 - }, - { - "id": "minecraft:arrow", - "damage": 23 - }, - { - "id": "minecraft:arrow", - "damage": 24 - }, - { - "id": "minecraft:arrow", - "damage": 25 - }, - { - "id": "minecraft:arrow", - "damage": 26 - }, - { - "id": "minecraft:arrow", - "damage": 27 - }, - { - "id": "minecraft:arrow", - "damage": 28 - }, - { - "id": "minecraft:arrow", - "damage": 29 - }, - { - "id": "minecraft:arrow", - "damage": 30 - }, - { - "id": "minecraft:arrow", - "damage": 31 - }, - { - "id": "minecraft:arrow", - "damage": 32 - }, - { - "id": "minecraft:arrow", - "damage": 33 - }, - { - "id": "minecraft:arrow", - "damage": 34 - }, - { - "id": "minecraft:arrow", - "damage": 35 - }, - { - "id": "minecraft:arrow", - "damage": 36 - }, - { - "id": "minecraft:arrow", - "damage": 37 - }, - { - "id": "minecraft:arrow", - "damage": 38 - }, - { - "id": "minecraft:arrow", - "damage": 39 - }, - { - "id": "minecraft:arrow", - "damage": 40 - }, - { - "id": "minecraft:arrow", - "damage": 41 - }, - { - "id": "minecraft:arrow", - "damage": 42 - }, - { - "id": "minecraft:arrow", - "damage": 43 - }, - { - "id": "minecraft:shield" - }, - { - "id": "minecraft:cooked_chicken" - }, - { - "id": "minecraft:cooked_porkchop" - }, - { - "id": "minecraft:cooked_beef" - }, - { - "id": "minecraft:cooked_mutton" - }, - { - "id": "minecraft:cooked_rabbit" - }, - { - "id": "minecraft:cooked_cod" - }, - { - "id": "minecraft:cooked_salmon" - }, - { - "id": "minecraft:bread" - }, - { - "id": "minecraft:mushroom_stew" - }, - { - "id": "minecraft:beetroot_soup" - }, - { - "id": "minecraft:rabbit_stew" - }, - { - "id": "minecraft:baked_potato" - }, - { - "id": "minecraft:cookie" - }, - { - "id": "minecraft:pumpkin_pie" - }, - { - "id": "minecraft:cake" - }, - { - "id": "minecraft:dried_kelp" - }, - { - "id": "minecraft:fishing_rod" - }, - { - "id": "minecraft:carrot_on_a_stick" - }, - { - "id": "minecraft:warped_fungus_on_a_stick" - }, - { - "id": "minecraft:snowball" - }, - { - "id": "minecraft:shears" - }, - { - "id": "minecraft:flint_and_steel" - }, - { - "id": "minecraft:lead" - }, - { - "id": "minecraft:clock" - }, - { - "id": "minecraft:compass" - }, - { - "id": "minecraft:recovery_compass" - }, - { - "id": "minecraft:goat_horn" - }, - { - "id": "minecraft:goat_horn", - "damage": 1 - }, - { - "id": "minecraft:goat_horn", - "damage": 2 - }, - { - "id": "minecraft:goat_horn", - "damage": 3 - }, - { - "id": "minecraft:goat_horn", - "damage": 4 - }, - { - "id": "minecraft:goat_horn", - "damage": 5 - }, - { - "id": "minecraft:goat_horn", - "damage": 6 - }, - { - "id": "minecraft:goat_horn", - "damage": 7 - }, - { - "id": "minecraft:empty_map" - }, - { - "id": "minecraft:empty_map", - "damage": 2 - }, - { - "id": "minecraft:saddle" - }, - { - "id": "minecraft:leather_horse_armor" - }, - { - "id": "minecraft:iron_horse_armor" - }, - { - "id": "minecraft:golden_horse_armor" - }, - { - "id": "minecraft:diamond_horse_armor" - }, - { - "id": "minecraft:trident" - }, - { - "id": "minecraft:turtle_helmet" - }, - { - "id": "minecraft:elytra" - }, - { - "id": "minecraft:totem_of_undying" - }, - { - "id": "minecraft:glass_bottle" - }, - { - "id": "minecraft:experience_bottle" - }, - { - "id": "minecraft:potion" - }, - { - "id": "minecraft:potion", - "damage": 1 - }, - { - "id": "minecraft:potion", - "damage": 2 - }, - { - "id": "minecraft:potion", - "damage": 3 - }, - { - "id": "minecraft:potion", - "damage": 4 - }, - { - "id": "minecraft:potion", - "damage": 5 - }, - { - "id": "minecraft:potion", - "damage": 6 - }, - { - "id": "minecraft:potion", - "damage": 7 - }, - { - "id": "minecraft:potion", - "damage": 8 - }, - { - "id": "minecraft:potion", - "damage": 9 - }, - { - "id": "minecraft:potion", - "damage": 10 - }, - { - "id": "minecraft:potion", - "damage": 11 - }, - { - "id": "minecraft:potion", - "damage": 12 - }, - { - "id": "minecraft:potion", - "damage": 13 - }, - { - "id": "minecraft:potion", - "damage": 14 - }, - { - "id": "minecraft:potion", - "damage": 15 - }, - { - "id": "minecraft:potion", - "damage": 16 - }, - { - "id": "minecraft:potion", - "damage": 17 - }, - { - "id": "minecraft:potion", - "damage": 18 - }, - { - "id": "minecraft:potion", - "damage": 19 - }, - { - "id": "minecraft:potion", - "damage": 20 - }, - { - "id": "minecraft:potion", - "damage": 21 - }, - { - "id": "minecraft:potion", - "damage": 22 - }, - { - "id": "minecraft:potion", - "damage": 23 - }, - { - "id": "minecraft:potion", - "damage": 24 - }, - { - "id": "minecraft:potion", - "damage": 25 - }, - { - "id": "minecraft:potion", - "damage": 26 - }, - { - "id": "minecraft:potion", - "damage": 27 - }, - { - "id": "minecraft:potion", - "damage": 28 - }, - { - "id": "minecraft:potion", - "damage": 29 - }, - { - "id": "minecraft:potion", - "damage": 30 - }, - { - "id": "minecraft:potion", - "damage": 31 - }, - { - "id": "minecraft:potion", - "damage": 32 - }, - { - "id": "minecraft:potion", - "damage": 33 - }, - { - "id": "minecraft:potion", - "damage": 34 - }, - { - "id": "minecraft:potion", - "damage": 35 - }, - { - "id": "minecraft:potion", - "damage": 36 - }, - { - "id": "minecraft:potion", - "damage": 37 - }, - { - "id": "minecraft:potion", - "damage": 38 - }, - { - "id": "minecraft:potion", - "damage": 39 - }, - { - "id": "minecraft:potion", - "damage": 40 - }, - { - "id": "minecraft:potion", - "damage": 41 - }, - { - "id": "minecraft:potion", - "damage": 42 - }, - { - "id": "minecraft:splash_potion" - }, - { - "id": "minecraft:splash_potion", - "damage": 1 - }, - { - "id": "minecraft:splash_potion", - "damage": 2 - }, - { - "id": "minecraft:splash_potion", - "damage": 3 - }, - { - "id": "minecraft:splash_potion", - "damage": 4 - }, - { - "id": "minecraft:splash_potion", - "damage": 5 - }, - { - "id": "minecraft:splash_potion", - "damage": 6 - }, - { - "id": "minecraft:splash_potion", - "damage": 7 - }, - { - "id": "minecraft:splash_potion", - "damage": 8 - }, - { - "id": "minecraft:splash_potion", - "damage": 9 - }, - { - "id": "minecraft:splash_potion", - "damage": 10 - }, - { - "id": "minecraft:splash_potion", - "damage": 11 - }, - { - "id": "minecraft:splash_potion", - "damage": 12 - }, - { - "id": "minecraft:splash_potion", - "damage": 13 - }, - { - "id": "minecraft:splash_potion", - "damage": 14 - }, - { - "id": "minecraft:splash_potion", - "damage": 15 - }, - { - "id": "minecraft:splash_potion", - "damage": 16 - }, - { - "id": "minecraft:splash_potion", - "damage": 17 - }, - { - "id": "minecraft:splash_potion", - "damage": 18 - }, - { - "id": "minecraft:splash_potion", - "damage": 19 - }, - { - "id": "minecraft:splash_potion", - "damage": 20 - }, - { - "id": "minecraft:splash_potion", - "damage": 21 - }, - { - "id": "minecraft:splash_potion", - "damage": 22 - }, - { - "id": "minecraft:splash_potion", - "damage": 23 - }, - { - "id": "minecraft:splash_potion", - "damage": 24 - }, - { - "id": "minecraft:splash_potion", - "damage": 25 - }, - { - "id": "minecraft:splash_potion", - "damage": 26 - }, - { - "id": "minecraft:splash_potion", - "damage": 27 - }, - { - "id": "minecraft:splash_potion", - "damage": 28 - }, - { - "id": "minecraft:splash_potion", - "damage": 29 - }, - { - "id": "minecraft:splash_potion", - "damage": 30 - }, - { - "id": "minecraft:splash_potion", - "damage": 31 - }, - { - "id": "minecraft:splash_potion", - "damage": 32 - }, - { - "id": "minecraft:splash_potion", - "damage": 33 - }, - { - "id": "minecraft:splash_potion", - "damage": 34 - }, - { - "id": "minecraft:splash_potion", - "damage": 35 - }, - { - "id": "minecraft:splash_potion", - "damage": 36 - }, - { - "id": "minecraft:splash_potion", - "damage": 37 - }, - { - "id": "minecraft:splash_potion", - "damage": 38 - }, - { - "id": "minecraft:splash_potion", - "damage": 39 - }, - { - "id": "minecraft:splash_potion", - "damage": 40 - }, - { - "id": "minecraft:splash_potion", - "damage": 41 - }, - { - "id": "minecraft:splash_potion", - "damage": 42 - }, - { - "id": "minecraft:lingering_potion" - }, - { - "id": "minecraft:lingering_potion", - "damage": 1 - }, - { - "id": "minecraft:lingering_potion", - "damage": 2 - }, - { - "id": "minecraft:lingering_potion", - "damage": 3 - }, - { - "id": "minecraft:lingering_potion", - "damage": 4 - }, - { - "id": "minecraft:lingering_potion", - "damage": 5 - }, - { - "id": "minecraft:lingering_potion", - "damage": 6 - }, - { - "id": "minecraft:lingering_potion", - "damage": 7 - }, - { - "id": "minecraft:lingering_potion", - "damage": 8 - }, - { - "id": "minecraft:lingering_potion", - "damage": 9 - }, - { - "id": "minecraft:lingering_potion", - "damage": 10 - }, - { - "id": "minecraft:lingering_potion", - "damage": 11 - }, - { - "id": "minecraft:lingering_potion", - "damage": 12 - }, - { - "id": "minecraft:lingering_potion", - "damage": 13 - }, - { - "id": "minecraft:lingering_potion", - "damage": 14 - }, - { - "id": "minecraft:lingering_potion", - "damage": 15 - }, - { - "id": "minecraft:lingering_potion", - "damage": 16 - }, - { - "id": "minecraft:lingering_potion", - "damage": 17 - }, - { - "id": "minecraft:lingering_potion", - "damage": 18 - }, - { - "id": "minecraft:lingering_potion", - "damage": 19 - }, - { - "id": "minecraft:lingering_potion", - "damage": 20 - }, - { - "id": "minecraft:lingering_potion", - "damage": 21 - }, - { - "id": "minecraft:lingering_potion", - "damage": 22 - }, - { - "id": "minecraft:lingering_potion", - "damage": 23 - }, - { - "id": "minecraft:lingering_potion", - "damage": 24 - }, - { - "id": "minecraft:lingering_potion", - "damage": 25 - }, - { - "id": "minecraft:lingering_potion", - "damage": 26 - }, - { - "id": "minecraft:lingering_potion", - "damage": 27 - }, - { - "id": "minecraft:lingering_potion", - "damage": 28 - }, - { - "id": "minecraft:lingering_potion", - "damage": 29 - }, - { - "id": "minecraft:lingering_potion", - "damage": 30 - }, - { - "id": "minecraft:lingering_potion", - "damage": 31 - }, - { - "id": "minecraft:lingering_potion", - "damage": 32 - }, - { - "id": "minecraft:lingering_potion", - "damage": 33 - }, - { - "id": "minecraft:lingering_potion", - "damage": 34 - }, - { - "id": "minecraft:lingering_potion", - "damage": 35 - }, - { - "id": "minecraft:lingering_potion", - "damage": 36 - }, - { - "id": "minecraft:lingering_potion", - "damage": 37 - }, - { - "id": "minecraft:lingering_potion", - "damage": 38 - }, - { - "id": "minecraft:lingering_potion", - "damage": 39 - }, - { - "id": "minecraft:lingering_potion", - "damage": 40 - }, - { - "id": "minecraft:lingering_potion", - "damage": 41 - }, - { - "id": "minecraft:lingering_potion", - "damage": 42 - }, - { - "id": "minecraft:spyglass" - }, - { - "id": "minecraft:brush" - }, - { - "id": "minecraft:stick" - }, - { - "id": "minecraft:bed" - }, - { - "id": "minecraft:bed", - "damage": 8 - }, - { - "id": "minecraft:bed", - "damage": 7 - }, - { - "id": "minecraft:bed", - "damage": 15 - }, - { - "id": "minecraft:bed", - "damage": 12 - }, - { - "id": "minecraft:bed", - "damage": 14 - }, - { - "id": "minecraft:bed", - "damage": 1 - }, - { - "id": "minecraft:bed", - "damage": 4 - }, - { - "id": "minecraft:bed", - "damage": 5 - }, - { - "id": "minecraft:bed", - "damage": 13 - }, - { - "id": "minecraft:bed", - "damage": 9 - }, - { - "id": "minecraft:bed", - "damage": 3 - }, - { - "id": "minecraft:bed", - "damage": 11 - }, - { - "id": "minecraft:bed", - "damage": 10 - }, - { - "id": "minecraft:bed", - "damage": 2 - }, - { - "id": "minecraft:bed", - "damage": 6 - }, - { - "id": "minecraft:torch", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OnRvcmNoBAkAbmFtZV9oYXNoagn7rmDBzisDCgBuZXR3b3JrX2lk+BwwuQoGAHN0YXRlcwgWAHRvcmNoX2ZhY2luZ19kaXJlY3Rpb24HAHVua25vd24AAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:soul_torch", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnNvdWxfdG9yY2gECQBuYW1lX2hhc2huixOT04BRdQMKAG5ldHdvcmtfaWShbFILCgYAc3RhdGVzCBYAdG9yY2hfZmFjaW5nX2RpcmVjdGlvbgcAdW5rbm93bgADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:sea_pickle", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnNlYV9waWNrbGUECQBuYW1lX2hhc2iONEfZJB+glgMKAG5ldHdvcmtfaWSINWQyCgYAc3RhdGVzAw0AY2x1c3Rlcl9jb3VudAAAAAABCABkZWFkX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:lantern", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OmxhbnRlcm4ECQBuYW1lX2hhc2hMw44VI2HWygMKAG5ldHdvcmtfaWRkjQvzCgYAc3RhdGVzAQcAaGFuZ2luZwAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:soul_lantern", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnNvdWxfbGFudGVybgQJAG5hbWVfaGFzaGjIpjxk9z+RAwoAbmV0d29ya19pZGfoP8cKBgBzdGF0ZXMBBwBoYW5naW5nAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:candle", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OmNhbmRsZQQJAG5hbWVfaGFzaHPd+MsNdWTfAwoAbmV0d29ya19pZHsBMA0KBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:white_candle", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OndoaXRlX2NhbmRsZQQJAG5hbWVfaGFzaN1EG5Q1mHiEAwoAbmV0d29ya19pZKN1mmgKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:orange_candle", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0Om9yYW5nZV9jYW5kbGUECQBuYW1lX2hhc2jySEVWHgUIHQMKAG5ldHdvcmtfaWSfVz82CgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:magenta_candle", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0Om1hZ2VudGFfY2FuZGxlBAkAbmFtZV9oYXNoG0u6YIOoBSEDCgBuZXR3b3JrX2lk9xGNkQoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:light_blue_candle", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY2FuZGxlBAkAbmFtZV9oYXNocXGeK0zgrG0DCgBuZXR3b3JrX2lk2m1y8goGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:yellow_candle", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnllbGxvd19jYW5kbGUECQBuYW1lX2hhc2i00dtusU3CqQMKAG5ldHdvcmtfaWR9LTmpCgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:lime_candle", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmxpbWVfY2FuZGxlBAkAbmFtZV9oYXNokcmrw5xvz7ADCgBuZXR3b3JrX2lkIAUu6QoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:pink_candle", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OnBpbmtfY2FuZGxlBAkAbmFtZV9oYXNoQJdEY4sZ0dwDCgBuZXR3b3JrX2lk23Rn5AoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:gray_candle", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmdyYXlfY2FuZGxlBAkAbmFtZV9oYXNoS5poSo9wBDEDCgBuZXR3b3JrX2lk3trRCAoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:light_gray_candle", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY2FuZGxlBAkAbmFtZV9oYXNo9ruTZLBNMasDCgBuZXR3b3JrX2lkb6DOegoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:cyan_candle", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmN5YW5fY2FuZGxlBAkAbmFtZV9oYXNoc/M8PNVcjOwDCgBuZXR3b3JrX2lkZoIQOQoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:purple_candle", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnB1cnBsZV9jYW5kbGUECQBuYW1lX2hhc2jaI3xUW0/myQMKAG5ldHdvcmtfaWSnLI2BCgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:blue_candle", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmJsdWVfY2FuZGxlBAkAbmFtZV9oYXNoAASSPW6TgQADCgBuZXR3b3JrX2lkrxrjQAoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:brown_candle", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmJyb3duX2NhbmRsZQQJAG5hbWVfaGFzaDia0l6s1+WYAwoAbmV0d29ya19pZKSkBXYKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:green_candle", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmdyZWVuX2NhbmRsZQQJAG5hbWVfaGFzaLeFPO1l+fIoAwoAbmV0d29ya19pZBkznDsKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:red_candle", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9jYW5kbGUECQBuYW1lX2hhc2jjAQpGf59ZdwMKAG5ldHdvcmtfaWRbb88GCgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:black_candle", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmJsYWNrX2NhbmRsZQQJAG5hbWVfaGFzaB+wRDpOqREKAwoAbmV0d29ya19pZNnOnuEKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:crafting_table", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNyYWZ0aW5nX3RhYmxlBAkAbmFtZV9oYXNoe76VAmjvbpYDCgBuZXR3b3JrX2lkwCxwaAoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:cartography_table", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmNhcnRvZ3JhcGh5X3RhYmxlBAkAbmFtZV9oYXNomaWiiD/znP8DCgBuZXR3b3JrX2lkI6FzMwoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:fletching_table", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmZsZXRjaGluZ190YWJsZQQJAG5hbWVfaGFzaPFibh8unKyUAwoAbmV0d29ya19pZJ2mW0oKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:smithing_table", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OnNtaXRoaW5nX3RhYmxlBAkAbmFtZV9oYXNo4tFES2xOXEYDCgBuZXR3b3JrX2lkXWMBzQoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:beehive", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OmJlZWhpdmUECQBuYW1lX2hhc2hCcqn12UbNpwMKAG5ldHdvcmtfaWR/idcaCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAMLAGhvbmV5X2xldmVsAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:suspicious_sand", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OnN1c3BpY2lvdXNfc2FuZAQJAG5hbWVfaGFzaL67QsuvLP00AwoAbmV0d29ya19pZKnkaIAKBgBzdGF0ZXMDEABicnVzaGVkX3Byb2dyZXNzAAAAAAEHAGhhbmdpbmcBAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:suspicious_gravel", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN1c3BpY2lvdXNfZ3JhdmVsBAkAbmFtZV9oYXNoJSVbGNk7C3oDCgBuZXR3b3JrX2lkvIEJAAoGAHN0YXRlcwMQAGJydXNoZWRfcHJvZ3Jlc3MAAAAAAQcAaGFuZ2luZwEAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:campfire" - }, - { - "id": "minecraft:soul_campfire" - }, - { - "id": "minecraft:furnace", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OmZ1cm5hY2UECQBuYW1lX2hhc2ioOQrludYY8wMKAG5ldHdvcmtfaWRZxnDOCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:blast_furnace", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmJsYXN0X2Z1cm5hY2UECQBuYW1lX2hhc2ivDbnjkpGm5QMKAG5ldHdvcmtfaWTcEbV/CgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:smoker", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OnNtb2tlcgQJAG5hbWVfaGFzaJd1rDMkRWomAwoAbmV0d29ya19pZGWswMwKBgBzdGF0ZXMIHABtaW5lY3JhZnQ6Y2FyZGluYWxfZGlyZWN0aW9uBQBzb3V0aAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:respawn_anchor", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OnJlc3Bhd25fYW5jaG9yBAkAbmFtZV9oYXNoZOdcjW05qigDCgBuZXR3b3JrX2lkmhMcaQoGAHN0YXRlcwMVAHJlc3Bhd25fYW5jaG9yX2NoYXJnZQAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:brewing_stand" - }, - { - "id": "minecraft:anvil", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OmFudmlsBAkAbmFtZV9oYXNoNqB3fgcUCbwDCgBuZXR3b3JrX2lk8Z3VowoGAHN0YXRlcwgGAGRhbWFnZQkAdW5kYW1hZ2VkCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:anvil", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OmFudmlsBAkAbmFtZV9oYXNoNqB3fgcUCbwDCgBuZXR3b3JrX2lkpiv8BAoGAHN0YXRlcwgGAGRhbWFnZRAAc2xpZ2h0bHlfZGFtYWdlZAgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:anvil", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OmFudmlsBAkAbmFtZV9oYXNoNqB3fgcUCbwDCgBuZXR3b3JrX2lkFu+pdwoGAHN0YXRlcwgGAGRhbWFnZQwAdmVyeV9kYW1hZ2VkCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:grindstone", - "block_state_b64": "CgAACAQAbmFtZRQAbWluZWNyYWZ0OmdyaW5kc3RvbmUECQBuYW1lX2hhc2id56zc0nk99wMKAG5ldHdvcmtfaWS4Es07CgYAc3RhdGVzCAoAYXR0YWNobWVudAgAc3RhbmRpbmcDCQBkaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:enchanting_table", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmVuY2hhbnRpbmdfdGFibGUECQBuYW1lX2hhc2jgIx24VLvMvwMKAG5ldHdvcmtfaWRliFFJCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:bookshelf", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmJvb2tzaGVsZgQJAG5hbWVfaGFzaDU04DrgJCS9AwoAbmV0d29ya19pZBcWwIwKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:chiseled_bookshelf", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OmNoaXNlbGVkX2Jvb2tzaGVsZgQJAG5hbWVfaGFzaNXDBnsIsywYAwoAbmV0d29ya19pZIprt5IKBgBzdGF0ZXMDDABib29rc19zdG9yZWQAAAAAAwkAZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:lectern", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OmxlY3Rlcm4ECQBuYW1lX2hhc2j5Z4Mmi/1QxAMKAG5ldHdvcmtfaWR4JfDHCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgBCwBwb3dlcmVkX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:cauldron" - }, - { - "id": "minecraft:composter", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmNvbXBvc3RlcgQJAG5hbWVfaGFzaPAADHptzeWJAwoAbmV0d29ya19pZHIL6i4KBgBzdGF0ZXMDFABjb21wb3N0ZXJfZmlsbF9sZXZlbAAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:chest", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OmNoZXN0BAkAbmFtZV9oYXNog9ozMxlcA88DCgBuZXR3b3JrX2lkDkOFvAoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAG5vcnRoAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:trapped_chest", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnRyYXBwZWRfY2hlc3QECQBuYW1lX2hhc2g2qpF9stsEjgMKAG5ldHdvcmtfaWTjJWYxCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAbm9ydGgAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:ender_chest", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmVuZGVyX2NoZXN0BAkAbmFtZV9oYXNohEZzOFdg0WUDCgBuZXR3b3JrX2lkx4jiSQoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAG5vcnRoAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:barrel", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OmJhcnJlbAQJAG5hbWVfaGFzaHDkRPGymiRqAwoAbmV0d29ya19pZPnxzgsKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:undyed_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OnVuZHllZF9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaOC9mypm/MlBAwoAbmV0d29ya19pZJ8rxp0KBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:white_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OndoaXRlX3NodWxrZXJfYm94BAkAbmFtZV9oYXNosK79m1rPUBwDCgBuZXR3b3JrX2lkjrET6goGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:light_gray_shulker_box", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2iBe5zq7PxHmgMKAG5ldHdvcmtfaWSCVJv0CgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:gray_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmdyYXlfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2ga2s8ctjHUhgMKAG5ldHdvcmtfaWS3WMsWCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:black_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmJsYWNrX3NodWxrZXJfYm94BAkAbmFtZV9oYXNoPm03OZphrp8DCgBuZXR3b3JrX2lkXHztNAoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:brown_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmJyb3duX3NodWxrZXJfYm94BAkAbmFtZV9oYXNoT3DD6qAL9cADCgBuZXR3b3JrX2lkaXxpYQoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:red_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OnJlZF9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaMIlKSCzqSZoAwoAbmV0d29ya19pZNrf+icKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:orange_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0Om9yYW5nZV9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaG2MAXU67wGrAwoAbmV0d29ya19pZGoO05gKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:yellow_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OnllbGxvd19zaHVsa2VyX2JveAQJAG5hbWVfaGFzaIsLwQHYjcIEAwoAbmV0d29ya19pZBCBSiYKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:lime_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmxpbWVfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2hUwBkg+faUGAMKAG5ldHdvcmtfaWRJeKqqCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:green_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmdyZWVuX3NodWxrZXJfYm94BAkAbmFtZV9oYXNoZgUeT3LupLUDCgBuZXR3b3JrX2lkzJiohQoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:cyan_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmN5YW5fc2h1bGtlcl9ib3gECQBuYW1lX2hhc2gSfbjteXg5yAMKAG5ldHdvcmtfaWTHeliECgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:light_blue_shulker_box", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2h0VFCX0qsRxQMKAG5ldHdvcmtfaWQXD8U0CgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:blue_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmJsdWVfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2hn9gS0XIe6rAMKAG5ldHdvcmtfaWTO4PJaCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:purple_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRwAbWluZWNyYWZ0OnB1cnBsZV9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaEV/lkNPxRDdAwoAbmV0d29ya19pZFK25GAKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:magenta_shulker_box", - "block_state_b64": "CgAACAQAbmFtZR0AbWluZWNyYWZ0Om1hZ2VudGFfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2iqWM7IJHxcFgMKAG5ldHdvcmtfaWTyyudTCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:pink_shulker_box", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OnBpbmtfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2in1tkJ1GNcZgMKAG5ldHdvcmtfaWQOEGXjCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:armor_stand" - }, - { - "id": "minecraft:noteblock", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0Om5vdGVibG9jawQJAG5hbWVfaGFzaHPA8dBBH0UaAwoAbmV0d29ya19pZH1U5QkKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:jukebox", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0Omp1a2Vib3gECQBuYW1lX2hhc2ieAIPExf/ZfgMKAG5ldHdvcmtfaWSmR7JfCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:music_disc_13" - }, - { - "id": "minecraft:music_disc_cat" - }, - { - "id": "minecraft:music_disc_blocks" - }, - { - "id": "minecraft:music_disc_chirp" - }, - { - "id": "minecraft:music_disc_far" - }, - { - "id": "minecraft:music_disc_mall" - }, - { - "id": "minecraft:music_disc_mellohi" - }, - { - "id": "minecraft:music_disc_stal" - }, - { - "id": "minecraft:music_disc_strad" - }, - { - "id": "minecraft:music_disc_ward" - }, - { - "id": "minecraft:music_disc_11" - }, - { - "id": "minecraft:music_disc_wait" - }, - { - "id": "minecraft:music_disc_otherside" - }, - { - "id": "minecraft:music_disc_5" - }, - { - "id": "minecraft:music_disc_pigstep" - }, - { - "id": "minecraft:music_disc_relic" - }, - { - "id": "minecraft:disc_fragment_5" - }, - { - "id": "minecraft:glowstone_dust" - }, - { - "id": "minecraft:glowstone", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0Omdsb3dzdG9uZQQJAG5hbWVfaGFzaFYqXNkefIlPAwoAbmV0d29ya19pZGT7WYYKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:redstone_lamp", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZHN0b25lX2xhbXAECQBuYW1lX2hhc2hJ9V80caPvEgMKAG5ldHdvcmtfaWRvNPwnCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:sea_lantern", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OnNlYV9sYW50ZXJuBAkAbmFtZV9oYXNoLPsv1TX9M+QDCgBuZXR3b3JrX2lk1PPVyAoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:oak_sign" - }, - { - "id": "minecraft:spruce_sign" - }, - { - "id": "minecraft:birch_sign" - }, - { - "id": "minecraft:jungle_sign" - }, - { - "id": "minecraft:acacia_sign" - }, - { - "id": "minecraft:dark_oak_sign" - }, - { - "id": "minecraft:mangrove_sign" - }, - { - "id": "minecraft:cherry_sign" - }, - { - "id": "minecraft:bamboo_sign" - }, - { - "id": "minecraft:crimson_sign" - }, - { - "id": "minecraft:warped_sign" - }, - { - "id": "minecraft:oak_hanging_sign" - }, - { - "id": "minecraft:spruce_hanging_sign" - }, - { - "id": "minecraft:birch_hanging_sign" - }, - { - "id": "minecraft:jungle_hanging_sign" - }, - { - "id": "minecraft:acacia_hanging_sign" - }, - { - "id": "minecraft:dark_oak_hanging_sign" - }, - { - "id": "minecraft:mangrove_hanging_sign" - }, - { - "id": "minecraft:cherry_hanging_sign" - }, - { - "id": "minecraft:bamboo_hanging_sign" - }, - { - "id": "minecraft:crimson_hanging_sign" - }, - { - "id": "minecraft:warped_hanging_sign" - }, - { - "id": "minecraft:painting" - }, - { - "id": "minecraft:frame" - }, - { - "id": "minecraft:glow_frame" - }, - { - "id": "minecraft:honey_bottle" - }, - { - "id": "minecraft:flower_pot" - }, - { - "id": "minecraft:bowl" - }, - { - "id": "minecraft:bucket" - }, - { - "id": "minecraft:milk_bucket" - }, - { - "id": "minecraft:water_bucket" - }, - { - "id": "minecraft:lava_bucket" - }, - { - "id": "minecraft:cod_bucket" - }, - { - "id": "minecraft:salmon_bucket" - }, - { - "id": "minecraft:tropical_fish_bucket" - }, - { - "id": "minecraft:pufferfish_bucket" - }, - { - "id": "minecraft:powder_snow_bucket" - }, - { - "id": "minecraft:axolotl_bucket" - }, - { - "id": "minecraft:tadpole_bucket" - }, - { - "id": "minecraft:skull", - "damage": 3 - }, - { - "id": "minecraft:skull", - "damage": 2 - }, - { - "id": "minecraft:skull", - "damage": 4 - }, - { - "id": "minecraft:skull", - "damage": 5 - }, - { - "id": "minecraft:skull" - }, - { - "id": "minecraft:skull", - "damage": 1 - }, - { - "id": "minecraft:skull", - "damage": 6 - }, - { - "id": "minecraft:beacon", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OmJlYWNvbgQJAG5hbWVfaGFzaACwhhfSkdkHAwoAbmV0d29ya19pZF8jfiEKBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:bell", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0OmJlbGwECQBuYW1lX2hhc2iPqsgDXRcsxAMKAG5ldHdvcmtfaWT7zhOoCgYAc3RhdGVzCAoAYXR0YWNobWVudAgAc3RhbmRpbmcDCQBkaXJlY3Rpb24AAAAAAQoAdG9nZ2xlX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:conduit", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OmNvbmR1aXQECQBuYW1lX2hhc2jqxKAxq2EaWQMKAG5ldHdvcmtfaWTWcBVnCgYAc3RhdGVzAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:stonecutter_block", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lY3V0dGVyX2Jsb2NrBAkAbmFtZV9oYXNoQAXTbAM3MeYDCgBuZXR3b3JrX2lkWS4RjAoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAG5vcnRoAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:end_portal_frame", - "block_state_b64": "CgAACAQAbmFtZRoAbWluZWNyYWZ0OmVuZF9wb3J0YWxfZnJhbWUECQBuYW1lX2hhc2gqofyUIjGOpQMKAG5ldHdvcmtfaWRbGHf8CgYAc3RhdGVzARIAZW5kX3BvcnRhbF9leWVfYml0AAgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:coal" - }, - { - "id": "minecraft:charcoal" - }, - { - "id": "minecraft:diamond" - }, - { - "id": "minecraft:iron_nugget" - }, - { - "id": "minecraft:raw_iron" - }, - { - "id": "minecraft:raw_gold" - }, - { - "id": "minecraft:raw_copper" - }, - { - "id": "minecraft:copper_ingot" - }, - { - "id": "minecraft:iron_ingot" - }, - { - "id": "minecraft:netherite_scrap" - }, - { - "id": "minecraft:netherite_ingot" - }, - { - "id": "minecraft:gold_nugget" - }, - { - "id": "minecraft:gold_ingot" - }, - { - "id": "minecraft:emerald" - }, - { - "id": "minecraft:quartz" - }, - { - "id": "minecraft:clay_ball" - }, - { - "id": "minecraft:brick" - }, - { - "id": "minecraft:netherbrick" - }, - { - "id": "minecraft:prismarine_shard" - }, - { - "id": "minecraft:amethyst_shard" - }, - { - "id": "minecraft:prismarine_crystals" - }, - { - "id": "minecraft:nautilus_shell" - }, - { - "id": "minecraft:heart_of_the_sea" - }, - { - "id": "minecraft:scute" - }, - { - "id": "minecraft:phantom_membrane" - }, - { - "id": "minecraft:string" - }, - { - "id": "minecraft:feather" - }, - { - "id": "minecraft:flint" - }, - { - "id": "minecraft:gunpowder" - }, - { - "id": "minecraft:leather" - }, - { - "id": "minecraft:rabbit_hide" - }, - { - "id": "minecraft:rabbit_foot" - }, - { - "id": "minecraft:fire_charge" - }, - { - "id": "minecraft:blaze_rod" - }, - { - "id": "minecraft:blaze_powder" - }, - { - "id": "minecraft:magma_cream" - }, - { - "id": "minecraft:fermented_spider_eye" - }, - { - "id": "minecraft:echo_shard" - }, - { - "id": "minecraft:dragon_breath" - }, - { - "id": "minecraft:shulker_shell" - }, - { - "id": "minecraft:ghast_tear" - }, - { - "id": "minecraft:slime_ball" - }, - { - "id": "minecraft:ender_pearl" - }, - { - "id": "minecraft:ender_eye" - }, - { - "id": "minecraft:nether_star" - }, - { - "id": "minecraft:end_rod", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OmVuZF9yb2QECQBuYW1lX2hhc2jx/q5cEA0hmQMKAG5ldHdvcmtfaWQ2eM8kCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:lightning_rod", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmxpZ2h0bmluZ19yb2QECQBuYW1lX2hhc2ioXQF1xvfHNQMKAG5ldHdvcmtfaWRLuHyACgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:end_crystal" - }, - { - "id": "minecraft:paper" - }, - { - "id": "minecraft:book" - }, - { - "id": "minecraft:writable_book" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQFAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQFAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQFAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQGAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQGAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQGAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQHAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQHAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQHAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQIAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAUAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAUAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAUAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQMAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQMAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQNAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQNAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQOAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQOAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQOAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAUAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQQAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQRAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQRAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQRAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQSAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQSAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQSAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAUAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQUAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQUAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQVAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQWAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQXAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQXAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQXAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQYAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQYAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQYAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQZAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQZAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQaAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQbAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQcAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAUAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQeAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQeAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQeAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQfAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQfAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQfAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQgAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQhAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQjAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQjAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQjAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQkAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQkAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQkAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQlAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQlAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQlAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:oak_boat" - }, - { - "id": "minecraft:spruce_boat" - }, - { - "id": "minecraft:birch_boat" - }, - { - "id": "minecraft:jungle_boat" - }, - { - "id": "minecraft:acacia_boat" - }, - { - "id": "minecraft:dark_oak_boat" - }, - { - "id": "minecraft:mangrove_boat" - }, - { - "id": "minecraft:cherry_boat" - }, - { - "id": "minecraft:bamboo_raft" - }, - { - "id": "minecraft:oak_chest_boat" - }, - { - "id": "minecraft:spruce_chest_boat" - }, - { - "id": "minecraft:birch_chest_boat" - }, - { - "id": "minecraft:jungle_chest_boat" - }, - { - "id": "minecraft:acacia_chest_boat" - }, - { - "id": "minecraft:dark_oak_chest_boat" - }, - { - "id": "minecraft:mangrove_chest_boat" - }, - { - "id": "minecraft:cherry_chest_boat" - }, - { - "id": "minecraft:bamboo_chest_raft" - }, - { - "id": "minecraft:rail", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0OnJhaWwECQBuYW1lX2hhc2hUzmhUXYJDUQMKAG5ldHdvcmtfaWR+Sp6YCgYAc3RhdGVzAw4AcmFpbF9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:golden_rail", - "block_state_b64": "CgAACAQAbmFtZRUAbWluZWNyYWZ0OmdvbGRlbl9yYWlsBAkAbmFtZV9oYXNoOoV5MaKipoUDCgBuZXR3b3JrX2lkfAcxLwoGAHN0YXRlcwENAHJhaWxfZGF0YV9iaXQAAw4AcmFpbF9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:detector_rail", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmRldGVjdG9yX3JhaWwECQBuYW1lX2hhc2gVUk31qOysUQMKAG5ldHdvcmtfaWRVW/aICgYAc3RhdGVzAQ0AcmFpbF9kYXRhX2JpdAADDgByYWlsX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:activator_rail", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmFjdGl2YXRvcl9yYWlsBAkAbmFtZV9oYXNosIL91qriCRkDCgBuZXR3b3JrX2lkZfckmwoGAHN0YXRlcwENAHJhaWxfZGF0YV9iaXQAAw4AcmFpbF9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:minecart" - }, - { - "id": "minecraft:chest_minecart" - }, - { - "id": "minecraft:hopper_minecart" - }, - { - "id": "minecraft:tnt_minecart" - }, - { - "id": "minecraft:redstone" - }, - { - "id": "minecraft:redstone_block", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OnJlZHN0b25lX2Jsb2NrBAkAbmFtZV9oYXNoRhULL0r8o0sDCgBuZXR3b3JrX2lklayOHgoGAHN0YXRlcwADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:redstone_torch", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OnJlZHN0b25lX3RvcmNoBAkAbmFtZV9oYXNoizFRjpYMIDgDCgBuZXR3b3JrX2lkuHz7yAoGAHN0YXRlcwgWAHRvcmNoX2ZhY2luZ19kaXJlY3Rpb24HAHVua25vd24AAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:lever", - "block_state_b64": "CgAACAQAbmFtZQ8AbWluZWNyYWZ0OmxldmVyBAkAbmFtZV9oYXNoGMJeLJsUMLYDCgBuZXR3b3JrX2lkEF/GuAoGAHN0YXRlcwgPAGxldmVyX2RpcmVjdGlvbg4AZG93bl9lYXN0X3dlc3QBCABvcGVuX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:wooden_button", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0Ondvb2Rlbl9idXR0b24ECQBuYW1lX2hhc2hR7PgSTQt0sQMKAG5ldHdvcmtfaWSU07kYCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:spruce_button", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9idXR0b24ECQBuYW1lX2hhc2jBW9Z8aYE7YQMKAG5ldHdvcmtfaWTkUIGuCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:birch_button", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX2J1dHRvbgQJAG5hbWVfaGFzaJXYgGuSHbTwAwoAbmV0d29ya19pZGWp3yoKBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:jungle_button", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9idXR0b24ECQBuYW1lX2hhc2iCgNANcJs+BQMKAG5ldHdvcmtfaWT9fImWCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:acacia_button", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9idXR0b24ECQBuYW1lX2hhc2gVvmcT7LTO0wMKAG5ldHdvcmtfaWRQnxIJCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:dark_oak_button", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX2J1dHRvbgQJAG5hbWVfaGFzaIV10ZGGrCIEAwoAbmV0d29ya19pZN5vAmIKBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:mangrove_button", - "block_state_b64": "CgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX2J1dHRvbgQJAG5hbWVfaGFzaNzeYYKLgOzJAwoAbmV0d29ya19pZAFEGQ0KBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:cherry_button", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9idXR0b24ECQBuYW1lX2hhc2j2/IHjeAbUcwMKAG5ldHdvcmtfaWRJ1irQCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:bamboo_button", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19idXR0b24ECQBuYW1lX2hhc2j7AddMi+6nsgMKAG5ldHdvcmtfaWSa9w4/CgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:stone_button", - "block_state_b64": "CgAACAQAbmFtZRYAbWluZWNyYWZ0OnN0b25lX2J1dHRvbgQJAG5hbWVfaGFzaM4ejMctmvohAwoAbmV0d29ya19pZMw+aC0KBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:crimson_button", - "block_state_b64": "CgAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fYnV0dG9uBAkAbmFtZV9oYXNofnjYHaYIeWgDCgBuZXR3b3JrX2lk+n1vyQoGAHN0YXRlcwESAGJ1dHRvbl9wcmVzc2VkX2JpdAADEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:warped_button", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9idXR0b24ECQBuYW1lX2hhc2jwkV2EU6Cn1QMKAG5ldHdvcmtfaWTnHnk1CgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:polished_blackstone_button", - "block_state_b64": "CgAACAQAbmFtZSQAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnV0dG9uBAkAbmFtZV9oYXNojmxzQKS0S/EDCgBuZXR3b3JrX2lkDtQ95woGAHN0YXRlcwESAGJ1dHRvbl9wcmVzc2VkX2JpdAADEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:tripwire_hook", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnRyaXB3aXJlX2hvb2sECQBuYW1lX2hhc2gQdp+oGZLNnAMKAG5ldHdvcmtfaWSy+1KJCgYAc3RhdGVzAQwAYXR0YWNoZWRfYml0AAMJAGRpcmVjdGlvbgAAAAABCwBwb3dlcmVkX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:wooden_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0Ondvb2Rlbl9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaGkGs5kCuA74AwoAbmV0d29ya19pZDRzPNwKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:spruce_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OnNwcnVjZV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaNmwuq549fJKAwoAbmV0d29ya19pZLQMCw0KBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:birch_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OmJpcmNoX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNorQkT9kDdlTwDCgBuZXR3b3JrX2lkH0G97AoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:jungle_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0Omp1bmdsZV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaJ7DcteCkb8/AwoAbmV0d29ya19pZLdPBSAKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:acacia_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OmFjYWNpYV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaC2frZtfoYqCAwoAbmV0d29ya19pZIDdI18KBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:dark_oak_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0OmRhcmtfb2FrX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoHUCJsTy52pwDCgBuZXR3b3JrX2lkKpi8rAoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:mangrove_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZSEAbWluZWNyYWZ0Om1hbmdyb3ZlX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoiDsTfJaX100DCgBuZXR3b3JrX2lkuwWDyQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:cherry_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OmNoZXJyeV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaALMqYEZDUQHAwoAbmV0d29ya19pZPNT+r0KBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:bamboo_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OmJhbWJvb19wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaNvxJ7NIAaqlAwoAbmV0d29ya19pZIZ8XnYKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:crimson_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZSAAbWluZWNyYWZ0OmNyaW1zb25fcHJlc3N1cmVfcGxhdGUECQBuYW1lX2hhc2hqBDVDAd31/gMKAG5ldHdvcmtfaWRmV18LCgYAc3RhdGVzAw8AcmVkc3RvbmVfc2lnbmFsAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:warped_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZR8AbWluZWNyYWZ0OndhcnBlZF9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaBxFoQksWtYUAwoAbmV0d29ya19pZJVRoIcKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:stone_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZR4AbWluZWNyYWZ0OnN0b25lX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNounJuTBUTrU8DCgBuZXR3b3JrX2lkjDydwQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:light_weighted_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZScAbWluZWNyYWZ0OmxpZ2h0X3dlaWdodGVkX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoOyOJkNxLtkEDCgBuZXR3b3JrX2lkrr2AjgoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:heavy_weighted_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZScAbWluZWNyYWZ0OmhlYXZ5X3dlaWdodGVkX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoltgDmDvTajUDCgBuZXR3b3JrX2lkFxVKuQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:polished_blackstone_pressure_plate", - "block_state_b64": "CgAACAQAbmFtZSwAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfcHJlc3N1cmVfcGxhdGUECQBuYW1lX2hhc2h65Ci6/CeGqwMKAG5ldHdvcmtfaWTaSW5xCgYAc3RhdGVzAw8AcmVkc3RvbmVfc2lnbmFsAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:observer", - "block_state_b64": "CgAACAQAbmFtZRIAbWluZWNyYWZ0Om9ic2VydmVyBAkAbmFtZV9oYXNoYhlh1lpmHTgDCgBuZXR3b3JrX2lkQEh55goGAHN0YXRlcwgaAG1pbmVjcmFmdDpmYWNpbmdfZGlyZWN0aW9uBABkb3duAQsAcG93ZXJlZF9iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:daylight_detector", - "block_state_b64": "CgAACAQAbmFtZRsAbWluZWNyYWZ0OmRheWxpZ2h0X2RldGVjdG9yBAkAbmFtZV9oYXNoV0F0s7B7PVgDCgBuZXR3b3JrX2lkri5afQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:repeater" - }, - { - "id": "minecraft:comparator" - }, - { - "id": "minecraft:hopper" - }, - { - "id": "minecraft:dropper", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OmRyb3BwZXIECQBuYW1lX2hhc2joXP7XqU0l3QMKAG5ldHdvcmtfaWQfQN6zCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgMAAAABDQB0cmlnZ2VyZWRfYml0AAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:dispenser", - "block_state_b64": "CgAACAQAbmFtZRMAbWluZWNyYWZ0OmRpc3BlbnNlcgQJAG5hbWVfaGFzaP1RR+zAbYP2AwoAbmV0d29ya19pZGAayD0KBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAwAAAAENAHRyaWdnZXJlZF9iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:crafter", - "block_state_b64": "CgAACAQAbmFtZREAbWluZWNyYWZ0OmNyYWZ0ZXIECQBuYW1lX2hhc2iLCT/rJmRN8QMKAG5ldHdvcmtfaWTPTbvrCgYAc3RhdGVzAQgAY3JhZnRpbmcACAsAb3JpZW50YXRpb24JAGRvd25fZWFzdAENAHRyaWdnZXJlZF9iaXQAAAMHAHZlcnNpb24BMhQBAA==" - }, - { - "id": "minecraft:piston", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OnBpc3RvbgQJAG5hbWVfaGFzaDs3AFh1fL0uAwoAbmV0d29ya19pZLD/5XQKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAQAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:sticky_piston", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OnN0aWNreV9waXN0b24ECQBuYW1lX2hhc2hPFJFJSiJ0ZQMKAG5ldHdvcmtfaWT/MzCJCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgEAAAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:tnt", - "block_state_b64": "CgAACAQAbmFtZQ0AbWluZWNyYWZ0OnRudAQJAG5hbWVfaGFzaEYOHwCvJH29AwoAbmV0d29ya19pZCGfjU4KBgBzdGF0ZXMBFABhbGxvd191bmRlcndhdGVyX2JpdAABCwBleHBsb2RlX2JpdAAAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:name_tag" - }, - { - "id": "minecraft:loom", - "block_state_b64": "CgAACAQAbmFtZQ4AbWluZWNyYWZ0Omxvb20ECQBuYW1lX2hhc2i7DKjAXNq8TAMKAG5ldHdvcmtfaWR/49HXCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:banner" - }, - { - "id": "minecraft:banner", - "damage": 8 - }, - { - "id": "minecraft:banner", - "damage": 7 - }, - { - "id": "minecraft:banner", - "damage": 15 - }, - { - "id": "minecraft:banner", - "damage": 12 - }, - { - "id": "minecraft:banner", - "damage": 14 - }, - { - "id": "minecraft:banner", - "damage": 1 - }, - { - "id": "minecraft:banner", - "damage": 4 - }, - { - "id": "minecraft:banner", - "damage": 5 - }, - { - "id": "minecraft:banner", - "damage": 13 - }, - { - "id": "minecraft:banner", - "damage": 9 - }, - { - "id": "minecraft:banner", - "damage": 3 - }, - { - "id": "minecraft:banner", - "damage": 11 - }, - { - "id": "minecraft:banner", - "damage": 10 - }, - { - "id": "minecraft:banner", - "damage": 2 - }, - { - "id": "minecraft:banner", - "damage": 6 - }, - { - "id": "minecraft:banner", - "damage": 15, - "nbt_b64": "CgAAAwQAVHlwZQEAAAAA" - }, - { - "id": "minecraft:creeper_banner_pattern" - }, - { - "id": "minecraft:skull_banner_pattern" - }, - { - "id": "minecraft:flower_banner_pattern" - }, - { - "id": "minecraft:mojang_banner_pattern" - }, - { - "id": "minecraft:field_masoned_banner_pattern" - }, - { - "id": "minecraft:bordure_indented_banner_pattern" - }, - { - "id": "minecraft:piglin_banner_pattern" - }, - { - "id": "minecraft:globe_banner_pattern" - }, - { - "id": "minecraft:angler_pottery_sherd" - }, - { - "id": "minecraft:archer_pottery_sherd" - }, - { - "id": "minecraft:arms_up_pottery_sherd" - }, - { - "id": "minecraft:blade_pottery_sherd" - }, - { - "id": "minecraft:brewer_pottery_sherd" - }, - { - "id": "minecraft:burn_pottery_sherd" - }, - { - "id": "minecraft:danger_pottery_sherd" - }, - { - "id": "minecraft:explorer_pottery_sherd" - }, - { - "id": "minecraft:friend_pottery_sherd" - }, - { - "id": "minecraft:heart_pottery_sherd" - }, - { - "id": "minecraft:heartbreak_pottery_sherd" - }, - { - "id": "minecraft:howl_pottery_sherd" - }, - { - "id": "minecraft:miner_pottery_sherd" - }, - { - "id": "minecraft:mourner_pottery_sherd" - }, - { - "id": "minecraft:plenty_pottery_sherd" - }, - { - "id": "minecraft:prize_pottery_sherd" - }, - { - "id": "minecraft:sheaf_pottery_sherd" - }, - { - "id": "minecraft:shelter_pottery_sherd" - }, - { - "id": "minecraft:skull_pottery_sherd" - }, - { - "id": "minecraft:snort_pottery_sherd" - }, - { - "id": "minecraft:netherite_upgrade_smithing_template" - }, - { - "id": "minecraft:sentry_armor_trim_smithing_template" - }, - { - "id": "minecraft:vex_armor_trim_smithing_template" - }, - { - "id": "minecraft:wild_armor_trim_smithing_template" - }, - { - "id": "minecraft:coast_armor_trim_smithing_template" - }, - { - "id": "minecraft:dune_armor_trim_smithing_template" - }, - { - "id": "minecraft:wayfinder_armor_trim_smithing_template" - }, - { - "id": "minecraft:shaper_armor_trim_smithing_template" - }, - { - "id": "minecraft:raiser_armor_trim_smithing_template" - }, - { - "id": "minecraft:host_armor_trim_smithing_template" - }, - { - "id": "minecraft:ward_armor_trim_smithing_template" - }, - { - "id": "minecraft:silence_armor_trim_smithing_template" - }, - { - "id": "minecraft:tide_armor_trim_smithing_template" - }, - { - "id": "minecraft:snout_armor_trim_smithing_template" - }, - { - "id": "minecraft:rib_armor_trim_smithing_template" - }, - { - "id": "minecraft:eye_armor_trim_smithing_template" - }, - { - "id": "minecraft:spire_armor_trim_smithing_template" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwAAAAAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAABwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAIBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAHBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAPBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAMBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAOBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAABBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAEBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAFBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAANBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAJBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAADBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAALBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAKBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAACBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAGBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_star", - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yIR0d/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 8, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yUk9H/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 7, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yl52d/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 15, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9y8PDw/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 12, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9y2rM6/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 14, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yHYD5/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 1, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yJi6w/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 4, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yqkQ8/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 5, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yuDKJ/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 13, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yvU7H/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 9, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yqovz/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 3, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yMlSD/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 11, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yPdj+/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 10, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yH8eA/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 2, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yFnxe/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 6, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9ynJwW/wA=" - }, - { - "id": "minecraft:chain" - }, - { - "id": "minecraft:target", - "block_state_b64": "CgAACAQAbmFtZRAAbWluZWNyYWZ0OnRhcmdldAQJAG5hbWVfaGFzaJc66SVbYlaxAwoAbmV0d29ya19pZPBozs0KBgBzdGF0ZXMAAwcAdmVyc2lvbgEyFAEA" - }, - { - "id": "minecraft:decorated_pot", - "block_state_b64": "CgAACAQAbmFtZRcAbWluZWNyYWZ0OmRlY29yYXRlZF9wb3QECQBuYW1lX2hhc2jjQgckn8VTvwMKAG5ldHdvcmtfaWRwvkUUCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATIUAQA=" - }, - { - "id": "minecraft:lodestone_compass" - }, - { - "id": "minecraft:wither_spawn_egg" - }, - { - "id": "minecraft:ender_dragon_spawn_egg" - } - ] -} \ No newline at end of file diff --git a/core/src/main/resources/bedrock/creative_items.1_20_60.json b/core/src/main/resources/bedrock/creative_items.1_20_60.json deleted file mode 100644 index d4063030e..000000000 --- a/core/src/main/resources/bedrock/creative_items.1_20_60.json +++ /dev/null @@ -1,5787 +0,0 @@ -{ - "items": [ - { - "id": "minecraft:oak_planks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQFAAAACAQAbmFtZRQAbWluZWNyYWZ0Om9ha19wbGFua3MECQBuYW1lX2hhc2ilMDLR92rQ4wMKAG5ldHdvcmtfaWS2MwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:spruce_planks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTiAwAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9wbGFua3MECQBuYW1lX2hhc2iumBkmFGFE8gMKAG5ldHdvcmtfaWQZNQAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:birch_planks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTjAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX3BsYW5rcwQJAG5hbWVfaGFzaLrrAKJqV2WFAwoAbmV0d29ya19pZJQjAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:jungle_planks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTkAwAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9wbGFua3MECQBuYW1lX2hhc2iBM3k4T3FAugMKAG5ldHdvcmtfaWQwLgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:acacia_planks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTlAwAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9wbGFua3MECQBuYW1lX2hhc2g60edJxO5/aAMKAG5ldHdvcmtfaWSDHAAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:dark_oak_planks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTmAwAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX3BsYW5rcwQJAG5hbWVfaGFzaAr64wkQ9cA7AwoAbmV0d29ya19pZDMXAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:mangrove_planks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTlAgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX3BsYW5rcwQJAG5hbWVfaGFzaPvLtcEA0F8xAwoAbmV0d29ya19pZGgJAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:cherry_planks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAwAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9wbGFua3MECQBuYW1lX2hhc2hNIvVh/lVW7gMKAG5ldHdvcmtfaWSVNAAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:bamboo_planks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWT9AgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19wbGFua3MECQBuYW1lX2hhc2gYnjNz7SCCjgMKAG5ldHdvcmtfaWTbJAAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:bamboo_mosaic", - "block_state_b64": "CgAAAwgAYmxvY2tfaWT8AgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19tb3NhaWMECQBuYW1lX2hhc2izSEgiMKOp/AMKAG5ldHdvcmtfaWT0NgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:crimson_planks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTxAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fcGxhbmtzBAkAbmFtZV9oYXNoJc5IKqNXJnwDCgBuZXR3b3JrX2lkmyEAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:warped_planks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTyAQAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9wbGFua3MECQBuYW1lX2hhc2g3yGXEWhe6LgMKAG5ldHdvcmtfaWRLCQAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRFCgAACgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCwBjb2JibGVzdG9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRGCgAACgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlEQBtb3NzeV9jb2JibGVzdG9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRHCgAACgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlBwBncmFuaXRlCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRICgAACgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlBwBkaW9yaXRlCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRJCgAACgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCABhbmRlc2l0ZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRKCgAACgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCQBzYW5kc3RvbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRRCgAACgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlDQByZWRfc2FuZHN0b25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRMCgAACgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCwBzdG9uZV9icmljawgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRNCgAACgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlEQBtb3NzeV9zdG9uZV9icmljawgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRLCgAACgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlBQBicmljawgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWROCgAACgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlDABuZXRoZXJfYnJpY2sIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRSCgAACgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlEAByZWRfbmV0aGVyX2JyaWNrCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRPCgAACgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCQBlbmRfYnJpY2sIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRQCgAACgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCgBwcmlzbWFyaW5lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:blackstone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQUAgAACAQAbmFtZRkAbWluZWNyYWZ0OmJsYWNrc3RvbmVfd2FsbAQJAG5hbWVfaGFzaMP8XppUSU1RAwoAbmV0d29ya19pZDsaAAAKBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:polished_blackstone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQoAgAACAQAbmFtZSIAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfd2FsbAQJAG5hbWVfaGFzaP6SwV08YwzAAwoAbmV0d29ya19pZJsuAAAKBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:polished_blackstone_brick_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQVAgAACAQAbmFtZSgAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tfd2FsbAQJAG5hbWVfaGFzaBBIDZbHxiEzAwoAbmV0d29ya19pZHYJAAAKBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:cobbled_deepslate_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR9AgAACAQAbmFtZSAAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlX3dhbGwECQBuYW1lX2hhc2iECY5oKxeT+gMKAG5ldHdvcmtfaWQwNgAACgYAc3RhdGVzCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:deepslate_tile_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAgAACAQAbmFtZR0AbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlX3dhbGwECQBuYW1lX2hhc2jz7N+PeuEXgQMKAG5ldHdvcmtfaWSNIgAACgYAc3RhdGVzCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:polished_deepslate_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSBAgAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZV93YWxsBAkAbmFtZV9oYXNoHxjTdj9pevMDCgBuZXR3b3JrX2lkKDUAAAoGAHN0YXRlcwgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:deepslate_brick_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSJAgAACAQAbmFtZR4AbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja193YWxsBAkAbmFtZV9oYXNoEs3EQrjroyEDCgBuZXR3b3JrX2lkoQQAAAoGAHN0YXRlcwgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:mud_brick_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTgAgAACAQAbmFtZRgAbWluZWNyYWZ0Om11ZF9icmlja193YWxsBAkAbmFtZV9oYXNov9b98ATpUSwDCgBuZXR3b3JrX2lkfQgAAAoGAHN0YXRlcwgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:oak_fence", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRVAAAACAQAbmFtZRMAbWluZWNyYWZ0Om9ha19mZW5jZQQJAG5hbWVfaGFzaGEmid7AaCWRAwoAbmV0d29ya19pZF0lAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:spruce_fence", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRCAwAACAQAbmFtZRYAbWluZWNyYWZ0OnNwcnVjZV9mZW5jZQQJAG5hbWVfaGFzaPQCm+aX1ZQeAwoAbmV0d29ya19pZHcEAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:birch_fence", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ/AwAACAQAbmFtZRUAbWluZWNyYWZ0OmJpcmNoX2ZlbmNlBAkAbmFtZV9oYXNo6CJ2ATpANfgDCgBuZXR3b3JrX2lkIzYAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:jungle_fence", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRBAwAACAQAbmFtZRYAbWluZWNyYWZ0Omp1bmdsZV9mZW5jZQQJAG5hbWVfaGFzaOX4cD9uAmsdAwoAbmV0d29ya19pZHAEAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:acacia_fence", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ+AwAACAQAbmFtZRYAbWluZWNyYWZ0OmFjYWNpYV9mZW5jZQQJAG5hbWVfaGFzaGjn+RlKVDH6AwoAbmV0d29ya19pZC42AAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:dark_oak_fence", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRAAwAACAQAbmFtZRgAbWluZWNyYWZ0OmRhcmtfb2FrX2ZlbmNlBAkAbmFtZV9oYXNoGPj0gCgM0c0DCgBuZXR3b3JrX2lkNTAAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:mangrove_fence", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTqAgAACAQAbmFtZRgAbWluZWNyYWZ0Om1hbmdyb3ZlX2ZlbmNlBAkAbmFtZV9oYXNowwAd7tPu9bsDCgBuZXR3b3JrX2lkQi4AAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:cherry_fence", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQTAwAACAQAbmFtZRYAbWluZWNyYWZ0OmNoZXJyeV9mZW5jZQQJAG5hbWVfaGFzaFmtUfHfTxcxAwoAbmV0d29ya19pZGcJAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:bamboo_fence", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQCAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJhbWJvb19mZW5jZQQJAG5hbWVfaGFzaCKRbxfXsfkiAwoAbmV0d29ya19pZF0FAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:nether_brick_fence", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRxAAAACAQAbmFtZRwAbWluZWNyYWZ0Om5ldGhlcl9icmlja19mZW5jZQQJAG5hbWVfaGFzaA6030ngawxcAwoAbmV0d29ya19pZLUbAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:crimson_fence", - "block_state_b64": "CgAAAwgAYmxvY2tfaWT/AQAACAQAbmFtZRcAbWluZWNyYWZ0OmNyaW1zb25fZmVuY2UECQBuYW1lX2hhc2jhUhKv1HGj9AMKAG5ldHdvcmtfaWTcNQAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:warped_fence", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQAAgAACAQAbmFtZRYAbWluZWNyYWZ0OndhcnBlZF9mZW5jZQQJAG5hbWVfaGFzaJfb3/YuKmOWAwoAbmV0d29ya19pZG0nAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:fence_gate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRrAAAACAQAbmFtZRQAbWluZWNyYWZ0OmZlbmNlX2dhdGUECQBuYW1lX2hhc2hTxpjEDmRzAwMKAG5ldHdvcmtfaWRVAAAACgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:spruce_fence_gate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS3AAAACAQAbmFtZRsAbWluZWNyYWZ0OnNwcnVjZV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoanTVB84HRbkDCgBuZXR3b3JrX2lkEC4AAAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:birch_fence_gate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS4AAAACAQAbmFtZRoAbWluZWNyYWZ0OmJpcmNoX2ZlbmNlX2dhdGUECQBuYW1lX2hhc2jmfPklI8azSwMKAG5ldHdvcmtfaWQkGAAACgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:jungle_fence_gate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS5AAAACAQAbmFtZRsAbWluZWNyYWZ0Omp1bmdsZV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNobYVQkfBomIcDCgBuZXR3b3JrX2lkuCMAAAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:acacia_fence_gate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS7AAAACAQAbmFtZRsAbWluZWNyYWZ0OmFjYWNpYV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoZnrLUx/XSekDCgBuZXR3b3JrX2lk5jMAAAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:dark_oak_fence_gate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS6AAAACAQAbmFtZR0AbWluZWNyYWZ0OmRhcmtfb2FrX2ZlbmNlX2dhdGUECQBuYW1lX2hhc2j2PTvdJJHcVQMKAG5ldHdvcmtfaWQxGwAACgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:mangrove_fence_gate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTrAgAACAQAbmFtZR0AbWluZWNyYWZ0Om1hbmdyb3ZlX2ZlbmNlX2dhdGUECQBuYW1lX2hhc2i/kOhBKiI/dAMKAG5ldHdvcmtfaWReHQAACgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:cherry_fence_gate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQUAwAACAQAbmFtZRsAbWluZWNyYWZ0OmNoZXJyeV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoKWLgCk0z+PsDCgBuZXR3b3JrX2lk3TYAAAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:bamboo_fence_gate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAwAACAQAbmFtZRsAbWluZWNyYWZ0OmJhbWJvb19mZW5jZV9nYXRlBAkAbmFtZV9oYXNopH1JrUgwdIADCgBuZXR3b3JrX2lkdCIAAAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:crimson_fence_gate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQBAgAACAQAbmFtZRwAbWluZWNyYWZ0OmNyaW1zb25fZmVuY2VfZ2F0ZQQJAG5hbWVfaGFzaHE3Gfd0Z2d2AwoAbmV0d29ya19pZCIfAAAKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQsAaW5fd2FsbF9iaXQAAQgAb3Blbl9iaXQAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:warped_fence_gate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQCAgAACAQAbmFtZRsAbWluZWNyYWZ0OndhcnBlZF9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoy0oIBjDIG4kDCgBuZXR3b3JrX2lk3iMAAAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:normal_stone_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAQAACAQAbmFtZR0AbWluZWNyYWZ0Om5vcm1hbF9zdG9uZV9zdGFpcnMECQBuYW1lX2hhc2hAEktZZOkGIwMKAG5ldHdvcmtfaWReBQAACgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:stone_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRDAAAACAQAbmFtZRYAbWluZWNyYWZ0OnN0b25lX3N0YWlycwQJAG5hbWVfaGFzaNRjqVC5GRVDAwoAbmV0d29ya19pZNQXAAAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:mossy_cobblestone_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSyAQAACAQAbmFtZSIAbWluZWNyYWZ0Om1vc3N5X2NvYmJsZXN0b25lX3N0YWlycwQJAG5hbWVfaGFzaMVSTq5z9n1RAwoAbmV0d29ya19pZN0aAAAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:oak_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ1AAAACAQAbmFtZRQAbWluZWNyYWZ0Om9ha19zdGFpcnMECQBuYW1lX2hhc2jk/HFzdXy0FQMKAG5ldHdvcmtfaWTSAgAACgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:spruce_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSGAAAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9zdGFpcnMECQBuYW1lX2hhc2iznygw7uBPBQMKAG5ldHdvcmtfaWSMAAAACgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:birch_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSHAAAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX3N0YWlycwQJAG5hbWVfaGFzaPfhbL619a3GAwoAbmV0d29ya19pZL8vAAAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:jungle_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSIAAAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9zdGFpcnMECQBuYW1lX2hhc2jodJsHUbOVxQMKAG5ldHdvcmtfaWSYLwAACgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:acacia_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSjAAAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9zdGFpcnMECQBuYW1lX2hhc2h3x1NmD43IqQMKAG5ldHdvcmtfaWRULAAACgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:dark_oak_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSkAAAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX3N0YWlycwQJAG5hbWVfaGFzaMfwkbYPbNmAAwoAbmV0d29ya19pZIUiAAAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:mangrove_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTnAgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX3N0YWlycwQJAG5hbWVfaGFzaNpUDY+uGMpyAwoAbmV0d29ya19pZDQdAAAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:cherry_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQcAwAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9zdGFpcnMECQBuYW1lX2hhc2jMtr0v9JY4zwMKAG5ldHdvcmtfaWRkMAAACgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:bamboo_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWT/AgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19zdGFpcnMECQBuYW1lX2hhc2jFOzWL8PalKwMKAG5ldHdvcmtfaWRvCAAACgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:bamboo_mosaic_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQKAwAACAQAbmFtZR4AbWluZWNyYWZ0OmJhbWJvb19tb3NhaWNfc3RhaXJzBAkAbmFtZV9oYXNoNLPiveSHPaoDCgBuZXR3b3JrX2lkXCwAAAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:stone_brick_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRtAAAACAQAbmFtZRwAbWluZWNyYWZ0OnN0b25lX2JyaWNrX3N0YWlycwQJAG5hbWVfaGFzaN6tQViRo5cwAwoAbmV0d29ya19pZFcJAAAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:mossy_stone_brick_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSuAQAACAQAbmFtZSIAbWluZWNyYWZ0Om1vc3N5X3N0b25lX2JyaWNrX3N0YWlycwQJAG5hbWVfaGFzaIB/Zv5YBPuYAwoAbmV0d29ya19pZCwpAAAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:sandstone_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSAAAAACAQAbmFtZRoAbWluZWNyYWZ0OnNhbmRzdG9uZV9zdGFpcnMECQBuYW1lX2hhc2hOyA0BoYUOPQMKAG5ldHdvcmtfaWRUFwAACgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:smooth_sandstone_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSwAQAACAQAbmFtZSEAbWluZWNyYWZ0OnNtb290aF9zYW5kc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNoB+CuCd8Ruz8DCgBuZXR3b3JrX2lkghcAAAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:red_sandstone_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS0AAAACAQAbmFtZR4AbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNoPs0LpHPL24YDCgBuZXR3b3JrX2lkqSMAAAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:smooth_red_sandstone_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAQAACAQAbmFtZSUAbWluZWNyYWZ0OnNtb290aF9yZWRfc2FuZHN0b25lX3N0YWlycwQJAG5hbWVfaGFzaBvjtQv5pf+MAwoAbmV0d29ya19pZJIkAAAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:granite_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAQAACAQAbmFtZRgAbWluZWNyYWZ0OmdyYW5pdGVfc3RhaXJzBAkAbmFtZV9oYXNoGzpvtoqKQjgDCgBuZXR3b3JrX2lkjxUAAAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:polished_granite_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSrAQAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2dyYW5pdGVfc3RhaXJzBAkAbmFtZV9oYXNo3PvbSfEQklIDCgBuZXR3b3JrX2lkGRsAAAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:diorite_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSpAQAACAQAbmFtZRgAbWluZWNyYWZ0OmRpb3JpdGVfc3RhaXJzBAkAbmFtZV9oYXNoi73T8VQuZmcDCgBuZXR3b3JrX2lkShwAAAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:polished_diorite_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSsAQAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2Rpb3JpdGVfc3RhaXJzBAkAbmFtZV9oYXNoFKRJd5Wk5L0DCgBuZXR3b3JrX2lkii4AAAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:andesite_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSqAQAACAQAbmFtZRkAbWluZWNyYWZ0OmFuZGVzaXRlX3N0YWlycwQJAG5hbWVfaGFzaO5w2FKBw76EAwoAbmV0d29ya19pZIwjAAAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:polished_andesite_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWStAQAACAQAbmFtZSIAbWluZWNyYWZ0OnBvbGlzaGVkX2FuZGVzaXRlX3N0YWlycwQJAG5hbWVfaGFzaNcZZ/zmLInIAwoAbmV0d29ya19pZNsvAAAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:brick_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRsAAAACAQAbmFtZRYAbWluZWNyYWZ0OmJyaWNrX3N0YWlycwQJAG5hbWVfaGFzaMyt+cRDk5O2AwoAbmV0d29ya19pZMgtAAAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:nether_brick_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRyAAAACAQAbmFtZR0AbWluZWNyYWZ0Om5ldGhlcl9icmlja19zdGFpcnMECQBuYW1lX2hhc2jRqIoOXgifBAMKAG5ldHdvcmtfaWRzAAAACgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:red_nether_brick_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS3AQAACAQAbmFtZSEAbWluZWNyYWZ0OnJlZF9uZXRoZXJfYnJpY2tfc3RhaXJzBAkAbmFtZV9oYXNogQvosSbcj7kDCgBuZXR3b3JrX2lkIi4AAAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:end_brick_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSxAQAACAQAbmFtZRoAbWluZWNyYWZ0OmVuZF9icmlja19zdGFpcnMECQBuYW1lX2hhc2hmlAk+QhsUsQMKAG5ldHdvcmtfaWQKLQAACgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:quartz_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWScAAAACAQAbmFtZRcAbWluZWNyYWZ0OnF1YXJ0el9zdGFpcnMECQBuYW1lX2hhc2hmvpvOqGi6egMKAG5ldHdvcmtfaWTEHwAACgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:smooth_quartz_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS4AQAACAQAbmFtZR4AbWluZWNyYWZ0OnNtb290aF9xdWFydHpfc3RhaXJzBAkAbmFtZV9oYXNoNZZ9rX0qZOsDCgBuZXR3b3JrX2lkWDQAAAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:purpur_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTLAAAACAQAbmFtZRcAbWluZWNyYWZ0OnB1cnB1cl9zdGFpcnMECQBuYW1lX2hhc2ifwDxeezXD7gMKAG5ldHdvcmtfaWSZNAAACgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:prismarine_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQBAQAACAQAbmFtZRsAbWluZWNyYWZ0OnByaXNtYXJpbmVfc3RhaXJzBAkAbmFtZV9oYXNooTHSZ+IrYtcDCgBuZXR3b3JrX2lkkTIAAAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:dark_prismarine_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQCAQAACAQAbmFtZSAAbWluZWNyYWZ0OmRhcmtfcHJpc21hcmluZV9zdGFpcnMECQBuYW1lX2hhc2hIciLmam4o4AMKAG5ldHdvcmtfaWRBMwAACgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:prismarine_bricks_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAQAACAQAbmFtZSIAbWluZWNyYWZ0OnByaXNtYXJpbmVfYnJpY2tzX3N0YWlycwQJAG5hbWVfaGFzaNIjq1oBlZMMAwoAbmV0d29ya19pZHECAAAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:crimson_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWT9AQAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fc3RhaXJzBAkAbmFtZV9oYXNoZJqIzCBpCq4DCgBuZXR3b3JrX2lknywAAAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:warped_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWT+AQAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9zdGFpcnMECQBuYW1lX2hhc2hOkY27jLD4RQMKAG5ldHdvcmtfaWThFwAACgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:blackstone_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQTAgAACAQAbmFtZRsAbWluZWNyYWZ0OmJsYWNrc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNokdoUb76p9McDCgBuZXR3b3JrX2lk0C8AAAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:polished_blackstone_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQjAgAACAQAbmFtZSQAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNolCFtFIE8MmADCgBuZXR3b3JrX2lk3hsAAAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:polished_blackstone_brick_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQSAgAACAQAbmFtZSoAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tfc3RhaXJzBAkAbmFtZV9oYXNonks6UlfpOmkDCgBuZXR3b3JrX2lkphwAAAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:cut_copper_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAgAACAQAbmFtZRsAbWluZWNyYWZ0OmN1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNoHfoAXYq5G3MDCgBuZXR3b3JrX2lkPR0AAAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:exposed_cut_copper_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAgAACAQAbmFtZSMAbWluZWNyYWZ0OmV4cG9zZWRfY3V0X2NvcHBlcl9zdGFpcnMECQBuYW1lX2hhc2howneQGtZ9cgMKAG5ldHdvcmtfaWQsHQAACgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:weathered_cut_copper_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAgAACAQAbmFtZSUAbWluZWNyYWZ0OndlYXRoZXJlZF9jdXRfY29wcGVyX3N0YWlycwQJAG5hbWVfaGFzaP+R5loXxrVgAwoAbmV0d29ya19pZOYbAAAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:oxidized_cut_copper_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRkAgAACAQAbmFtZSQAbWluZWNyYWZ0Om94aWRpemVkX2N1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNo6Jeoq5rsPxsDCgBuZXR3b3JrX2lkSgQAAAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:waxed_cut_copper_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRlAgAACAQAbmFtZSEAbWluZWNyYWZ0OndheGVkX2N1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNoh07CQj0/SR8DCgBuZXR3b3JrX2lkegQAAAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:waxed_exposed_cut_copper_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRmAgAACAQAbmFtZSkAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY3V0X2NvcHBlcl9zdGFpcnMECQBuYW1lX2hhc2guVct1ilmxTwMKAG5ldHdvcmtfaWQeGgAACgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:waxed_weathered_cut_copper_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRnAgAACAQAbmFtZSsAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jdXRfY29wcGVyX3N0YWlycwQJAG5hbWVfaGFzaPXC8Sz/phCpAwoAbmV0d29ya19pZEMsAAAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:waxed_oxidized_cut_copper_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS/AgAACAQAbmFtZSoAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2N1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNoaqGdkuhxVZUDCgBuZXR3b3JrX2lkQCcAAAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:cobbled_deepslate_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR8AgAACAQAbmFtZSIAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlX3N0YWlycwQJAG5hbWVfaGFzaPIfa+TpyJcIAwoAbmV0d29ya19pZDUCAAAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:deepslate_tile_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAgAACAQAbmFtZR8AbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlX3N0YWlycwQJAG5hbWVfaGFzaGFRFzB72mN2AwoAbmV0d29ya19pZBofAAAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:polished_deepslate_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSAAgAACAQAbmFtZSMAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZV9zdGFpcnMECQBuYW1lX2hhc2iNCYxVik9sGAMKAG5ldHdvcmtfaWQNBAAACgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:deepslate_brick_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSIAgAACAQAbmFtZSAAbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja19zdGFpcnMECQBuYW1lX2hhc2hIasOahEf83wMKAG5ldHdvcmtfaWQ5MwAACgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:mud_brick_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTfAgAACAQAbmFtZRoAbWluZWNyYWZ0Om11ZF9icmlja19zdGFpcnMECQBuYW1lX2hhc2gt3qxK1NWajAMKAG5ldHdvcmtfaWR6JAAACgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:wooden_door" - }, - { - "id": "minecraft:spruce_door" - }, - { - "id": "minecraft:birch_door" - }, - { - "id": "minecraft:jungle_door" - }, - { - "id": "minecraft:acacia_door" - }, - { - "id": "minecraft:dark_oak_door" - }, - { - "id": "minecraft:mangrove_door" - }, - { - "id": "minecraft:cherry_door" - }, - { - "id": "minecraft:bamboo_door" - }, - { - "id": "minecraft:iron_door" - }, - { - "id": "minecraft:crimson_door" - }, - { - "id": "minecraft:warped_door" - }, - { - "id": "minecraft:trapdoor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRgAAAACAQAbmFtZRIAbWluZWNyYWZ0OnRyYXBkb29yBAkAbmFtZV9oYXNotYiAJGtN0xADCgBuZXR3b3JrX2lkkQIAAAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:spruce_trapdoor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSUAQAACAQAbmFtZRkAbWluZWNyYWZ0OnNwcnVjZV90cmFwZG9vcgQJAG5hbWVfaGFzaOwlfbgBkUW4AwoAbmV0d29ya19pZO8tAAAKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:birch_trapdoor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAQAACAQAbmFtZRgAbWluZWNyYWZ0OmJpcmNoX3RyYXBkb29yBAkAbmFtZV9oYXNoSLtLweOLJ7wDCgBuZXR3b3JrX2lkVC4AAAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:jungle_trapdoor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSTAQAACAQAbmFtZRkAbWluZWNyYWZ0Omp1bmdsZV90cmFwZG9vcgQJAG5hbWVfaGFzaDP/TnM9wyCIAwoAbmV0d29ya19pZMsjAAAKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:acacia_trapdoor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSQAQAACAQAbmFtZRkAbWluZWNyYWZ0OmFjYWNpYV90cmFwZG9vcgQJAG5hbWVfaGFzaMj8xi3vmEKOAwoAbmV0d29ya19pZLskAAAKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:dark_oak_trapdoor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSSAQAACAQAbmFtZRsAbWluZWNyYWZ0OmRhcmtfb2FrX3RyYXBkb29yBAkAbmFtZV9oYXNomB2GGJQ2aOMDCgBuZXR3b3JrX2lkizMAAAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:mangrove_trapdoor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTvAgAACAQAbmFtZRsAbWluZWNyYWZ0Om1hbmdyb3ZlX3RyYXBkb29yBAkAbmFtZV9oYXNooV3kQsQUUmkDCgBuZXR3b3JrX2lkrhwAAAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:cherry_trapdoor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQeAwAACAQAbmFtZRkAbWluZWNyYWZ0OmNoZXJyeV90cmFwZG9vcgQJAG5hbWVfaGFzaH/PefpfdHgtAwoAbmV0d29ya19pZDEJAAAKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:bamboo_trapdoor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQHAwAACAQAbmFtZRkAbWluZWNyYWZ0OmJhbWJvb190cmFwZG9vcgQJAG5hbWVfaGFzaJrEOpsTwtKCAwoAbmV0d29ya19pZE4jAAAKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:iron_trapdoor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSnAAAACAQAbmFtZRcAbWluZWNyYWZ0Omlyb25fdHJhcGRvb3IECQBuYW1lX2hhc2gwA+IumsEiGQMKAG5ldHdvcmtfaWQqBAAACgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAEPAHVwc2lkZV9kb3duX2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:crimson_trapdoor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWT1AQAACAQAbmFtZRoAbWluZWNyYWZ0OmNyaW1zb25fdHJhcGRvb3IECQBuYW1lX2hhc2jHXufTnwUkYgMKAG5ldHdvcmtfaWQHHAAACgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAEPAHVwc2lkZV9kb3duX2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:warped_trapdoor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWT2AQAACAQAbmFtZRkAbWluZWNyYWZ0OndhcnBlZF90cmFwZG9vcgQJAG5hbWVfaGFzaA20wG/+vkd6AwoAbmV0d29ya19pZJIfAAAKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:iron_bars", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRlAAAACAQAbmFtZRMAbWluZWNyYWZ0Omlyb25fYmFycwQJAG5hbWVfaGFzaPuefWSNAe56AwoAbmV0d29ya19pZOcfAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQUAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmdsYXNzBAkAbmFtZV9oYXNowGJByfWff6gDCgBuZXR3b3JrX2lkQCwAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:white_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTxAAAACAQAbmFtZR0AbWluZWNyYWZ0OndoaXRlX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2iHubqoMbu9fAMKAG5ldHdvcmtfaWSdIQAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:light_gray_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSnAwAACAQAbmFtZSIAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaKKa+LrRsHQhAwoAbmV0d29ya19pZJ4EAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:gray_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSmAwAACAQAbmFtZRwAbWluZWNyYWZ0OmdyYXlfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaIETy7Y/HZREAwoAbmV0d29ya19pZN0XAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:black_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSuAwAACAQAbmFtZR0AbWluZWNyYWZ0OmJsYWNrX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2iV6BCwpfDMmwMKAG5ldHdvcmtfaWRZKQAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:brown_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSrAwAACAQAbmFtZR0AbWluZWNyYWZ0OmJyb3duX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2igsEiq5np8JgMKAG5ldHdvcmtfaWTxBgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:red_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWStAwAACAQAbmFtZRsAbWluZWNyYWZ0OnJlZF9zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNoCa2J12/lQoIDCgBuZXR3b3JrX2lkPSMAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:orange_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSgAwAACAQAbmFtZR4AbWluZWNyYWZ0Om9yYW5nZV9zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNozgjAuvzhxGsDCgBuZXR3b3JrX2lk8RwAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:yellow_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSjAwAACAQAbmFtZR4AbWluZWNyYWZ0OnllbGxvd19zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNo7EbHMd5WVugDCgBuZXR3b3JrX2lk5DMAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:lime_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSkAwAACAQAbmFtZRwAbWluZWNyYWZ0OmxpbWVfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaBtZA1nZtwcFAwoAbmV0d29ya19pZH4AAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:green_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSsAwAACAQAbmFtZR0AbWluZWNyYWZ0OmdyZWVuX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2h91ptDgbehWwMKAG5ldHdvcmtfaWS0GwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:cyan_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAwAACAQAbmFtZRwAbWluZWNyYWZ0OmN5YW5fc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaBkIYQ8nQLqbAwoAbmV0d29ya19pZFgpAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:light_blue_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSiAwAACAQAbmFtZSIAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaLt05n1G0fiSAwoAbmV0d29ya19pZIYlAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:blue_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSqAwAACAQAbmFtZRwAbWluZWNyYWZ0OmJsdWVfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaPhLocSfzduRAwoAbmV0d29ya19pZGIlAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:purple_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSpAwAACAQAbmFtZR4AbWluZWNyYWZ0OnB1cnBsZV9zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNoJk0DhRO0szUDCgBuZXR3b3JrX2lkPQoAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:magenta_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWShAwAACAQAbmFtZR8AbWluZWNyYWZ0Om1hZ2VudGFfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaFEDeFiJj3zSAwoAbmV0d29ya19pZGgyAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:pink_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAwAACAQAbmFtZRwAbWluZWNyYWZ0OnBpbmtfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaDijTX87ywxhAwoAbmV0d29ya19pZPYbAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:tinted_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRNAgAACAQAbmFtZRYAbWluZWNyYWZ0OnRpbnRlZF9nbGFzcwQJAG5hbWVfaGFzaAFZWSamk6KdAwoAbmV0d29ya19pZNkpAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRmAAAACAQAbmFtZRQAbWluZWNyYWZ0OmdsYXNzX3BhbmUECQBuYW1lX2hhc2gRSBHwNMQ4gQMKAG5ldHdvcmtfaWQvIwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:white_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSgAAAACAQAbmFtZSIAbWluZWNyYWZ0OndoaXRlX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaHgxQmgJVtRrAwoAbmV0d29ya19pZPIcAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:light_gray_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSJAwAACAQAbmFtZScAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNon0aQw9lNkSEDCgBuZXR3b3JrX2lkoAQAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:gray_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSIAwAACAQAbmFtZSEAbWluZWNyYWZ0OmdyYXlfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNors74IIw+2MMDCgBuZXR3b3JrX2lkTi8AAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:black_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSQAwAACAQAbmFtZSIAbWluZWNyYWZ0OmJsYWNrX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaOK/5ZRRd+M1AwoAbmV0d29ya19pZEQKAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:brown_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSNAwAACAQAbmFtZSIAbWluZWNyYWZ0OmJyb3duX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaLHeGJyRFTIWAwoAbmV0d29ya19pZN4CAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:red_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSPAwAACAQAbmFtZSAAbWluZWNyYWZ0OnJlZF9zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2gGr4x6JheAywMKAG5ldHdvcmtfaWQtMAAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:orange_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSCAwAACAQAbmFtZSMAbWluZWNyYWZ0Om9yYW5nZV9zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2hbHxPD2gEbEAMKAG5ldHdvcmtfaWSIAgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:yellow_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAwAACAQAbmFtZSMAbWluZWNyYWZ0OnllbGxvd19zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2g9tl4aOCyZBwMKAG5ldHdvcmtfaWQxAgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:lime_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSGAwAACAQAbmFtZSEAbWluZWNyYWZ0OmxpbWVfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNo3CtUyLwoGegDCgBuZXR3b3JrX2lk4jMAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:green_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSOAwAACAQAbmFtZSIAbWluZWNyYWZ0OmdyZWVuX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaJo6YP7IMy9SAwoAbmV0d29ya19pZBgbAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:cyan_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSKAwAACAQAbmFtZSEAbWluZWNyYWZ0OmN5YW5fc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNoti97c6QrbLQDCgBuZXR3b3JrX2lkmy0AAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:light_blue_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAwAACAQAbmFtZScAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNovDg/gQle104DCgBuZXR3b3JrX2lkDBoAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:blue_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSMAwAACAQAbmFtZSEAbWluZWNyYWZ0OmJsdWVfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNoGc57tiexbQMDCgBuZXR3b3JrX2lkVAAAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:purple_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAwAACAQAbmFtZSMAbWluZWNyYWZ0OnB1cnBsZV9zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2hDJHYdd0FdfQMKAG5ldHdvcmtfaWSeIQAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:magenta_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAwAACAQAbmFtZSQAbWluZWNyYWZ0Om1hZ2VudGFfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNo3pcOw5bs5XoDCgBuZXR3b3JrX2lk5h8AAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:pink_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSHAwAACAQAbmFtZSEAbWluZWNyYWZ0OnBpbmtfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNoWRhSACMWgswDCgBuZXR3b3JrX2lkMjAAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:ladder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRBAAAACAQAbmFtZRAAbWluZWNyYWZ0OmxhZGRlcgQJAG5hbWVfaGFzaKBhqheJVOz+AwoAbmV0d29ya19pZPo2AAAKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:scaffolding", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSkAQAACAQAbmFtZRUAbWluZWNyYWZ0OnNjYWZmb2xkaW5nBAkAbmFtZV9oYXNoYrkevrqcljwDCgBuZXR3b3JrX2lkRBcAAAoGAHN0YXRlcwMJAHN0YWJpbGl0eQAAAAABDwBzdGFiaWxpdHlfY2hlY2sAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWSeGwAACgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQwAc21vb3RoX3N0b25lAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:stone_block_slab4", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkqSUAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNAUAc3RvbmUAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWShGwAACgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQsAY29iYmxlc3RvbmUAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkjCUAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhEAbW9zc3lfY29iYmxlc3RvbmUAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:wooden_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSeAAAACAQAbmFtZRUAbWluZWNyYWZ0Ondvb2Rlbl9zbGFiBAkAbmFtZV9oYXNoBVBkRBCCh4MDCgBuZXR3b3JrX2lkZiMAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20ICQB3b29kX3R5cGUDAG9hawADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:wooden_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSeAAAACAQAbmFtZRUAbWluZWNyYWZ0Ondvb2Rlbl9zbGFiBAkAbmFtZV9oYXNoBVBkRBCCh4MDCgBuZXR3b3JrX2lkZyMAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20ICQB3b29kX3R5cGUGAHNwcnVjZQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:wooden_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSeAAAACAQAbmFtZRUAbWluZWNyYWZ0Ondvb2Rlbl9zbGFiBAkAbmFtZV9oYXNoBVBkRBCCh4MDCgBuZXR3b3JrX2lkaCMAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20ICQB3b29kX3R5cGUFAGJpcmNoAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:wooden_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSeAAAACAQAbmFtZRUAbWluZWNyYWZ0Ondvb2Rlbl9zbGFiBAkAbmFtZV9oYXNoBVBkRBCCh4MDCgBuZXR3b3JrX2lkaSMAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20ICQB3b29kX3R5cGUGAGp1bmdsZQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:wooden_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSeAAAACAQAbmFtZRUAbWluZWNyYWZ0Ondvb2Rlbl9zbGFiBAkAbmFtZV9oYXNoBVBkRBCCh4MDCgBuZXR3b3JrX2lkaiMAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20ICQB3b29kX3R5cGUGAGFjYWNpYQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:wooden_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSeAAAACAQAbmFtZRUAbWluZWNyYWZ0Ondvb2Rlbl9zbGFiBAkAbmFtZV9oYXNoBVBkRBCCh4MDCgBuZXR3b3JrX2lkayMAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20ICQB3b29kX3R5cGUIAGRhcmtfb2FrAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:mangrove_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWToAgAACAQAbmFtZRcAbWluZWNyYWZ0Om1hbmdyb3ZlX3NsYWIECQBuYW1lX2hhc2jYCcmhJPeNMwMKAG5ldHdvcmtfaWQYCgAACgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:cherry_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQaAwAACAQAbmFtZRUAbWluZWNyYWZ0OmNoZXJyeV9zbGFiBAkAbmFtZV9oYXNoTt0MmVn/mqoDCgBuZXR3b3JrX2lkZSwAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:bamboo_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQAAwAACAQAbmFtZRUAbWluZWNyYWZ0OmJhbWJvb19zbGFiBAkAbmFtZV9oYXNoo1xuFqINeLYDCgBuZXR3b3JrX2lkxS0AAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:bamboo_mosaic_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQLAwAACAQAbmFtZRwAbWluZWNyYWZ0OmJhbWJvb19tb3NhaWNfc2xhYgQJAG5hbWVfaGFzaNbVRBZ/ChI3AwoAbmV0d29ya19pZCkTAAAKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWSjGwAACgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQsAc3RvbmVfYnJpY2sAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:stone_block_slab4", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkpyUAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNBEAbW9zc3lfc3RvbmVfYnJpY2sAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWSfGwAACgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQkAc2FuZHN0b25lAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:stone_block_slab4", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkqiUAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNA0AY3V0X3NhbmRzdG9uZQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkjSUAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAc21vb3RoX3NhbmRzdG9uZQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkhyUAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMg0AcmVkX3NhbmRzdG9uZQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:stone_block_slab4", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkqyUAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNBEAY3V0X3JlZF9zYW5kc3RvbmUAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkmCUAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxQAc21vb3RoX3JlZF9zYW5kc3RvbmUAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lknSUAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMwcAZ3Jhbml0ZQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkniUAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxAAcG9saXNoZWRfZ3Jhbml0ZQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkmyUAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMwcAZGlvcml0ZQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lknCUAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxAAcG9saXNoZWRfZGlvcml0ZQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkmiUAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMwgAYW5kZXNpdGUAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkmSUAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxEAcG9saXNoZWRfYW5kZXNpdGUAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWSiGwAACgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQUAYnJpY2sAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWSlGwAACgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQwAbmV0aGVyX2JyaWNrAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkjiUAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAcmVkX25ldGhlcl9icmljawADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lklyUAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMw8AZW5kX3N0b25lX2JyaWNrAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWSkGwAACgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQYAcXVhcnR6AAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:stone_block_slab4", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkqCUAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNA0Ac21vb3RoX3F1YXJ0egADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkiCUAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMgYAcHVycHVyAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkiSUAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAcHJpc21hcmluZV9yb3VnaAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkiiUAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMg8AcHJpc21hcmluZV9kYXJrAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkiyUAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAcHJpc21hcmluZV9icmljawADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:crimson_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQHAgAACAQAbmFtZRYAbWluZWNyYWZ0OmNyaW1zb25fc2xhYgQJAG5hbWVfaGFzaKZ+EfP0ZYOZAwoAbmV0d29ya19pZEApAAAKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:warped_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQIAgAACAQAbmFtZRUAbWluZWNyYWZ0OndhcnBlZF9zbGFiBAkAbmFtZV9oYXNo/AT0e/Z9W7UDCgBuZXR3b3JrX2lkoC0AAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:blackstone_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQZAgAACAQAbmFtZRkAbWluZWNyYWZ0OmJsYWNrc3RvbmVfc2xhYgQJAG5hbWVfaGFzaF/DD4ZUlNgtAwoAbmV0d29ya19pZEEJAAAKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:polished_blackstone_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQkAgAACAQAbmFtZSIAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfc2xhYgQJAG5hbWVfaGFzaDYnuUs86EWfAwoAbmV0d29ya19pZIUrAAAKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:polished_blackstone_brick_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQbAgAACAQAbmFtZSgAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tfc2xhYgQJAG5hbWVfaGFzaKySLqvHc4xXAwoAbmV0d29ya19pZEsbAAAKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:cut_copper_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRoAgAACAQAbmFtZRkAbWluZWNyYWZ0OmN1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaDsNpb2qs4iBAwoAbmV0d29ya19pZDEjAAAKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:exposed_cut_copper_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRpAgAACAQAbmFtZSEAbWluZWNyYWZ0OmV4cG9zZWRfY3V0X2NvcHBlcl9zbGFiBAkAbmFtZV9oYXNoahQ5OwIQb7kDCgBuZXR3b3JrX2lkIC4AAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:weathered_cut_copper_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRqAgAACAQAbmFtZSMAbWluZWNyYWZ0OndlYXRoZXJlZF9jdXRfY29wcGVyX3NsYWIECQBuYW1lX2hhc2hBIuGIOVVXogMKAG5ldHdvcmtfaWS0KwAACgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:oxidized_cut_copper_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRrAgAACAQAbmFtZSIAbWluZWNyYWZ0Om94aWRpemVkX2N1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaOptj9ycfpaDAwoAbmV0d29ya19pZHIjAAAKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:waxed_cut_copper_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRsAgAACAQAbmFtZR8AbWluZWNyYWZ0OndheGVkX2N1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaAlx6DZOCTHzAwoAbmV0d29ya19pZCY1AAAKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:waxed_exposed_cut_copper_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRtAgAACAQAbmFtZScAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY3V0X2NvcHBlcl9zbGFiBAkAbmFtZV9oYXNo3KqS5OnhtRIDCgBuZXR3b3JrX2lkpQIAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:waxed_weathered_cut_copper_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRuAgAACAQAbmFtZSkAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jdXRfY29wcGVyX3NsYWIECQBuYW1lX2hhc2gzZ1oX0HCFtwMKAG5ldHdvcmtfaWToLQAACgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:waxed_oxidized_cut_copper_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTAAgAACAQAbmFtZSgAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2N1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaMjjTnLu1KcqAwoAbmV0d29ya19pZL0HAAAKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:cobbled_deepslate_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR7AgAACAQAbmFtZSAAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlX3NsYWIECQBuYW1lX2hhc2gwJIVWK1TM2QMKAG5ldHdvcmtfaWTLMgAACgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:polished_deepslate_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR/AgAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZV9zbGFiBAkAbmFtZV9oYXNoC/Adiz8k6RYDCgBuZXR3b3JrX2lk5wIAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:deepslate_tile_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAgAACAQAbmFtZR0AbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlX3NsYWIECQBuYW1lX2hhc2hPydV6emzIXAMKAG5ldHdvcmtfaWS2GwAACgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:deepslate_brick_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSHAgAACAQAbmFtZR4AbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja19zbGFiBAkAbmFtZV9oYXNoSv62V7iw10UDCgBuZXR3b3JrX2lk3xcAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:mud_brick_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTdAgAACAQAbmFtZRgAbWluZWNyYWZ0Om11ZF9icmlja19zbGFiBAkAbmFtZV9oYXNoq/tGBQWkv08DCgBuZXR3b3JrX2lkJxoAAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:brick_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQtAAAACAQAbmFtZRUAbWluZWNyYWZ0OmJyaWNrX2Jsb2NrBAkAbmFtZV9oYXNo5Qc2E005S3oDCgBuZXR3b3JrX2lksh8AAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:chiseled_nether_bricks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQtAgAACAQAbmFtZSAAbWluZWNyYWZ0OmNoaXNlbGVkX25ldGhlcl9icmlja3MECQBuYW1lX2hhc2g31SBPTcUK1QMKAG5ldHdvcmtfaWR7MgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:cracked_nether_bricks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQuAgAACAQAbmFtZR8AbWluZWNyYWZ0OmNyYWNrZWRfbmV0aGVyX2JyaWNrcwQJAG5hbWVfaGFzaAdC6eKzXT5tAwoAbmV0d29ya19pZPMcAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:quartz_bricks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQvAgAACAQAbmFtZRcAbWluZWNyYWZ0OnF1YXJ0el9icmlja3MECQBuYW1lX2hhc2jSZO590dd8sAMKAG5ldHdvcmtfaWTrLAAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:stonebrick", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAAAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWTqLQAACgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQcAZGVmYXVsdAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:stonebrick", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAAAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWTrLQAACgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQUAbW9zc3kAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:stonebrick", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAAAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWTsLQAACgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQcAY3JhY2tlZAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:stonebrick", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAAAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWTtLQAACgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQgAY2hpc2VsZWQAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:end_bricks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTOAAAACAQAbmFtZRQAbWluZWNyYWZ0OmVuZF9icmlja3MECQBuYW1lX2hhc2hIUFfxNLZaFgMKAG5ldHdvcmtfaWTfAgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:prismarine", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAAAACAQAbmFtZRQAbWluZWNyYWZ0OnByaXNtYXJpbmUECQBuYW1lX2hhc2jcnQCHi9CspQMKAG5ldHdvcmtfaWThKwAACgYAc3RhdGVzCBUAcHJpc21hcmluZV9ibG9ja190eXBlBgBicmlja3MAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:polished_blackstone_bricks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQRAgAACAQAbmFtZSQAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tzBAkAbmFtZV9oYXNoIHgsgIdzKXcDCgBuZXR3b3JrX2lkNR8AAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:cracked_polished_blackstone_bricks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQXAgAACAQAbmFtZSwAbWluZWNyYWZ0OmNyYWNrZWRfcG9saXNoZWRfYmxhY2tzdG9uZV9icmlja3MECQBuYW1lX2hhc2jQIO1GQDk80AMKAG5ldHdvcmtfaWRGMgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:gilded_blackstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAgAACAQAbmFtZRsAbWluZWNyYWZ0OmdpbGRlZF9ibGFja3N0b25lBAkAbmFtZV9oYXNoNoWt1ocG0HEDCgBuZXR3b3JrX2lkKR0AAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:chiseled_polished_blackstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQWAgAACAQAbmFtZSYAbWluZWNyYWZ0OmNoaXNlbGVkX3BvbGlzaGVkX2JsYWNrc3RvbmUECQBuYW1lX2hhc2gzFa+kEjCJgAMKAG5ldHdvcmtfaWSEIgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:deepslate_tiles", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSCAgAACAQAbmFtZRkAbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlcwQJAG5hbWVfaGFzaGcLLx3NXAFvAwoAbmV0d29ya19pZBEdAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:cracked_deepslate_tiles", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSYAgAACAQAbmFtZSEAbWluZWNyYWZ0OmNyYWNrZWRfZGVlcHNsYXRlX3RpbGVzBAkAbmFtZV9oYXNo9zWgkFuMM1QDCgBuZXR3b3JrX2lkJBsAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:deepslate_bricks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSGAgAACAQAbmFtZRoAbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja3MECQBuYW1lX2hhc2gucvFmPdZxigMKAG5ldHdvcmtfaWQ/JAAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:cracked_deepslate_bricks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSZAgAACAQAbmFtZSIAbWluZWNyYWZ0OmNyYWNrZWRfZGVlcHNsYXRlX2JyaWNrcwQJAG5hbWVfaGFzaN40aqhh9WqHAwoAbmV0d29ya19pZLcjAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:chiseled_deepslate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSKAgAACAQAbmFtZRwAbWluZWNyYWZ0OmNoaXNlbGVkX2RlZXBzbGF0ZQQJAG5hbWVfaGFzaEU7/uRG8HSBAwoAbmV0d29ya19pZDAjAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:cobblestone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQEAAAACAQAbmFtZRUAbWluZWNyYWZ0OmNvYmJsZXN0b25lBAkAbmFtZV9oYXNoPoK7mGlSUz4DCgBuZXR3b3JrX2lkcxcAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:mossy_cobblestone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQwAAAACAQAbmFtZRsAbWluZWNyYWZ0Om1vc3N5X2NvYmJsZXN0b25lBAkAbmFtZV9oYXNoGJ67FCbkChMDCgBuZXR3b3JrX2lkqAIAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:cobbled_deepslate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR6AgAACAQAbmFtZRsAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlBAkAbmFtZV9oYXNoLUz9Y/ywmLwDCgBuZXR3b3JrX2lkaS4AAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:smooth_stone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AQAACAQAbmFtZRYAbWluZWNyYWZ0OnNtb290aF9zdG9uZQQJAG5hbWVfaGFzaMwf87/JaTNvAwoAbmV0d29ya19pZBIdAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:sandstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZJ0XAAAKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGUHAGRlZmF1bHQAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:sandstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZJ4XAAAKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGULAGhlaXJvZ2x5cGhzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:sandstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZJ8XAAAKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGUDAGN1dAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:sandstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZKAXAAAKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGUGAHNtb290aAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:red_sandstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWQLLgAACgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlBwBkZWZhdWx0AAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:red_sandstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWQMLgAACgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlCwBoZWlyb2dseXBocwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:red_sandstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWQNLgAACgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlAwBjdXQAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:red_sandstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWQOLgAACgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlBgBzbW9vdGgAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:coal_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWStAAAACAQAbmFtZRQAbWluZWNyYWZ0OmNvYWxfYmxvY2sECQBuYW1lX2hhc2jH8QQP3t5PiAMKAG5ldHdvcmtfaWTcIwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:dried_kelp_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSKAQAACAQAbmFtZRoAbWluZWNyYWZ0OmRyaWVkX2tlbHBfYmxvY2sECQBuYW1lX2hhc2iRoucexkrl8wMKAG5ldHdvcmtfaWTKNQAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:gold_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQpAAAACAQAbmFtZRQAbWluZWNyYWZ0OmdvbGRfYmxvY2sECQBuYW1lX2hhc2iYLshvjtXzFwMKAG5ldHdvcmtfaWQKAwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:iron_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQqAAAACAQAbmFtZRQAbWluZWNyYWZ0Omlyb25fYmxvY2sECQBuYW1lX2hhc2jYINmJQbvV/gMKAG5ldHdvcmtfaWT5NgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:copper_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRTAgAACAQAbmFtZRYAbWluZWNyYWZ0OmNvcHBlcl9ibG9jawQJAG5hbWVfaGFzaDVxnehsGaZ1AwoAbmV0d29ya19pZBgfAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:exposed_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRUAgAACAQAbmFtZRgAbWluZWNyYWZ0OmV4cG9zZWRfY29wcGVyBAkAbmFtZV9oYXNoQH3Fukmu3CEDCgBuZXR3b3JrX2lkRgUAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:weathered_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRVAgAACAQAbmFtZRoAbWluZWNyYWZ0OndlYXRoZXJlZF9jb3BwZXIECQBuYW1lX2hhc2hJCQXbvobv+gMKAG5ldHdvcmtfaWTVNgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:oxidized_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRWAgAACAQAbmFtZRkAbWluZWNyYWZ0Om94aWRpemVkX2NvcHBlcgQJAG5hbWVfaGFzaMDtJqR0G5Y7AwoAbmV0d29ya19pZDEXAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:waxed_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRXAgAACAQAbmFtZRYAbWluZWNyYWZ0OndheGVkX2NvcHBlcgQJAG5hbWVfaGFzaPF+FG6Eh5fsAwoAbmV0d29ya19pZIA0AAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:waxed_exposed_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRYAgAACAQAbmFtZR4AbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY29wcGVyBAkAbmFtZV9oYXNoig8IOc+SCikDCgBuZXR3b3JrX2lkrwcAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:waxed_weathered_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRZAgAACAQAbmFtZSAAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jb3BwZXIECQBuYW1lX2hhc2gjtPq8MOdvKgMKAG5ldHdvcmtfaWS8BwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:waxed_oxidized_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS9AgAACAQAbmFtZR8AbWluZWNyYWZ0OndheGVkX294aWRpemVkX2NvcHBlcgQJAG5hbWVfaGFzaMaORhsO+LzjAwoAbmV0d29ya19pZLUzAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:cut_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRaAgAACAQAbmFtZRQAbWluZWNyYWZ0OmN1dF9jb3BwZXIECQBuYW1lX2hhc2hAfN3NGax3eAMKAG5ldHdvcmtfaWQ+HwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:exposed_cut_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRbAgAACAQAbmFtZRwAbWluZWNyYWZ0OmV4cG9zZWRfY3V0X2NvcHBlcgQJAG5hbWVfaGFzaA85G3yv/w6pAwoAbmV0d29ya19pZEIsAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:weathered_cut_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRcAgAACAQAbmFtZR4AbWluZWNyYWZ0OndlYXRoZXJlZF9jdXRfY29wcGVyBAkAbmFtZV9oYXNoVgRV0fBaz88DCgBuZXR3b3JrX2lkNTIAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:oxidized_cut_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRdAgAACAQAbmFtZR0AbWluZWNyYWZ0Om94aWRpemVkX2N1dF9jb3BwZXIECQBuYW1lX2hhc2iP8WmFWOkriwMKAG5ldHdvcmtfaWRNJAAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:waxed_cut_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWReAgAACAQAbmFtZRoAbWluZWNyYWZ0OndheGVkX2N1dF9jb3BwZXIECQBuYW1lX2hhc2jumiwOZIqv2AMKAG5ldHdvcmtfaWS6MgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:waxed_exposed_cut_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRfAgAACAQAbmFtZSIAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY3V0X2NvcHBlcgQJAG5hbWVfaGFzaPE/OfK6IoVMAwoAbmV0d29ya19pZEQYAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:waxed_weathered_cut_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRgAgAACAQAbmFtZSQAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jdXRfY29wcGVyBAkAbmFtZV9oYXNoCA1xDp11bnwDCgBuZXR3b3JrX2lknCEAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:waxed_oxidized_cut_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS+AgAACAQAbmFtZSMAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2N1dF9jb3BwZXIECQBuYW1lX2hhc2i1pZAsZYHLDAMKAG5ldHdvcmtfaWR5AgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:emerald_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAAAACAQAbmFtZRcAbWluZWNyYWZ0OmVtZXJhbGRfYmxvY2sECQBuYW1lX2hhc2hK6QunqJznNAMKAG5ldHdvcmtfaWQkCgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:diamond_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ5AAAACAQAbmFtZRcAbWluZWNyYWZ0OmRpYW1vbmRfYmxvY2sECQBuYW1lX2hhc2iGKrxuvkytFQMKAG5ldHdvcmtfaWTRAgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:lapis_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQWAAAACAQAbmFtZRUAbWluZWNyYWZ0OmxhcGlzX2Jsb2NrBAkAbmFtZV9oYXNoDZ44xdb2zVoDCgBuZXR3b3JrX2lkrhsAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:raw_iron_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTCAgAACAQAbmFtZRgAbWluZWNyYWZ0OnJhd19pcm9uX2Jsb2NrBAkAbmFtZV9oYXNo9XyzNIQXxvwDCgBuZXR3b3JrX2lk9jYAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:raw_copper_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTDAgAACAQAbmFtZRoAbWluZWNyYWZ0OnJhd19jb3BwZXJfYmxvY2sECQBuYW1lX2hhc2hw1KG0TNUGgwMKAG5ldHdvcmtfaWRlIwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:raw_gold_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTEAgAACAQAbmFtZRgAbWluZWNyYWZ0OnJhd19nb2xkX2Jsb2NrBAkAbmFtZV9oYXNo6YuwuLwfOBwDCgBuZXR3b3JrX2lkVAQAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:quartz_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAAAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZMgXAAAKBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQcAZGVmYXVsdAgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:quartz_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAAAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZMoXAAAKBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQUAbGluZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:quartz_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAAAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZMkXAAAKBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQgAY2hpc2VsZWQICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:quartz_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAAAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZMsXAAAKBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQYAc21vb3RoCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:prismarine", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAAAACAQAbmFtZRQAbWluZWNyYWZ0OnByaXNtYXJpbmUECQBuYW1lX2hhc2jcnQCHi9CspQMKAG5ldHdvcmtfaWTfKwAACgYAc3RhdGVzCBUAcHJpc21hcmluZV9ibG9ja190eXBlBwBkZWZhdWx0AAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:prismarine", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAAAACAQAbmFtZRQAbWluZWNyYWZ0OnByaXNtYXJpbmUECQBuYW1lX2hhc2jcnQCHi9CspQMKAG5ldHdvcmtfaWTgKwAACgYAc3RhdGVzCBUAcHJpc21hcmluZV9ibG9ja190eXBlBABkYXJrAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:slime", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAAAACAQAbmFtZQ8AbWluZWNyYWZ0OnNsaW1lBAkAbmFtZV9oYXNoHJiEEJx+JlkDCgBuZXR3b3JrX2lkdhsAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:honey_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTbAQAACAQAbmFtZRUAbWluZWNyYWZ0OmhvbmV5X2Jsb2NrBAkAbmFtZV9oYXNo9zLYSUlelywDCgBuZXR3b3JrX2lkHwkAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:honeycomb_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTcAQAACAQAbmFtZRkAbWluZWNyYWZ0OmhvbmV5Y29tYl9ibG9jawQJAG5hbWVfaGFzaASIPuOCYd1oAwoAbmV0d29ya19pZKUcAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:hay_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSqAAAACAQAbmFtZRMAbWluZWNyYWZ0OmhheV9ibG9jawQJAG5hbWVfaGFzaIB2VxKxX8EpAwoAbmV0d29ya19pZLAHAAAKBgBzdGF0ZXMDCgBkZXByZWNhdGVkAAAAAAgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:bone_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTYAAAACAQAbmFtZRQAbWluZWNyYWZ0OmJvbmVfYmxvY2sECQBuYW1lX2hhc2i4ZX576W9AWgMKAG5ldHdvcmtfaWR3GwAACgYAc3RhdGVzAwoAZGVwcmVjYXRlZAAAAAAICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:nether_brick", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRwAAAACAQAbmFtZRYAbWluZWNyYWZ0Om5ldGhlcl9icmljawQJAG5hbWVfaGFzaMxcRiheU+nXAwoAbmV0d29ya19pZKUyAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:red_nether_brick", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTXAAAACAQAbmFtZRoAbWluZWNyYWZ0OnJlZF9uZXRoZXJfYnJpY2sECQBuYW1lX2hhc2j8pRO4LfoECAMKAG5ldHdvcmtfaWQ0AgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:netherite_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQNAgAACAQAbmFtZRkAbWluZWNyYWZ0Om5ldGhlcml0ZV9ibG9jawQJAG5hbWVfaGFzaMghh6Zib/ZKAwoAbmV0d29ya19pZCEYAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:lodestone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTdAQAACAQAbmFtZRMAbWluZWNyYWZ0OmxvZGVzdG9uZQQJAG5hbWVfaGFzaJ2gmHOTlXv8AwoAbmV0d29ya19pZPM2AAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:white_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQjAAAACAQAbmFtZRQAbWluZWNyYWZ0OndoaXRlX3dvb2wECQBuYW1lX2hhc2jRWB7vaIEDiQMKAG5ldHdvcmtfaWTdIwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:light_gray_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQnAwAACAQAbmFtZRkAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfd29vbAQJAG5hbWVfaGFzaOpdQ1a2v4b3AwoAbmV0d29ya19pZAo2AAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:gray_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQoAwAACAQAbmFtZRMAbWluZWNyYWZ0OmdyYXlfd29vbAQJAG5hbWVfaGFzaLsc1Lp1xdIOAwoAbmV0d29ya19pZIcCAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:black_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQpAwAACAQAbmFtZRQAbWluZWNyYWZ0OmJsYWNrX3dvb2wECQBuYW1lX2hhc2hP2HC6o0X4HAMKAG5ldHdvcmtfaWRXBAAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:brown_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQqAwAACAQAbmFtZRQAbWluZWNyYWZ0OmJyb3duX3dvb2wECQBuYW1lX2hhc2ig5IW89PrREwMKAG5ldHdvcmtfaWS9AgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:red_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQrAwAACAQAbmFtZRIAbWluZWNyYWZ0OnJlZF93b29sBAkAbmFtZV9oYXNoY4TBDq+mFgUDCgBuZXR3b3JrX2lkfwAAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:orange_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAwAACAQAbmFtZRUAbWluZWNyYWZ0Om9yYW5nZV93b29sBAkAbmFtZV9oYXNoFstfrTZfSCgDCgBuZXR3b3JrX2lknAcAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:yellow_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQtAwAACAQAbmFtZRUAbWluZWNyYWZ0OnllbGxvd193b29sBAkAbmFtZV9oYXNoTFyus2RHegcDCgBuZXR3b3JrX2lkKgIAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:lime_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQuAwAACAQAbmFtZRMAbWluZWNyYWZ0OmxpbWVfd29vbAQJAG5hbWVfaGFzaNVnnzKiMxmeAwoAbmV0d29ya19pZHorAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:green_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQvAwAACAQAbmFtZRQAbWluZWNyYWZ0OmdyZWVuX3dvb2wECQBuYW1lX2hhc2i3mElRYHIcSQMKAG5ldHdvcmtfaWTtFwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:cyan_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQwAwAACAQAbmFtZRMAbWluZWNyYWZ0OmN5YW5fd29vbAQJAG5hbWVfaGFzaBNDfvHn8dqFAwoAbmV0d29ya19pZKEjAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:light_blue_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQxAwAACAQAbmFtZRkAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfd29vbAQJAG5hbWVfaGFzaLWFAUfyxFPNAwoAbmV0d29ya19pZDMwAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:blue_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQyAwAACAQAbmFtZRMAbWluZWNyYWZ0OmJsdWVfd29vbAQJAG5hbWVfaGFzaLjHyxxbTWCLAwoAbmV0d29ya19pZE4kAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:purple_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQzAwAACAQAbmFtZRUAbWluZWNyYWZ0OnB1cnBsZV93b29sBAkAbmFtZV9oYXNojvFtqzjAf/4DCgBuZXR3b3JrX2lk+DYAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:magenta_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ0AwAACAQAbmFtZRYAbWluZWNyYWZ0Om1hZ2VudGFfd29vbAQJAG5hbWVfaGFzaGuOHvf+Pd4yAwoAbmV0d29ya19pZG8JAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:pink_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ1AwAACAQAbmFtZRMAbWluZWNyYWZ0OnBpbmtfd29vbAQJAG5hbWVfaGFzaPiVA2pFeoFLAwoAbmV0d29ya19pZCIYAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:white_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSrAAAACAQAbmFtZRYAbWluZWNyYWZ0OndoaXRlX2NhcnBldAQJAG5hbWVfaGFzaNeMHTI1fWPXAwoAbmV0d29ya19pZJkyAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:light_gray_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRbAwAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY2FycGV0BAkAbmFtZV9oYXNoHPw6ArBAsP0DCgBuZXR3b3JrX2lk9zYAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:gray_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRaAwAACAQAbmFtZRUAbWluZWNyYWZ0OmdyYXlfY2FycGV0BAkAbmFtZV9oYXNoZVR0OI+1VRADCgBuZXR3b3JrX2lkigIAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:black_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJsYWNrX2NhcnBldAQJAG5hbWVfaGFzaOk7LP9NptyhAwoAbmV0d29ya19pZKErAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:brown_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRfAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJyb3duX2NhcnBldAQJAG5hbWVfaGFzaNaXFyOsAvIvAwoAbmV0d29ya19pZFIJAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:red_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAwAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9jYXJwZXQECQBuYW1lX2hhc2i9eSKBf6SO3wMKAG5ldHdvcmtfaWQ3MwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:orange_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRUAwAACAQAbmFtZRcAbWluZWNyYWZ0Om9yYW5nZV9jYXJwZXQECQBuYW1lX2hhc2hIUkO4HlAdygMKAG5ldHdvcmtfaWQKMAAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:yellow_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRXAwAACAQAbmFtZRcAbWluZWNyYWZ0OnllbGxvd19jYXJwZXQECQBuYW1lX2hhc2hSDKX3scCamwMKAG5ldHdvcmtfaWRXKQAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:lime_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRYAwAACAQAbmFtZRUAbWluZWNyYWZ0OmxpbWVfY2FycGV0BAkAbmFtZV9oYXNo+6KFOpzsib4DCgBuZXR3b3JrX2lklS4AAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:green_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRgAwAACAQAbmFtZRYAbWluZWNyYWZ0OmdyZWVuX2NhcnBldAQJAG5hbWVfaGFzaCHPMP9ltqFJAwoAbmV0d29ya19pZO4XAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:cyan_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRcAwAACAQAbmFtZRUAbWluZWNyYWZ0OmN5YW5fY2FycGV0BAkAbmFtZV9oYXNobXf62dQBJj8DCgBuZXR3b3JrX2lkdhcAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:light_blue_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRWAwAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY2FycGV0BAkAbmFtZV9oYXNo20l4oktdZ3sDCgBuZXR3b3JrX2lk6R8AAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:blue_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWReAwAACAQAbmFtZRUAbWluZWNyYWZ0OmJsdWVfY2FycGV0BAkAbmFtZV9oYXNo3p3lsW0eQwsDCgBuZXR3b3JrX2lkVQIAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:purple_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRdAwAACAQAbmFtZRcAbWluZWNyYWZ0OnB1cnBsZV9jYXJwZXQECQBuYW1lX2hhc2jwIA9pW/qp7QMKAG5ldHdvcmtfaWSRNAAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:magenta_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRVAwAACAQAbmFtZRgAbWluZWNyYWZ0Om1hZ2VudGFfY2FycGV0BAkAbmFtZV9oYXNoFXT36YNNZhMDCgBuZXR3b3JrX2lkrAIAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:pink_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRZAwAACAQAbmFtZRUAbWluZWNyYWZ0OnBpbmtfY2FycGV0BAkAbmFtZV9oYXNoHll72oqk+OoDCgBuZXR3b3JrX2lkVzQAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:white_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTtAAAACAQAbmFtZR8AbWluZWNyYWZ0OndoaXRlX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaFUk9iXVjwV8AwoAbmV0d29ya19pZGohAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:light_gray_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTLAwAACAQAbmFtZSQAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNo7EUk30hmUtYDCgBuZXR3b3JrX2lkiTIAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:gray_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTKAwAACAQAbmFtZR4AbWluZWNyYWZ0OmdyYXlfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoW77af6WihdwDCgBuZXR3b3JrX2lkATMAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:black_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTSAwAACAQAbmFtZR8AbWluZWNyYWZ0OmJsYWNrX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaAfWYp0xtgcfAwoAbmV0d29ya19pZHkEAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:brown_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTPAwAACAQAbmFtZR8AbWluZWNyYWZ0OmJyb3duX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaB74EeiLO46XAwoAbmV0d29ya19pZJMnAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:red_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTRAwAACAQAbmFtZR0AbWluZWNyYWZ0OnJlZF9jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2gjFut6Z/VH1gMKAG5ldHdvcmtfaWSIMgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:orange_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTEAwAACAQAbmFtZSAAbWluZWNyYWZ0Om9yYW5nZV9jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2gADDj2IJiw+gMKAG5ldHdvcmtfaWTSNgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:yellow_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTHAwAACAQAbmFtZSAAbWluZWNyYWZ0OnllbGxvd19jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2iy6qKNn3ob5wMKAG5ldHdvcmtfaWTdMwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:lime_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTIAwAACAQAbmFtZR4AbWluZWNyYWZ0OmxpbWVfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNo4dYIPslbXPUDCgBuZXR3b3JrX2lk3jUAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:green_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTQAwAACAQAbmFtZR8AbWluZWNyYWZ0OmdyZWVuX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaM/c9x2aJh3HAwoAbmV0d29ya19pZM0vAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:cyan_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTMAwAACAQAbmFtZR4AbWluZWNyYWZ0OmN5YW5fY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNok+xKAe7XXjoDCgBuZXR3b3JrX2lkGhcAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:light_blue_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTGAwAACAQAbmFtZSQAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNogScpIQceyAEDCgBuZXR3b3JrX2lkPgAAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:blue_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTOAwAACAQAbmFtZR4AbWluZWNyYWZ0OmJsdWVfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoFp7mmeL86r0DCgBuZXR3b3JrX2lkki4AAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:purple_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTNAwAACAQAbmFtZSAAbWluZWNyYWZ0OnB1cnBsZV9jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2iYcVU04hoStwMKAG5ldHdvcmtfaWThLQAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:magenta_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTFAwAACAQAbmFtZSEAbWluZWNyYWZ0Om1hZ2VudGFfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoy/70q6VPsWgDCgBuZXR3b3JrX2lkhBwAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:pink_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAwAACAQAbmFtZR4AbWluZWNyYWZ0OnBpbmtfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoVikSAf8DwV0DCgBuZXR3b3JrX2lkuBsAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:white_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTsAAAACAQAbmFtZRgAbWluZWNyYWZ0OndoaXRlX2NvbmNyZXRlBAkAbmFtZV9oYXNo6zAp7lsLlvkDCgBuZXR3b3JrX2lkJzYAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:light_gray_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR6AwAACAQAbmFtZR0AbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY29uY3JldGUECQBuYW1lX2hhc2hEtet5wuDIKAMKAG5ldHdvcmtfaWSmBwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:gray_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR5AwAACAQAbmFtZRcAbWluZWNyYWZ0OmdyYXlfY29uY3JldGUECQBuYW1lX2hhc2j92INnb0a83AMKAG5ldHdvcmtfaWQCMwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:black_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSBAwAACAQAbmFtZRgAbWluZWNyYWZ0OmJsYWNrX2NvbmNyZXRlBAkAbmFtZV9oYXNo2X7NDIQmZ70DCgBuZXR3b3JrX2lkgi4AAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:brown_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR+AwAACAQAbmFtZRgAbWluZWNyYWZ0OmJyb3duX2NvbmNyZXRlBAkAbmFtZV9oYXNoeka02BwXf6oDCgBuZXR3b3JrX2lkZCwAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:red_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSAAwAACAQAbmFtZRYAbWluZWNyYWZ0OnJlZF9jb25jcmV0ZQQJAG5hbWVfaGFzaPWmNowLGubqAwoAbmV0d29ya19pZFY0AAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:orange_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRzAwAACAQAbmFtZRkAbWluZWNyYWZ0Om9yYW5nZV9jb25jcmV0ZQQJAG5hbWVfaGFzaAgE8XmaAi6+AwoAbmV0d29ya19pZJMuAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:yellow_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR2AwAACAQAbmFtZRkAbWluZWNyYWZ0OnllbGxvd19jb25jcmV0ZQQJAG5hbWVfaGFzaE6ONfJPBd0+AwoAbmV0d29ya19pZHUXAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:lime_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR3AwAACAQAbmFtZRcAbWluZWNyYWZ0OmxpbWVfY29uY3JldGUECQBuYW1lX2hhc2gnd8JW6wmJcAMKAG5ldHdvcmtfaWQlHQAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:green_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR/AwAACAQAbmFtZRgAbWluZWNyYWZ0OmdyZWVuX2NvbmNyZXRlBAkAbmFtZV9oYXNokbFxRKchQZkDCgBuZXR3b3JrX2lkPSkAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:cyan_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR7AwAACAQAbmFtZRcAbWluZWNyYWZ0OmN5YW5fY29uY3JldGUECQBuYW1lX2hhc2hFRrWJ33qj1wMKAG5ldHdvcmtfaWSaMgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:light_blue_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR1AwAACAQAbmFtZR0AbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY29uY3JldGUECQBuYW1lX2hhc2gHAe0kl0SE4AMKAG5ldHdvcmtfaWRKMwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:blue_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR9AwAACAQAbmFtZRcAbWluZWNyYWZ0OmJsdWVfY29uY3JldGUECQBuYW1lX2hhc2hiay301nnj1wMKAG5ldHdvcmtfaWSkMgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:purple_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR8AwAACAQAbmFtZRkAbWluZWNyYWZ0OnB1cnBsZV9jb25jcmV0ZQQJAG5hbWVfaGFzaHBHflsPIwdXAwoAbmV0d29ya19pZEYbAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:magenta_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR0AwAACAQAbmFtZRoAbWluZWNyYWZ0Om1hZ2VudGFfY29uY3JldGUECQBuYW1lX2hhc2gN7LuB/OvdZAMKAG5ldHdvcmtfaWQpHAAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:pink_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR4AwAACAQAbmFtZRcAbWluZWNyYWZ0OnBpbmtfY29uY3JldGUECQBuYW1lX2hhc2ii2G5F0u3SOAMKAG5ldHdvcmtfaWSXFQAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:clay", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRSAAAACAQAbmFtZQ4AbWluZWNyYWZ0OmNsYXkECQBuYW1lX2hhc2j/S6sKXRcpzwMKAG5ldHdvcmtfaWRjMAAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:hardened_clay", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSsAAAACAQAbmFtZRcAbWluZWNyYWZ0OmhhcmRlbmVkX2NsYXkECQBuYW1lX2hhc2jrnRwCJ0krJAMKAG5ldHdvcmtfaWRmBQAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:white_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSfAAAACAQAbmFtZRoAbWluZWNyYWZ0OndoaXRlX3RlcnJhY290dGEECQBuYW1lX2hhc2j3RSdgmnAIewMKAG5ldHdvcmtfaWToHwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:light_gray_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTaAwAACAQAbmFtZR8AbWluZWNyYWZ0OmxpZ2h0X2dyYXlfdGVycmFjb3R0YQQJAG5hbWVfaGFzaAz1Ri3wIxomAwoAbmV0d29ya19pZOwGAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:gray_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTZAwAACAQAbmFtZRkAbWluZWNyYWZ0OmdyYXlfdGVycmFjb3R0YQQJAG5hbWVfaGFzaAXdSLAaNZ9vAwoAbmV0d29ya19pZBQdAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:black_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWThAwAACAQAbmFtZRoAbWluZWNyYWZ0OmJsYWNrX3RlcnJhY290dGEECQBuYW1lX2hhc2jxssdv5vlbpgMKAG5ldHdvcmtfaWT0KwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:brown_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTeAwAACAQAbmFtZRoAbWluZWNyYWZ0OmJyb3duX3RlcnJhY290dGEECQBuYW1lX2hhc2gG4kPenmOF9gMKAG5ldHdvcmtfaWT4NQAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:red_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTgAwAACAQAbmFtZRgAbWluZWNyYWZ0OnJlZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNo7fX56HXFejEDCgBuZXR3b3JrX2lkagkAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:orange_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAwAACAQAbmFtZRsAbWluZWNyYWZ0Om9yYW5nZV90ZXJyYWNvdHRhBAkAbmFtZV9oYXNo0Hjmql3sruMDCgBuZXR3b3JrX2lktDMAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:yellow_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTWAwAACAQAbmFtZRsAbWluZWNyYWZ0OnllbGxvd190ZXJyYWNvdHRhBAkAbmFtZV9oYXNoqkyKKrmA3VcDCgBuZXR3b3JrX2lkThsAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:lime_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTXAwAACAQAbmFtZRkAbWluZWNyYWZ0OmxpbWVfdGVycmFjb3R0YQQJAG5hbWVfaGFzaANjADFOF9v7AwoAbmV0d29ya19pZNw2AAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:green_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTfAwAACAQAbmFtZRoAbWluZWNyYWZ0OmdyZWVuX3RlcnJhY290dGEECQBuYW1lX2hhc2j5Ybq36yYwRQMKAG5ldHdvcmtfaWTeFwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:cyan_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTbAwAACAQAbmFtZRkAbWluZWNyYWZ0OmN5YW5fdGVycmFjb3R0YQQJAG5hbWVfaGFzaN09COzMuHwAAwoAbmV0d29ya19pZAAAAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:light_blue_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTVAwAACAQAbmFtZR8AbWluZWNyYWZ0OmxpZ2h0X2JsdWVfdGVycmFjb3R0YQQJAG5hbWVfaGFzaOMytez7cOZiAwoAbmV0d29ya19pZBscAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:blue_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTdAwAACAQAbmFtZRkAbWluZWNyYWZ0OmJsdWVfdGVycmFjb3R0YQQJAG5hbWVfaGFzaF6inyTK5RpAAwoAbmV0d29ya19pZJwXAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:purple_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTcAwAACAQAbmFtZRsAbWluZWNyYWZ0OnB1cnBsZV90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoKF7YG61yTbEDCgBuZXR3b3JrX2lkEi0AAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:magenta_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTUAwAACAQAbmFtZRwAbWluZWNyYWZ0Om1hZ2VudGFfdGVycmFjb3R0YQQJAG5hbWVfaGFzaLWvtpAVtztyAwoAbmV0d29ya19pZCsdAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:pink_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTYAwAACAQAbmFtZRkAbWluZWNyYWZ0OnBpbmtfdGVycmFjb3R0YQQJAG5hbWVfaGFzaJ7mzvyzSQZTAwoAbmV0d29ya19pZCEbAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:white_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTcAAAACAQAbmFtZSEAbWluZWNyYWZ0OndoaXRlX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoiVzCdoHAJo0DCgBuZXR3b3JrX2lkrSQAAAoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:silver_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTkAAAACAQAbmFtZSIAbWluZWNyYWZ0OnNpbHZlcl9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaAVsA0CnhzA4AwoAbmV0d29ya19pZIkVAAAKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:gray_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTjAAAACAQAbmFtZSAAbWluZWNyYWZ0OmdyYXlfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2jvLZt9u/lF/AMKAG5ldHdvcmtfaWTtNgAACgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:black_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTrAAAACAQAbmFtZSEAbWluZWNyYWZ0OmJsYWNrX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoe8I4xAXbO5UDCgBuZXR3b3JrX2lkOicAAAoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:brown_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWToAAAACAQAbmFtZSEAbWluZWNyYWZ0OmJyb3duX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoSiNZOobbpjoDCgBuZXR3b3JrX2lkGxcAAAoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:red_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTqAAAACAQAbmFtZR8AbWluZWNyYWZ0OnJlZF9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaBdWFGLmCLFVAwoAbmV0d29ya19pZCsbAAAKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:orange_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTdAAAACAQAbmFtZSIAbWluZWNyYWZ0Om9yYW5nZV9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaMyJMrnPr7szAwoAbmV0d29ya19pZBoKAAAKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:yellow_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTgAAAACAQAbmFtZSIAbWluZWNyYWZ0OnllbGxvd19nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaN6NaIhf6m0uAwoAbmV0d29ya19pZEQJAAAKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:lime_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWThAAAACAQAbmFtZSAAbWluZWNyYWZ0OmxpbWVfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2iF3E68/rB2EAMKAG5ldHdvcmtfaWSLAgAACgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:green_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTpAAAACAQAbmFtZSEAbWluZWNyYWZ0OmdyZWVuX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNow5mo8aQDFboDCgBuZXR3b3JrX2lkKi4AAAoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:cyan_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTlAAAACAQAbmFtZSAAbWluZWNyYWZ0OmN5YW5fZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2gnNB+cCFRJhwMKAG5ldHdvcmtfaWSxIwAACgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:light_blue_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTfAAAACAQAbmFtZSYAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2gladnCDBKCigMKAG5ldHdvcmtfaWRGJAAACgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:blue_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTnAAAACAQAbmFtZSAAbWluZWNyYWZ0OmJsdWVfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2giOZK+2nB1igMKAG5ldHdvcmtfaWRAJAAACgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:purple_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTbAAAACAQAbmFtZSIAbWluZWNyYWZ0OnB1cnBsZV9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaIQU03txeAfHAwoAbmV0d29ya19pZMcvAAAKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:magenta_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTeAAAACAQAbmFtZSMAbWluZWNyYWZ0Om1hZ2VudGFfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2i/SNqDJbfjMgMKAG5ldHdvcmtfaWRwCQAACgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:pink_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTiAAAACAQAbmFtZSAAbWluZWNyYWZ0OnBpbmtfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2hik8DVt4g+twMKAG5ldHdvcmtfaWTiLQAACgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:purpur_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAAAACAQAbmFtZRYAbWluZWNyYWZ0OnB1cnB1cl9ibG9jawQJAG5hbWVfaGFzaAgLwnUZGlzsAwoAbmV0d29ya19pZGY0AAAKBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQcAZGVmYXVsdAgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:purpur_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAAAACAQAbmFtZRYAbWluZWNyYWZ0OnB1cnB1cl9ibG9jawQJAG5hbWVfaGFzaAgLwnUZGlzsAwoAbmV0d29ya19pZGg0AAAKBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQUAbGluZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:packed_mud", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTcAgAACAQAbmFtZRQAbWluZWNyYWZ0OnBhY2tlZF9tdWQECQBuYW1lX2hhc2gHOMa121h4FgMKAG5ldHdvcmtfaWTiAgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:mud_bricks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTaAgAACAQAbmFtZRQAbWluZWNyYWZ0Om11ZF9icmlja3MECQBuYW1lX2hhc2iDL/SVl/PewQMKAG5ldHdvcmtfaWRBLwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:nether_wart_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTWAAAACAQAbmFtZRsAbWluZWNyYWZ0Om5ldGhlcl93YXJ0X2Jsb2NrBAkAbmFtZV9oYXNo9XGS4GNnlV4DCgBuZXR3b3JrX2lkuhsAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:warped_wart_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTiAQAACAQAbmFtZRsAbWluZWNyYWZ0OndhcnBlZF93YXJ0X2Jsb2NrBAkAbmFtZV9oYXNo9IqDS9yUPJoDCgBuZXR3b3JrX2lkRSkAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:shroomlight", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTlAQAACAQAbmFtZRUAbWluZWNyYWZ0OnNocm9vbWxpZ2h0BAkAbmFtZV9oYXNoZHCHcHX/HYADCgBuZXR3b3JrX2lkcyIAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:crimson_nylium", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTnAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fbnlsaXVtBAkAbmFtZV9oYXNoOr6DJYW2bFYDCgBuZXR3b3JrX2lkQxsAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:warped_nylium", - "block_state_b64": "CgAAAwgAYmxvY2tfaWToAQAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9ueWxpdW0ECQBuYW1lX2hhc2g0Zf89cfr3rwMKAG5ldHdvcmtfaWTpLAAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:netherrack", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRXAAAACAQAbmFtZRQAbWluZWNyYWZ0Om5ldGhlcnJhY2sECQBuYW1lX2hhc2i/r5ZyRsvPyQMKAG5ldHdvcmtfaWTlLwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:basalt", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTpAQAACAQAbmFtZRAAbWluZWNyYWZ0OmJhc2FsdAQJAG5hbWVfaGFzaH+UQO2yWodiAwoAbmV0d29ya19pZBccAAAKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:polished_basalt", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTqAQAACAQAbmFtZRkAbWluZWNyYWZ0OnBvbGlzaGVkX2Jhc2FsdAQJAG5hbWVfaGFzaMS+L0gMnRcBAwoAbmV0d29ya19pZBoAAAAKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:smooth_basalt", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR4AgAACAQAbmFtZRcAbWluZWNyYWZ0OnNtb290aF9iYXNhbHQECQBuYW1lX2hhc2jKPUdz89kuNAMKAG5ldHdvcmtfaWQhCgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:soul_soil", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTrAQAACAQAbmFtZRMAbWluZWNyYWZ0OnNvdWxfc29pbAQJAG5hbWVfaGFzaC1/87ccutuTAwoAbmV0d29ya19pZLElAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:dirt", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAAAACAQAbmFtZQ4AbWluZWNyYWZ0OmRpcnQECQBuYW1lX2hhc2hXp6jnXAe+kQMKAG5ldHdvcmtfaWRgJQAACgYAc3RhdGVzCAkAZGlydF90eXBlBgBub3JtYWwAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:dirt", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAAAACAQAbmFtZQ4AbWluZWNyYWZ0OmRpcnQECQBuYW1lX2hhc2hXp6jnXAe+kQMKAG5ldHdvcmtfaWRhJQAACgYAc3RhdGVzCAkAZGlydF90eXBlBgBjb2Fyc2UAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:farmland", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ8AAAACAQAbmFtZRIAbWluZWNyYWZ0OmZhcm1sYW5kBAkAbmFtZV9oYXNoxyQ5ag7LolADCgBuZXR3b3JrX2lkKRoAAAoGAHN0YXRlcwMSAG1vaXN0dXJpemVkX2Ftb3VudAAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:grass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQCAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmdyYXNzBAkAbmFtZV9oYXNosppASPWFlsUDCgBuZXR3b3JrX2lkoC8AAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:grass_path", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTGAAAACAQAbmFtZRQAbWluZWNyYWZ0OmdyYXNzX3BhdGgECQBuYW1lX2hhc2i0/KZV8Qsy+gMKAG5ldHdvcmtfaWQvNgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:podzol", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTzAAAACAQAbmFtZRAAbWluZWNyYWZ0OnBvZHpvbAQJAG5hbWVfaGFzaBzqokRjH4Z1AwoAbmV0d29ya19pZBcfAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:mycelium", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRuAAAACAQAbmFtZRIAbWluZWNyYWZ0Om15Y2VsaXVtBAkAbmFtZV9oYXNojTN09cKickIDCgBuZXR3b3JrX2lkuxcAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:mud", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTYAgAACAQAbmFtZQ0AbWluZWNyYWZ0Om11ZAQJAG5hbWVfaGFzaPb/3P+uLy+9AwoAbmV0d29ya19pZGsuAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:stone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQBAAAACAQAbmFtZQ8AbWluZWNyYWZ0OnN0b25lBAkAbmFtZV9oYXNoE3mqhJxzJycDCgBuZXR3b3JrX2lk9AYAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:iron_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQPAAAACAQAbmFtZRIAbWluZWNyYWZ0Omlyb25fb3JlBAkAbmFtZV9oYXNoS7BYtLnfx3gDCgBuZXR3b3JrX2lkPx8AAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:gold_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQOAAAACAQAbmFtZRIAbWluZWNyYWZ0OmdvbGRfb3JlBAkAbmFtZV9oYXNoC5Y+DUGXLC4DCgBuZXR3b3JrX2lkQwkAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:diamond_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ4AAAACAQAbmFtZRUAbWluZWNyYWZ0OmRpYW1vbmRfb3JlBAkAbmFtZV9oYXNokUOJ2wZZrGQDCgBuZXR3b3JrX2lkJxwAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:lapis_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQVAAAACAQAbmFtZRMAbWluZWNyYWZ0OmxhcGlzX29yZQQJAG5hbWVfaGFzaMrmrUrSzb7qAwoAbmV0d29ya19pZFU0AAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:redstone_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRJAAAACAQAbmFtZRYAbWluZWNyYWZ0OnJlZHN0b25lX29yZQQJAG5hbWVfaGFzaFHVnp8Wc4JbAwoAbmV0d29ya19pZLEbAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:coal_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQQAAAACAQAbmFtZRIAbWluZWNyYWZ0OmNvYWxfb3JlBAkAbmFtZV9oYXNo1OjA+Iuy51oDCgBuZXR3b3JrX2lkrxsAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:copper_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ2AgAACAQAbmFtZRQAbWluZWNyYWZ0OmNvcHBlcl9vcmUECQBuYW1lX2hhc2iSZduSntOzOwMKAG5ldHdvcmtfaWQyFwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:emerald_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSBAAAACAQAbmFtZRUAbWluZWNyYWZ0OmVtZXJhbGRfb3JlBAkAbmFtZV9oYXNoJTovr+VgINsDCgBuZXR3b3JrX2lk8DIAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:quartz_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSZAAAACAQAbmFtZRQAbWluZWNyYWZ0OnF1YXJ0el9vcmUECQBuYW1lX2hhc2g0yNHLMK9TaQMKAG5ldHdvcmtfaWS+HAAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:nether_gold_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQfAgAACAQAbmFtZRkAbWluZWNyYWZ0Om5ldGhlcl9nb2xkX29yZQQJAG5hbWVfaGFzaEJZ7segIBgBAwoAbmV0d29ya19pZB0AAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:ancient_debris", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQOAgAACAQAbmFtZRgAbWluZWNyYWZ0OmFuY2llbnRfZGVicmlzBAkAbmFtZV9oYXNoNrbxMc9AwKcDCgBuZXR3b3JrX2lkBiwAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:deepslate_iron_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSQAgAACAQAbmFtZRwAbWluZWNyYWZ0OmRlZXBzbGF0ZV9pcm9uX29yZQQJAG5hbWVfaGFzaB/fDL9pgvXXAwoAbmV0d29ya19pZKYyAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:deepslate_gold_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAgAACAQAbmFtZRwAbWluZWNyYWZ0OmRlZXBzbGF0ZV9nb2xkX29yZQQJAG5hbWVfaGFzaF9G7WYhKFinAwoAbmV0d29ya19pZAUsAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:deepslate_diamond_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSUAgAACAQAbmFtZR8AbWluZWNyYWZ0OmRlZXBzbGF0ZV9kaWFtb25kX29yZQQJAG5hbWVfaGFzaEUH5USh+iD3AwoAbmV0d29ya19pZPk1AAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:deepslate_lapis_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSPAgAACAQAbmFtZR0AbWluZWNyYWZ0OmRlZXBzbGF0ZV9sYXBpc19vcmUECQBuYW1lX2hhc2j+yFxU/KZs1gMKAG5ldHdvcmtfaWSKMgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:deepslate_redstone_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSSAgAACAQAbmFtZSAAbWluZWNyYWZ0OmRlZXBzbGF0ZV9yZWRzdG9uZV9vcmUECQBuYW1lX2hhc2iVgM3wWWD6ugMKAG5ldHdvcmtfaWQxLgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:deepslate_emerald_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSWAgAACAQAbmFtZR8AbWluZWNyYWZ0OmRlZXBzbGF0ZV9lbWVyYWxkX29yZQQJAG5hbWVfaGFzaNlfo5HTwS6wAwoAbmV0d29ya19pZOosAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:deepslate_coal_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSVAgAACAQAbmFtZRwAbWluZWNyYWZ0OmRlZXBzbGF0ZV9jb2FsX29yZQQJAG5hbWVfaGFzaIjikmcbRrPPAwoAbmV0d29ya19pZDQyAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:deepslate_copper_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSXAgAACAQAbmFtZR4AbWluZWNyYWZ0OmRlZXBzbGF0ZV9jb3BwZXJfb3JlBAkAbmFtZV9oYXNottjV4Ev5LAQDCgBuZXR3b3JrX2lkcgAAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:gravel", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQNAAAACAQAbmFtZRAAbWluZWNyYWZ0OmdyYXZlbAQJAG5hbWVfaGFzaOFxz8XJd2r/AwoAbmV0d29ya19pZBM3AAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:granite", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRNAwAACAQAbmFtZREAbWluZWNyYWZ0OmdyYW5pdGUECQBuYW1lX2hhc2iq+Dur2pw4AwMKAG5ldHdvcmtfaWRTAAAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:diorite", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRPAwAACAQAbmFtZREAbWluZWNyYWZ0OmRpb3JpdGUECQBuYW1lX2hhc2iaFsq2iinZBQMKAG5ldHdvcmtfaWSVAAAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:andesite", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRRAwAACAQAbmFtZRIAbWluZWNyYWZ0OmFuZGVzaXRlBAkAbmFtZV9oYXNosaLIEnQQoSYDCgBuZXR3b3JrX2lk8gYAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:blackstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQQAgAACAQAbmFtZRQAbWluZWNyYWZ0OmJsYWNrc3RvbmUECQBuYW1lX2hhc2iMFYziD80D6QMKAG5ldHdvcmtfaWTlMwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:deepslate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR5AgAACAQAbmFtZRMAbWluZWNyYWZ0OmRlZXBzbGF0ZQQJAG5hbWVfaGFzaKX5pAblxz8TAwoAbmV0d29ya19pZKkCAAAKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:polished_granite", - "block_state_b64": "CgAAAwgAYmxvY2tfaWROAwAACAQAbmFtZRoAbWluZWNyYWZ0OnBvbGlzaGVkX2dyYW5pdGUECQBuYW1lX2hhc2iLiEfys8pFIAMKAG5ldHdvcmtfaWSDBAAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:polished_diorite", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRQAwAACAQAbmFtZRoAbWluZWNyYWZ0OnBvbGlzaGVkX2Rpb3JpdGUECQBuYW1lX2hhc2hTxY4fKmNmlAMKAG5ldHdvcmtfaWQzJwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:polished_andesite", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRSAwAACAQAbmFtZRsAbWluZWNyYWZ0OnBvbGlzaGVkX2FuZGVzaXRlBAkAbmFtZV9oYXNovl28uFk4HuQDCgBuZXR3b3JrX2lkujMAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:polished_blackstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQiAgAACAQAbmFtZR0AbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmUECQBuYW1lX2hhc2jT9fHCl6vWQQMKAG5ldHdvcmtfaWS6FwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:polished_deepslate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR+AgAACAQAbmFtZRwAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZQQJAG5hbWVfaGFzaHC1edoaWF3uAwoAbmV0d29ya19pZJY0AAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:sand", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQMAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnNhbmQECQBuYW1lX2hhc2i6lthXXbAyWAMKAG5ldHdvcmtfaWRQGwAACgYAc3RhdGVzCAkAc2FuZF90eXBlBgBub3JtYWwAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:sand", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQMAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnNhbmQECQBuYW1lX2hhc2i6lthXXbAyWAMKAG5ldHdvcmtfaWRRGwAACgYAc3RhdGVzCAkAc2FuZF90eXBlAwByZWQAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:cactus", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRRAAAACAQAbmFtZRAAbWluZWNyYWZ0OmNhY3R1cwQJAG5hbWVfaGFzaCG9zL0N4wvGAwoAbmV0d29ya19pZKsvAAAKBgBzdGF0ZXMDAwBhZ2UAAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:oak_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQRAAAACAQAbmFtZREAbWluZWNyYWZ0Om9ha19sb2cECQBuYW1lX2hhc2ho6TS+K7PZFQMKAG5ldHdvcmtfaWTbAgAACgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:stripped_oak_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQJAQAACAQAbmFtZRoAbWluZWNyYWZ0OnN0cmlwcGVkX29ha19sb2cECQBuYW1lX2hhc2h8dqh+OOHU4wMKAG5ldHdvcmtfaWS3MwAACgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:spruce_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ4AwAACAQAbmFtZRQAbWluZWNyYWZ0OnNwcnVjZV9sb2cECQBuYW1lX2hhc2hZ03qaLoF3WgMKAG5ldHdvcmtfaWSbGwAACgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:stripped_spruce_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQEAQAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX3NwcnVjZV9sb2cECQBuYW1lX2hhc2iNrhKjS5IyrgMKAG5ldHdvcmtfaWSnLAAACgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:birch_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ5AwAACAQAbmFtZRMAbWluZWNyYWZ0OmJpcmNoX2xvZwQJAG5hbWVfaGFzaBUzT3NxsZAnAwoAbmV0d29ya19pZPUGAAAKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:stripped_birch_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQFAQAACAQAbmFtZRwAbWluZWNyYWZ0OnN0cmlwcGVkX2JpcmNoX2xvZwQJAG5hbWVfaGFzaCFKS4AeuSidAwoAbmV0d29ya19pZNYpAAAKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:jungle_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ6AwAACAQAbmFtZRQAbWluZWNyYWZ0Omp1bmdsZV9sb2cECQBuYW1lX2hhc2gkwW0KNulqDgMKAG5ldHdvcmtfaWR/AgAACgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:stripped_jungle_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAQAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2p1bmdsZV9sb2cECQBuYW1lX2hhc2hAwMsgOk02JAMKAG5ldHdvcmtfaWTnBgAACgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:acacia_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSiAAAACAQAbmFtZRQAbWluZWNyYWZ0OmFjYWNpYV9sb2cECQBuYW1lX2hhc2iV48VpYhjoYQMKAG5ldHdvcmtfaWQEHAAACgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:stripped_acacia_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQHAQAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2FjYWNpYV9sb2cECQBuYW1lX2hhc2hJb0lQqnEqlgMKAG5ldHdvcmtfaWRoJwAACgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:dark_oak_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ7AwAACAQAbmFtZRYAbWluZWNyYWZ0OmRhcmtfb2FrX2xvZwQJAG5hbWVfaGFzaIWfVRd0XUo3AwoAbmV0d29ya19pZCsTAAAKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:stripped_dark_oak_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQIAQAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX2Rhcmtfb2FrX2xvZwQJAG5hbWVfaGFzaPFTdxRdPwkOAwoAbmV0d29ya19pZHsCAAAKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:mangrove_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTjAgAACAQAbmFtZRYAbWluZWNyYWZ0Om1hbmdyb3ZlX2xvZwQJAG5hbWVfaGFzaHZe6DzPZBobAwoAbmV0d29ya19pZEcEAAAKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:stripped_mangrove_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTkAgAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX21hbmdyb3ZlX2xvZwQJAG5hbWVfaGFzaLqIBo4hwA//AwoAbmV0d29ya19pZBA3AAAKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:cherry_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQXAwAACAQAbmFtZRQAbWluZWNyYWZ0OmNoZXJyeV9sb2cECQBuYW1lX2hhc2hwFlaioppB1wMKAG5ldHdvcmtfaWSOMgAACgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:stripped_cherry_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQWAwAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2NoZXJyeV9sb2cECQBuYW1lX2hhc2i85H6G+WhXaAMKAG5ldHdvcmtfaWR0HAAACgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:crimson_stem", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTgAQAACAQAbmFtZRYAbWluZWNyYWZ0OmNyaW1zb25fc3RlbQQJAG5hbWVfaGFzaM0FzfL0UTKZAwoAbmV0d29ya19pZDopAAAKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:stripped_crimson_stem", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTvAQAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX2NyaW1zb25fc3RlbQQJAG5hbWVfaGFzaDlA6nood57EAwoAbmV0d29ya19pZIQvAAAKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:warped_stem", - "block_state_b64": "CgAAAwgAYmxvY2tfaWThAQAACAQAbmFtZRUAbWluZWNyYWZ0OndhcnBlZF9zdGVtBAkAbmFtZV9oYXNon7cKfPZxdrUDCgBuZXR3b3JrX2lkoi0AAAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:stripped_warped_stem", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTwAQAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX3dhcnBlZF9zdGVtBAkAbmFtZV9oYXNoEw+y0dDPSd8DCgBuZXR3b3JrX2lkIjMAAAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAQAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWQuEwAACgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQACAkAd29vZF90eXBlAwBvYWsAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAQAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWQ0EwAACgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQBCAkAd29vZF90eXBlAwBvYWsAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAQAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWQvEwAACgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQACAkAd29vZF90eXBlBgBzcHJ1Y2UAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAQAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWQ1EwAACgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQBCAkAd29vZF90eXBlBgBzcHJ1Y2UAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAQAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWQwEwAACgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQACAkAd29vZF90eXBlBQBiaXJjaAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAQAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWQ2EwAACgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQBCAkAd29vZF90eXBlBQBiaXJjaAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAQAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWQxEwAACgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQACAkAd29vZF90eXBlBgBqdW5nbGUAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAQAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWQ3EwAACgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQBCAkAd29vZF90eXBlBgBqdW5nbGUAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAQAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWQyEwAACgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQACAkAd29vZF90eXBlBgBhY2FjaWEAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAQAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWQ4EwAACgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQBCAkAd29vZF90eXBlBgBhY2FjaWEAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAQAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWQzEwAACgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQACAkAd29vZF90eXBlCABkYXJrX29hawADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAQAACAQAbmFtZQ4AbWluZWNyYWZ0Ondvb2QECQBuYW1lX2hhc2gbHdJFXQ1vNwMKAG5ldHdvcmtfaWQ5EwAACgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQBCAkAd29vZF90eXBlCABkYXJrX29hawADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:mangrove_wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTwAgAACAQAbmFtZRcAbWluZWNyYWZ0Om1hbmdyb3ZlX3dvb2QECQBuYW1lX2hhc2iXVxG0JG2fVAMKAG5ldHdvcmtfaWQlGwAACgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:stripped_mangrove_wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTxAgAACAQAbmFtZSAAbWluZWNyYWZ0OnN0cmlwcGVkX21hbmdyb3ZlX3dvb2QECQBuYW1lX2hhc2h7CkbaBF7/WAMKAG5ldHdvcmtfaWRyGwAACgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:cherry_wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQhAwAACAQAbmFtZRUAbWluZWNyYWZ0OmNoZXJyeV93b29kBAkAbmFtZV9oYXNoAW8srlmpBM8DCgBuZXR3b3JrX2lkWjAAAAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AQwAc3RyaXBwZWRfYml0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:stripped_cherry_wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQgAwAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX2NoZXJyeV93b29kBAkAbmFtZV9oYXNo/e7KXv+CB38DCgBuZXR3b3JrX2lktiEAAAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:crimson_hyphae", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQqAgAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25faHlwaGFlBAkAbmFtZV9oYXNouRmKmfSqEWADCgBuZXR3b3JrX2lk2xsAAAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:stripped_crimson_hyphae", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQrAgAACAQAbmFtZSEAbWluZWNyYWZ0OnN0cmlwcGVkX2NyaW1zb25faHlwaGFlBAkAbmFtZV9oYXNoFffwmABq4LUDCgBuZXR3b3JrX2lkpi0AAAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:warped_hyphae", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQpAgAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9oeXBoYWUECQBuYW1lX2hhc2hn8plQUr6pmQMKAG5ldHdvcmtfaWRCKQAACgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:stripped_warped_hyphae", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAgAACAQAbmFtZSAAbWluZWNyYWZ0OnN0cmlwcGVkX3dhcnBlZF9oeXBoYWUECQBuYW1lX2hhc2irKq+HYPSgjQMKAG5ldHdvcmtfaWSzJAAACgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:bamboo_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQOAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJhbWJvb19ibG9jawQJAG5hbWVfaGFzaAbDeur6stIBAwoAbmV0d29ya19pZD8AAAAKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:stripped_bamboo_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQPAwAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX2JhbWJvb19ibG9jawQJAG5hbWVfaGFzaJpwytpZOZM9AwoAbmV0d29ya19pZF4XAAAKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:leaves", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQSAAAACAQAbmFtZRAAbWluZWNyYWZ0OmxlYXZlcwQJAG5hbWVfaGFzaACPIsusW0mnAwoAbmV0d29ya19pZPUrAAAKBgBzdGF0ZXMIDQBvbGRfbGVhZl90eXBlAwBvYWsBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:leaves", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQSAAAACAQAbmFtZRAAbWluZWNyYWZ0OmxlYXZlcwQJAG5hbWVfaGFzaACPIsusW0mnAwoAbmV0d29ya19pZPYrAAAKBgBzdGF0ZXMIDQBvbGRfbGVhZl90eXBlBgBzcHJ1Y2UBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:leaves", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQSAAAACAQAbmFtZRAAbWluZWNyYWZ0OmxlYXZlcwQJAG5hbWVfaGFzaACPIsusW0mnAwoAbmV0d29ya19pZPcrAAAKBgBzdGF0ZXMIDQBvbGRfbGVhZl90eXBlBQBiaXJjaAEOAHBlcnNpc3RlbnRfYml0AAEKAHVwZGF0ZV9iaXQAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:leaves", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQSAAAACAQAbmFtZRAAbWluZWNyYWZ0OmxlYXZlcwQJAG5hbWVfaGFzaACPIsusW0mnAwoAbmV0d29ya19pZPgrAAAKBgBzdGF0ZXMIDQBvbGRfbGVhZl90eXBlBgBqdW5nbGUBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:leaves2", - "block_state_b64": "CgAAAwgAYmxvY2tfaWShAAAACAQAbmFtZREAbWluZWNyYWZ0OmxlYXZlczIECQBuYW1lX2hhc2gy/bgrncY1ZAMKAG5ldHdvcmtfaWQdHAAACgYAc3RhdGVzCA0AbmV3X2xlYWZfdHlwZQYAYWNhY2lhAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:leaves2", - "block_state_b64": "CgAAAwgAYmxvY2tfaWShAAAACAQAbmFtZREAbWluZWNyYWZ0OmxlYXZlczIECQBuYW1lX2hhc2gy/bgrncY1ZAMKAG5ldHdvcmtfaWQeHAAACgYAc3RhdGVzCA0AbmV3X2xlYWZfdHlwZQgAZGFya19vYWsBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:mangrove_leaves", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTXAgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX2xlYXZlcwQJAG5hbWVfaGFzaKyI/dWvhEG8AwoAbmV0d29ya19pZGUuAAAKBgBzdGF0ZXMBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:cherry_leaves", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQjAwAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9sZWF2ZXMECQBuYW1lX2hhc2giTs9ChhYBlQMKAG5ldHdvcmtfaWQ2JwAACgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:azalea_leaves", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRDAgAACAQAbmFtZRcAbWluZWNyYWZ0OmF6YWxlYV9sZWF2ZXMECQBuYW1lX2hhc2iXFhD57wFS7AMKAG5ldHdvcmtfaWRiNAAACgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:azalea_leaves_flowered", - "block_state_b64": "CgAAAwgAYmxvY2tfaWREAgAACAQAbmFtZSAAbWluZWNyYWZ0OmF6YWxlYV9sZWF2ZXNfZmxvd2VyZWQECQBuYW1lX2hhc2gs8jxlS/pMrwMKAG5ldHdvcmtfaWTeLAAACgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:sapling", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAAAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWRjCAAACgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUDAG9hawADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:sapling", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAAAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWRkCAAACgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUGAHNwcnVjZQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:sapling", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAAAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWRlCAAACgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUFAGJpcmNoAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:sapling", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAAAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWRmCAAACgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUGAGp1bmdsZQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:sapling", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAAAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWRnCAAACgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUGAGFjYWNpYQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:sapling", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAAAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWRoCAAACgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUIAGRhcmtfb2FrAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:mangrove_propagule", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTZAgAACAQAbmFtZRwAbWluZWNyYWZ0Om1hbmdyb3ZlX3Byb3BhZ3VsZQQJAG5hbWVfaGFzaJGeox6hkfLFAwoAbmV0d29ya19pZKEvAAAKBgBzdGF0ZXMBBwBoYW5naW5nAAMPAHByb3BhZ3VsZV9zdGFnZQAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:cherry_sapling", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQiAwAACAQAbmFtZRgAbWluZWNyYWZ0OmNoZXJyeV9zYXBsaW5nBAkAbmFtZV9oYXNoGrPpNMf1LtcDCgBuZXR3b3JrX2lkjDIAAAoGAHN0YXRlcwEHAGFnZV9iaXQAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:bee_nest", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTZAQAACAQAbmFtZRIAbWluZWNyYWZ0OmJlZV9uZXN0BAkAbmFtZV9oYXNo2R2WBxUHEZIDCgBuZXR3b3JrX2lkZCUAAAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAADCwBob25leV9sZXZlbAAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:wheat_seeds" - }, - { - "id": "minecraft:pumpkin_seeds" - }, - { - "id": "minecraft:melon_seeds" - }, - { - "id": "minecraft:beetroot_seeds" - }, - { - "id": "minecraft:torchflower_seeds" - }, - { - "id": "minecraft:pitcher_pod" - }, - { - "id": "minecraft:wheat" - }, - { - "id": "minecraft:beetroot" - }, - { - "id": "minecraft:potato" - }, - { - "id": "minecraft:poisonous_potato" - }, - { - "id": "minecraft:carrot" - }, - { - "id": "minecraft:golden_carrot" - }, - { - "id": "minecraft:apple" - }, - { - "id": "minecraft:golden_apple" - }, - { - "id": "minecraft:enchanted_golden_apple" - }, - { - "id": "minecraft:melon_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRnAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1lbG9uX2Jsb2NrBAkAbmFtZV9oYXNoXxSm0iYpAx8DCgBuZXR3b3JrX2lkeAQAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:melon_slice" - }, - { - "id": "minecraft:glistering_melon_slice" - }, - { - "id": "minecraft:sweet_berries" - }, - { - "id": "minecraft:glow_berries" - }, - { - "id": "minecraft:pumpkin", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRWAAAACAQAbmFtZREAbWluZWNyYWZ0OnB1bXBraW4ECQBuYW1lX2hhc2gc8A3jaSzWbgMKAG5ldHdvcmtfaWQNHQAACgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:carved_pumpkin", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSaAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNhcnZlZF9wdW1wa2luBAkAbmFtZV9oYXNoPu1T0MJuG90DCgBuZXR3b3JrX2lkDDMAAAoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:lit_pumpkin", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRbAAAACAQAbmFtZRUAbWluZWNyYWZ0OmxpdF9wdW1wa2luBAkAbmFtZV9oYXNo7gWtEm2uPL0DCgBuZXR3b3JrX2lkbC4AAAoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:honeycomb" - }, - { - "id": "minecraft:tallgrass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQfAAAACAQAbmFtZRMAbWluZWNyYWZ0OnRhbGxncmFzcwQJAG5hbWVfaGFzaC3PXpAXXYswAwoAbmV0d29ya19pZFUJAAAKBgBzdGF0ZXMIDwB0YWxsX2dyYXNzX3R5cGUEAGZlcm4AAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:double_plant", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZBYkAAAKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQQAZmVybgEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:tallgrass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQfAAAACAQAbmFtZRMAbWluZWNyYWZ0OnRhbGxncmFzcwQJAG5hbWVfaGFzaC3PXpAXXYswAwoAbmV0d29ya19pZFQJAAAKBgBzdGF0ZXMIDwB0YWxsX2dyYXNzX3R5cGUEAHRhbGwAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:double_plant", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZBUkAAAKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQUAZ3Jhc3MBDwB1cHBlcl9ibG9ja19iaXQAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:nether_sprouts" - }, - { - "id": "minecraft:fire_coral", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRGAwAACAQAbmFtZRQAbWluZWNyYWZ0OmZpcmVfY29yYWwECQBuYW1lX2hhc2hOHyyECVQVJwMKAG5ldHdvcmtfaWTzBgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:brain_coral", - "block_state_b64": "CgAAAwgAYmxvY2tfaWREAwAACAQAbmFtZRUAbWluZWNyYWZ0OmJyYWluX2NvcmFsBAkAbmFtZV9oYXNoRiWlLCwA2ycDCgBuZXR3b3JrX2lkmwcAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:bubble_coral", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRFAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJ1YmJsZV9jb3JhbAQJAG5hbWVfaGFzaJz6rWnl+v2qAwoAbmV0d29ya19pZGcsAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:tube_coral", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSCAQAACAQAbmFtZRQAbWluZWNyYWZ0OnR1YmVfY29yYWwECQBuYW1lX2hhc2iYa8oO/tgk7wMKAG5ldHdvcmtfaWShNAAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:horn_coral", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRHAwAACAQAbmFtZRQAbWluZWNyYWZ0Omhvcm5fY29yYWwECQBuYW1lX2hhc2iZnRHjZbnLPgMKAG5ldHdvcmtfaWR0FwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:dead_fire_coral", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRLAwAACAQAbmFtZRkAbWluZWNyYWZ0OmRlYWRfZmlyZV9jb3JhbAQJAG5hbWVfaGFzaEPU6tFy/latAwoAbmV0d29ya19pZJ4sAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:dead_brain_coral", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRJAwAACAQAbmFtZRoAbWluZWNyYWZ0OmRlYWRfYnJhaW5fY29yYWwECQBuYW1lX2hhc2j5L6QJCISvzwMKAG5ldHdvcmtfaWQzMgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:dead_bubble_coral", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRKAwAACAQAbmFtZRsAbWluZWNyYWZ0OmRlYWRfYnViYmxlX2NvcmFsBAkAbmFtZV9oYXNoSTOZ/8wpeNYDCgBuZXR3b3JrX2lkizIAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:dead_tube_coral", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRIAwAACAQAbmFtZRkAbWluZWNyYWZ0OmRlYWRfdHViZV9jb3JhbAQJAG5hbWVfaGFzaJGjNWhlaIJeAwoAbmV0d29ya19pZLkbAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:dead_horn_coral", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRMAwAACAQAbmFtZRkAbWluZWNyYWZ0OmRlYWRfaG9ybl9jb3JhbAQJAG5hbWVfaGFzaJBkz3qt+g2cAwoAbmV0d29ya19pZHopAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:coral_fan", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAQAACAQAbmFtZRMAbWluZWNyYWZ0OmNvcmFsX2ZhbgQJAG5hbWVfaGFzaAFROjbTm8JzAwoAbmV0d29ya19pZEkdAAAKBgBzdGF0ZXMICwBjb3JhbF9jb2xvcgMAcmVkAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:coral_fan", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAQAACAQAbmFtZRMAbWluZWNyYWZ0OmNvcmFsX2ZhbgQJAG5hbWVfaGFzaAFROjbTm8JzAwoAbmV0d29ya19pZEcdAAAKBgBzdGF0ZXMICwBjb3JhbF9jb2xvcgQAcGluawMTAGNvcmFsX2Zhbl9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:coral_fan", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAQAACAQAbmFtZRMAbWluZWNyYWZ0OmNvcmFsX2ZhbgQJAG5hbWVfaGFzaAFROjbTm8JzAwoAbmV0d29ya19pZEgdAAAKBgBzdGF0ZXMICwBjb3JhbF9jb2xvcgYAcHVycGxlAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:coral_fan", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAQAACAQAbmFtZRMAbWluZWNyYWZ0OmNvcmFsX2ZhbgQJAG5hbWVfaGFzaAFROjbTm8JzAwoAbmV0d29ya19pZEYdAAAKBgBzdGF0ZXMICwBjb3JhbF9jb2xvcgQAYmx1ZQMTAGNvcmFsX2Zhbl9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:coral_fan", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAQAACAQAbmFtZRMAbWluZWNyYWZ0OmNvcmFsX2ZhbgQJAG5hbWVfaGFzaAFROjbTm8JzAwoAbmV0d29ya19pZEodAAAKBgBzdGF0ZXMICwBjb3JhbF9jb2xvcgYAeWVsbG93AxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:coral_fan_dead", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNvcmFsX2Zhbl9kZWFkBAkAbmFtZV9oYXNo3kgokLV4uQIDCgBuZXR3b3JrX2lkTAAAAAoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yAwByZWQDEwBjb3JhbF9mYW5fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:coral_fan_dead", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNvcmFsX2Zhbl9kZWFkBAkAbmFtZV9oYXNo3kgokLV4uQIDCgBuZXR3b3JrX2lkSgAAAAoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABwaW5rAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:coral_fan_dead", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNvcmFsX2Zhbl9kZWFkBAkAbmFtZV9oYXNo3kgokLV4uQIDCgBuZXR3b3JrX2lkSwAAAAoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgBwdXJwbGUDEwBjb3JhbF9mYW5fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:coral_fan_dead", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNvcmFsX2Zhbl9kZWFkBAkAbmFtZV9oYXNo3kgokLV4uQIDCgBuZXR3b3JrX2lkSQAAAAoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABibHVlAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:coral_fan_dead", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNvcmFsX2Zhbl9kZWFkBAkAbmFtZV9oYXNo3kgokLV4uQIDCgBuZXR3b3JrX2lkTQAAAAoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgB5ZWxsb3cDEwBjb3JhbF9mYW5fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:crimson_roots", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTeAQAACAQAbmFtZRcAbWluZWNyYWZ0OmNyaW1zb25fcm9vdHMECQBuYW1lX2hhc2j1fWgQLViv5QMKAG5ldHdvcmtfaWTYMwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:warped_roots", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTfAQAACAQAbmFtZRYAbWluZWNyYWZ0OndhcnBlZF9yb290cwQJAG5hbWVfaGFzaBc3WvbJOLlkAwoAbmV0d29ya19pZCgcAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:yellow_flower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQlAAAACAQAbmFtZRcAbWluZWNyYWZ0OnllbGxvd19mbG93ZXIECQBuYW1lX2hhc2jWbU1pF0OUGAMKAG5ldHdvcmtfaWQVBAAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWR3FwAACgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUFAHBvcHB5AAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWR4FwAACgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUGAG9yY2hpZAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWR5FwAACgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUGAGFsbGl1bQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWR6FwAACgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUJAGhvdXN0b25pYQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWR7FwAACgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUJAHR1bGlwX3JlZAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWR8FwAACgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUMAHR1bGlwX29yYW5nZQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWR9FwAACgYAc3RhdGVzCAsAZmxvd2VyX3R5cGULAHR1bGlwX3doaXRlAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWR+FwAACgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUKAHR1bGlwX3BpbmsAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWR/FwAACgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUFAG94ZXllAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWSAFwAACgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUKAGNvcm5mbG93ZXIAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:red_flower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWSBFwAACgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUSAGxpbHlfb2ZfdGhlX3ZhbGxleQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:double_plant", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZBMkAAAKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQkAc3VuZmxvd2VyAQ8AdXBwZXJfYmxvY2tfYml0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:double_plant", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZBQkAAAKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQcAc3lyaW5nYQEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:double_plant", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZBckAAAKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQQAcm9zZQEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:double_plant", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZBgkAAAKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQcAcGFlb25pYQEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:pitcher_plant", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAwAACAQAbmFtZRcAbWluZWNyYWZ0OnBpdGNoZXJfcGxhbnQECQBuYW1lX2hhc2hRJHzsbDH+SQMKAG5ldHdvcmtfaWQPGAAACgYAc3RhdGVzAQ8AdXBwZXJfYmxvY2tfYml0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:pink_petals", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQkAwAACAQAbmFtZRUAbWluZWNyYWZ0OnBpbmtfcGV0YWxzBAkAbmFtZV9oYXNo6DQwN9SwV3QDCgBuZXR3b3JrX2lkbh0AAAoGAHN0YXRlcwMGAGdyb3d0aAAAAAAIHABtaW5lY3JhZnQ6Y2FyZGluYWxfZGlyZWN0aW9uBQBzb3V0aAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:wither_rose", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTXAQAACAQAbmFtZRUAbWluZWNyYWZ0OndpdGhlcl9yb3NlBAkAbmFtZV9oYXNoaSKxl3I516gDCgBuZXR3b3JrX2lkQSwAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:torchflower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ3AwAACAQAbmFtZRUAbWluZWNyYWZ0OnRvcmNoZmxvd2VyBAkAbmFtZV9oYXNoL+mHtElwbqQDCgBuZXR3b3JrX2lkxisAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:white_dye" - }, - { - "id": "minecraft:light_gray_dye" - }, - { - "id": "minecraft:gray_dye" - }, - { - "id": "minecraft:black_dye" - }, - { - "id": "minecraft:brown_dye" - }, - { - "id": "minecraft:red_dye" - }, - { - "id": "minecraft:orange_dye" - }, - { - "id": "minecraft:yellow_dye" - }, - { - "id": "minecraft:lime_dye" - }, - { - "id": "minecraft:green_dye" - }, - { - "id": "minecraft:cyan_dye" - }, - { - "id": "minecraft:light_blue_dye" - }, - { - "id": "minecraft:blue_dye" - }, - { - "id": "minecraft:purple_dye" - }, - { - "id": "minecraft:magenta_dye" - }, - { - "id": "minecraft:pink_dye" - }, - { - "id": "minecraft:ink_sac" - }, - { - "id": "minecraft:glow_ink_sac" - }, - { - "id": "minecraft:cocoa_beans" - }, - { - "id": "minecraft:lapis_lazuli" - }, - { - "id": "minecraft:bone_meal" - }, - { - "id": "minecraft:vine", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRqAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnZpbmUECQBuYW1lX2hhc2j0Sj8/XeXOLAMKAG5ldHdvcmtfaWQhCQAACgYAc3RhdGVzAxMAdmluZV9kaXJlY3Rpb25fYml0cwAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:weeping_vines", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTmAQAACAQAbmFtZRcAbWluZWNyYWZ0OndlZXBpbmdfdmluZXMECQBuYW1lX2hhc2jrLgLHkQygiwMKAG5ldHdvcmtfaWRPJAAACgYAc3RhdGVzAxEAd2VlcGluZ192aW5lc19hZ2UAAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:twisting_vines", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQeAgAACAQAbmFtZRgAbWluZWNyYWZ0OnR3aXN0aW5nX3ZpbmVzBAkAbmFtZV9oYXNoDYR5QgVUQJADCgBuZXR3b3JrX2lkIiUAAAoGAHN0YXRlcwMSAHR3aXN0aW5nX3ZpbmVzX2FnZQAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:waterlily", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRvAAAACAQAbmFtZRMAbWluZWNyYWZ0OndhdGVybGlseQQJAG5hbWVfaGFzaEHgC4c1SXg0AwoAbmV0d29ya19pZCIKAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:seagrass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSBAQAACAQAbmFtZRIAbWluZWNyYWZ0OnNlYWdyYXNzBAkAbmFtZV9oYXNoHSBFtoHdWxIDCgBuZXR3b3JrX2lkogIAAAoGAHN0YXRlcwgOAHNlYV9ncmFzc190eXBlBwBkZWZhdWx0AAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:kelp" - }, - { - "id": "minecraft:deadbush", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQgAAAACAQAbmFtZRIAbWluZWNyYWZ0OmRlYWRidXNoBAkAbmFtZV9oYXNoPFODe4IScnYDCgBuZXR3b3JrX2lkMh8AAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:bamboo", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSiAQAACAQAbmFtZRAAbWluZWNyYWZ0OmJhbWJvbwQJAG5hbWVfaGFzaBgpGmyzhedCAwoAbmV0d29ya19pZLwXAAAKBgBzdGF0ZXMBBwBhZ2VfYml0AAgQAGJhbWJvb19sZWFmX3NpemUJAG5vX2xlYXZlcwgWAGJhbWJvb19zdGFsa190aGlja25lc3MEAHRoaW4AAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:snow", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRQAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnNub3cECQBuYW1lX2hhc2gVHr5XXdETWAMKAG5ldHdvcmtfaWRPGwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:ice", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRPAAAACAQAbmFtZQ0AbWluZWNyYWZ0OmljZQQJAG5hbWVfaGFzaNF26f+uUT29AwoAbmV0d29ya19pZHAuAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:packed_ice", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSuAAAACAQAbmFtZRQAbWluZWNyYWZ0OnBhY2tlZF9pY2UECQBuYW1lX2hhc2hk4bu123ZrFgMKAG5ldHdvcmtfaWThAgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:blue_ice", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQKAQAACAQAbmFtZRIAbWluZWNyYWZ0OmJsdWVfaWNlBAkAbmFtZV9oYXNo+EKxYgFhKcgDCgBuZXR3b3JrX2lk2C8AAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:snow_layer", - "block_state_b64": "CgAAAwgAYmxvY2tfaWROAAAACAQAbmFtZRQAbWluZWNyYWZ0OnNub3dfbGF5ZXIECQBuYW1lX2hhc2hXka6atMYUCQMKAG5ldHdvcmtfaWQ9AgAACgYAc3RhdGVzAQsAY292ZXJlZF9iaXQAAwYAaGVpZ2h0AAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:pointed_dripstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQzAgAACAQAbmFtZRsAbWluZWNyYWZ0OnBvaW50ZWRfZHJpcHN0b25lBAkAbmFtZV9oYXNoJMISzmHQgt8DCgBuZXR3b3JrX2lkMjMAAAoGAHN0YXRlcwgTAGRyaXBzdG9uZV90aGlja25lc3MDAHRpcAEHAGhhbmdpbmcBAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:dripstone_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ8AgAACAQAbmFtZRkAbWluZWNyYWZ0OmRyaXBzdG9uZV9ibG9jawQJAG5hbWVfaGFzaIIXnEqY77YsAwoAbmV0d29ya19pZCAJAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:moss_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWROAgAACAQAbmFtZRUAbWluZWNyYWZ0Om1vc3NfY2FycGV0BAkAbmFtZV9oYXNo/NEDxRPTshYDCgBuZXR3b3JrX2lk5QIAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:moss_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ/AgAACAQAbmFtZRQAbWluZWNyYWZ0Om1vc3NfYmxvY2sECQBuYW1lX2hhc2iovcsPUYX2tgMKAG5ldHdvcmtfaWTgLQAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:dirt_with_roots", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ9AgAACAQAbmFtZRkAbWluZWNyYWZ0OmRpcnRfd2l0aF9yb290cwQJAG5hbWVfaGFzaLCNDYPviDCIAwoAbmV0d29ya19pZNsjAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:hanging_roots", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ+AgAACAQAbmFtZRcAbWluZWNyYWZ0Omhhbmdpbmdfcm9vdHMECQBuYW1lX2hhc2jaXn+Y5UZpDAMKAG5ldHdvcmtfaWRwAgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:mangrove_roots", - "block_state_b64": "CgAAAwgAYmxvY2tfaWThAgAACAQAbmFtZRgAbWluZWNyYWZ0Om1hbmdyb3ZlX3Jvb3RzBAkAbmFtZV9oYXNoa786PzQGZ6kDCgBuZXR3b3JrX2lkSywAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:muddy_mangrove_roots", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTiAgAACAQAbmFtZR4AbWluZWNyYWZ0Om11ZGR5X21hbmdyb3ZlX3Jvb3RzBAkAbmFtZV9oYXNo9YApdHpo1RkDCgBuZXR3b3JrX2lkQgQAAAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:big_dripleaf", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRCAgAACAQAbmFtZRYAbWluZWNyYWZ0OmJpZ19kcmlwbGVhZgQJAG5hbWVfaGFzaGBEhXjo6qSdAwoAbmV0d29ya19pZN4pAAAKBgBzdGF0ZXMBEQBiaWdfZHJpcGxlYWZfaGVhZAEIEQBiaWdfZHJpcGxlYWZfdGlsdAQAbm9uZQgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:small_dripleaf_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRPAgAACAQAbmFtZR4AbWluZWNyYWZ0OnNtYWxsX2RyaXBsZWFmX2Jsb2NrBAkAbmFtZV9oYXNojxRAgXP9uWADCgBuZXR3b3JrX2lk9RsAAAoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24EAGVhc3QBDwB1cHBlcl9ibG9ja19iaXQBAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:spore_blossom", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRAAgAACAQAbmFtZRcAbWluZWNyYWZ0OnNwb3JlX2Jsb3Nzb20ECQBuYW1lX2hhc2il3U72Gbco2gMKAG5ldHdvcmtfaWTNMgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:azalea", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRQAgAACAQAbmFtZRAAbWluZWNyYWZ0OmF6YWxlYQQJAG5hbWVfaGFzaNyUl+BW9JrBAwoAbmV0d29ya19pZEAvAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:flowering_azalea", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRRAgAACAQAbmFtZRoAbWluZWNyYWZ0OmZsb3dlcmluZ19hemFsZWEECQBuYW1lX2hhc2ie9r33wz8kiwMKAG5ldHdvcmtfaWRMJAAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:glow_lichen", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSaAgAACAQAbmFtZRUAbWluZWNyYWZ0Omdsb3dfbGljaGVuBAkAbmFtZV9oYXNobyPUrIYlo44DCgBuZXR3b3JrX2lkGyUAAAoGAHN0YXRlcwMZAG11bHRpX2ZhY2VfZGlyZWN0aW9uX2JpdHM/AAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:amethyst_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRGAgAACAQAbmFtZRgAbWluZWNyYWZ0OmFtZXRoeXN0X2Jsb2NrBAkAbmFtZV9oYXNob+JK1iiAthcDCgBuZXR3b3JrX2lkCQMAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:budding_amethyst", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRHAgAACAQAbmFtZRoAbWluZWNyYWZ0OmJ1ZGRpbmdfYW1ldGh5c3QECQBuYW1lX2hhc2gJvAwfI14fxgMKAG5ldHdvcmtfaWS7LwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:amethyst_cluster", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRIAgAACAQAbmFtZRoAbWluZWNyYWZ0OmFtZXRoeXN0X2NsdXN0ZXIECQBuYW1lX2hhc2jK82S88Jgm8wMKAG5ldHdvcmtfaWQgNQAACgYAc3RhdGVzCBQAbWluZWNyYWZ0OmJsb2NrX2ZhY2UCAHVwAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:large_amethyst_bud", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRJAgAACAQAbmFtZRwAbWluZWNyYWZ0OmxhcmdlX2FtZXRoeXN0X2J1ZAQJAG5hbWVfaGFzaAHhdpWD+sd5AwoAbmV0d29ya19pZGUfAAAKBgBzdGF0ZXMIFABtaW5lY3JhZnQ6YmxvY2tfZmFjZQIAdXAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:medium_amethyst_bud", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRKAgAACAQAbmFtZR0AbWluZWNyYWZ0Om1lZGl1bV9hbWV0aHlzdF9idWQECQBuYW1lX2hhc2g5lBGtC0DzZQMKAG5ldHdvcmtfaWQ1HAAACgYAc3RhdGVzCBQAbWluZWNyYWZ0OmJsb2NrX2ZhY2UCAHVwAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:small_amethyst_bud", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRLAgAACAQAbmFtZRwAbWluZWNyYWZ0OnNtYWxsX2FtZXRoeXN0X2J1ZAQJAG5hbWVfaGFzaEnb4+q9PO4YAwoAbmV0d29ya19pZBkEAAAKBgBzdGF0ZXMIFABtaW5lY3JhZnQ6YmxvY2tfZmFjZQIAdXAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:tuff", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRMAgAACAQAbmFtZQ4AbWluZWNyYWZ0OnR1ZmYECQBuYW1lX2hhc2h1Rwc1XYsBGwMKAG5ldHdvcmtfaWRGBAAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:calcite", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRFAgAACAQAbmFtZREAbWluZWNyYWZ0OmNhbGNpdGUECQBuYW1lX2hhc2ixKLu8ZIdzDQMKAG5ldHdvcmtfaWR6AgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:chicken" - }, - { - "id": "minecraft:porkchop" - }, - { - "id": "minecraft:beef" - }, - { - "id": "minecraft:mutton" - }, - { - "id": "minecraft:rabbit" - }, - { - "id": "minecraft:cod" - }, - { - "id": "minecraft:salmon" - }, - { - "id": "minecraft:tropical_fish" - }, - { - "id": "minecraft:pufferfish" - }, - { - "id": "minecraft:brown_mushroom", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQnAAAACAQAbmFtZRgAbWluZWNyYWZ0OmJyb3duX211c2hyb29tBAkAbmFtZV9oYXNonYw/FO78WDoDCgBuZXR3b3JrX2lkGRcAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:red_mushroom", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQoAAAACAQAbmFtZRYAbWluZWNyYWZ0OnJlZF9tdXNocm9vbQQJAG5hbWVfaGFzaPpzJua7669xAwoAbmV0d29ya19pZCgdAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:crimson_fungus", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTjAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fZnVuZ3VzBAkAbmFtZV9oYXNolIcCUuFM2u0DCgBuZXR3b3JrX2lklDQAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:warped_fungus", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTkAQAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9mdW5ndXMECQBuYW1lX2hhc2gq8bSnRVTAFgMKAG5ldHdvcmtfaWTmAgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:brown_mushroom_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAAAACAQAbmFtZR4AbWluZWNyYWZ0OmJyb3duX211c2hyb29tX2Jsb2NrBAkAbmFtZV9oYXNoIyjnbI6xy9sDCgBuZXR3b3JrX2lk/zIAAAoGAHN0YXRlcwMSAGh1Z2VfbXVzaHJvb21fYml0cw4AAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:red_mushroom_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRkAAAACAQAbmFtZRwAbWluZWNyYWZ0OnJlZF9tdXNocm9vbV9ibG9jawQJAG5hbWVfaGFzaJTTyJbth9M9AwoAbmV0d29ya19pZG8XAAAKBgBzdGF0ZXMDEgBodWdlX211c2hyb29tX2JpdHMOAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:brown_mushroom_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAAAACAQAbmFtZR4AbWluZWNyYWZ0OmJyb3duX211c2hyb29tX2Jsb2NrBAkAbmFtZV9oYXNoIyjnbI6xy9sDCgBuZXR3b3JrX2lkADMAAAoGAHN0YXRlcwMSAGh1Z2VfbXVzaHJvb21fYml0cw8AAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:brown_mushroom_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAAAACAQAbmFtZR4AbWluZWNyYWZ0OmJyb3duX211c2hyb29tX2Jsb2NrBAkAbmFtZV9oYXNoIyjnbI6xy9sDCgBuZXR3b3JrX2lk8TIAAAoGAHN0YXRlcwMSAGh1Z2VfbXVzaHJvb21fYml0cwAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:egg" - }, - { - "id": "minecraft:sugar_cane" - }, - { - "id": "minecraft:sugar" - }, - { - "id": "minecraft:rotten_flesh" - }, - { - "id": "minecraft:bone" - }, - { - "id": "minecraft:web", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQeAAAACAQAbmFtZQ0AbWluZWNyYWZ0OndlYgQJAG5hbWVfaGFzaA4GKQCvG4i9AwoAbmV0d29ya19pZIkuAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:spider_eye" - }, - { - "id": "minecraft:mob_spawner", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ0AAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vYl9zcGF3bmVyBAkAbmFtZV9oYXNoNwGrCV/Fkh8DCgBuZXR3b3JrX2lkggQAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:monster_egg", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkEhsAAAoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGUFAHN0b25lAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:monster_egg", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkExsAAAoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGULAGNvYmJsZXN0b25lAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:monster_egg", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkFBsAAAoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGULAHN0b25lX2JyaWNrAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:monster_egg", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkFRsAAAoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGURAG1vc3N5X3N0b25lX2JyaWNrAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:monster_egg", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkFhsAAAoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGUTAGNyYWNrZWRfc3RvbmVfYnJpY2sAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:monster_egg", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkFxsAAAoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGUUAGNoaXNlbGVkX3N0b25lX2JyaWNrAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:infested_deepslate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTFAgAACAQAbmFtZRwAbWluZWNyYWZ0OmluZmVzdGVkX2RlZXBzbGF0ZQQJAG5hbWVfaGFzaICF2VYccxF1AwoAbmV0d29ya19pZA4fAAAKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:dragon_egg", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR6AAAACAQAbmFtZRQAbWluZWNyYWZ0OmRyYWdvbl9lZ2cECQBuYW1lX2hhc2inMzXrV+/e1wMKAG5ldHdvcmtfaWSjMgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:turtle_egg", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSeAQAACAQAbmFtZRQAbWluZWNyYWZ0OnR1cnRsZV9lZ2cECQBuYW1lX2hhc2iwSRcxOJIJ9gMKAG5ldHdvcmtfaWTfNQAACgYAc3RhdGVzCA0AY3JhY2tlZF9zdGF0ZQkAbm9fY3JhY2tzCBAAdHVydGxlX2VnZ19jb3VudAcAb25lX2VnZwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:sniffer_egg", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRTAwAACAQAbmFtZRUAbWluZWNyYWZ0OnNuaWZmZXJfZWdnBAkAbmFtZV9oYXNoY1lozc8lPcYDCgBuZXR3b3JrX2lkvC8AAAoGAHN0YXRlcwgNAGNyYWNrZWRfc3RhdGUJAG5vX2NyYWNrcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:frog_spawn", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAgAACAQAbmFtZRQAbWluZWNyYWZ0OmZyb2dfc3Bhd24ECQBuYW1lX2hhc2iWmd7idp3ZZwMKAG5ldHdvcmtfaWRSHAAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:pearlescent_froglight", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTUAgAACAQAbmFtZR8AbWluZWNyYWZ0OnBlYXJsZXNjZW50X2Zyb2dsaWdodAQJAG5hbWVfaGFzaKkcFRyycYGyAwoAbmV0d29ya19pZGEtAAAKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:verdant_froglight", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTVAgAACAQAbmFtZRsAbWluZWNyYWZ0OnZlcmRhbnRfZnJvZ2xpZ2h0BAkAbmFtZV9oYXNoA+eXuTBohrQDCgBuZXR3b3JrX2lknC0AAAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:ochre_froglight", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTWAgAACAQAbmFtZRkAbWluZWNyYWZ0Om9jaHJlX2Zyb2dsaWdodAQJAG5hbWVfaGFzaMY59kjPe+c3AwoAbmV0d29ya19pZNIUAAAKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:chicken_spawn_egg" - }, - { - "id": "minecraft:bee_spawn_egg" - }, - { - "id": "minecraft:cow_spawn_egg" - }, - { - "id": "minecraft:pig_spawn_egg" - }, - { - "id": "minecraft:sheep_spawn_egg" - }, - { - "id": "minecraft:wolf_spawn_egg" - }, - { - "id": "minecraft:polar_bear_spawn_egg" - }, - { - "id": "minecraft:ocelot_spawn_egg" - }, - { - "id": "minecraft:cat_spawn_egg" - }, - { - "id": "minecraft:mooshroom_spawn_egg" - }, - { - "id": "minecraft:bat_spawn_egg" - }, - { - "id": "minecraft:parrot_spawn_egg" - }, - { - "id": "minecraft:rabbit_spawn_egg" - }, - { - "id": "minecraft:llama_spawn_egg" - }, - { - "id": "minecraft:horse_spawn_egg" - }, - { - "id": "minecraft:donkey_spawn_egg" - }, - { - "id": "minecraft:mule_spawn_egg" - }, - { - "id": "minecraft:skeleton_horse_spawn_egg" - }, - { - "id": "minecraft:zombie_horse_spawn_egg" - }, - { - "id": "minecraft:tropical_fish_spawn_egg" - }, - { - "id": "minecraft:cod_spawn_egg" - }, - { - "id": "minecraft:pufferfish_spawn_egg" - }, - { - "id": "minecraft:salmon_spawn_egg" - }, - { - "id": "minecraft:dolphin_spawn_egg" - }, - { - "id": "minecraft:turtle_spawn_egg" - }, - { - "id": "minecraft:panda_spawn_egg" - }, - { - "id": "minecraft:fox_spawn_egg" - }, - { - "id": "minecraft:creeper_spawn_egg" - }, - { - "id": "minecraft:enderman_spawn_egg" - }, - { - "id": "minecraft:silverfish_spawn_egg" - }, - { - "id": "minecraft:skeleton_spawn_egg" - }, - { - "id": "minecraft:wither_skeleton_spawn_egg" - }, - { - "id": "minecraft:stray_spawn_egg" - }, - { - "id": "minecraft:slime_spawn_egg" - }, - { - "id": "minecraft:spider_spawn_egg" - }, - { - "id": "minecraft:zombie_spawn_egg" - }, - { - "id": "minecraft:zombie_pigman_spawn_egg" - }, - { - "id": "minecraft:husk_spawn_egg" - }, - { - "id": "minecraft:drowned_spawn_egg" - }, - { - "id": "minecraft:squid_spawn_egg" - }, - { - "id": "minecraft:glow_squid_spawn_egg" - }, - { - "id": "minecraft:cave_spider_spawn_egg" - }, - { - "id": "minecraft:witch_spawn_egg" - }, - { - "id": "minecraft:guardian_spawn_egg" - }, - { - "id": "minecraft:elder_guardian_spawn_egg" - }, - { - "id": "minecraft:endermite_spawn_egg" - }, - { - "id": "minecraft:magma_cube_spawn_egg" - }, - { - "id": "minecraft:strider_spawn_egg" - }, - { - "id": "minecraft:hoglin_spawn_egg" - }, - { - "id": "minecraft:piglin_spawn_egg" - }, - { - "id": "minecraft:zoglin_spawn_egg" - }, - { - "id": "minecraft:piglin_brute_spawn_egg" - }, - { - "id": "minecraft:goat_spawn_egg" - }, - { - "id": "minecraft:axolotl_spawn_egg" - }, - { - "id": "minecraft:warden_spawn_egg" - }, - { - "id": "minecraft:allay_spawn_egg" - }, - { - "id": "minecraft:frog_spawn_egg" - }, - { - "id": "minecraft:tadpole_spawn_egg" - }, - { - "id": "minecraft:trader_llama_spawn_egg" - }, - { - "id": "minecraft:camel_spawn_egg" - }, - { - "id": "minecraft:ghast_spawn_egg" - }, - { - "id": "minecraft:blaze_spawn_egg" - }, - { - "id": "minecraft:shulker_spawn_egg" - }, - { - "id": "minecraft:vindicator_spawn_egg" - }, - { - "id": "minecraft:evoker_spawn_egg" - }, - { - "id": "minecraft:vex_spawn_egg" - }, - { - "id": "minecraft:villager_spawn_egg" - }, - { - "id": "minecraft:wandering_trader_spawn_egg" - }, - { - "id": "minecraft:zombie_villager_spawn_egg" - }, - { - "id": "minecraft:phantom_spawn_egg" - }, - { - "id": "minecraft:pillager_spawn_egg" - }, - { - "id": "minecraft:ravager_spawn_egg" - }, - { - "id": "minecraft:iron_golem_spawn_egg" - }, - { - "id": "minecraft:snow_golem_spawn_egg" - }, - { - "id": "minecraft:sniffer_spawn_egg" - }, - { - "id": "minecraft:obsidian", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQxAAAACAQAbmFtZRIAbWluZWNyYWZ0Om9ic2lkaWFuBAkAbmFtZV9oYXNoiz4qrb8QjyEDCgBuZXR3b3JrX2lknwQAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:crying_obsidian", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQgAgAACAQAbmFtZRkAbWluZWNyYWZ0OmNyeWluZ19vYnNpZGlhbgQJAG5hbWVfaGFzaKT0JlA7Z1K+AwoAbmV0d29ya19pZJQuAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:bedrock", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQHAAAACAQAbmFtZREAbWluZWNyYWZ0OmJlZHJvY2sECQBuYW1lX2hhc2hWfFrh4LVtxwMKAG5ldHdvcmtfaWTOLwAACgYAc3RhdGVzAQ4AaW5maW5pYnVybl9iaXQAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:soul_sand", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNvdWxfc2FuZAQJAG5hbWVfaGFzaMaf+bccu+KTAwoAbmV0d29ya19pZLIlAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:magma", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTVAAAACAQAbmFtZQ8AbWluZWNyYWZ0Om1hZ21hBAkAbmFtZV9oYXNoqyTjKaIsWfYDCgBuZXR3b3JrX2lk6zUAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:nether_wart" - }, - { - "id": "minecraft:end_stone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR5AAAACAQAbmFtZRMAbWluZWNyYWZ0OmVuZF9zdG9uZQQJAG5hbWVfaGFzaH1J9jA39GJNAwoAbmV0d29ya19pZNkZAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:chorus_flower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTIAAAACAQAbmFtZRcAbWluZWNyYWZ0OmNob3J1c19mbG93ZXIECQBuYW1lX2hhc2iMpSodli5uawMKAG5ldHdvcmtfaWTbHAAACgYAc3RhdGVzAwMAYWdlAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:chorus_plant", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTwAAAACAQAbmFtZRYAbWluZWNyYWZ0OmNob3J1c19wbGFudAQJAG5hbWVfaGFzaJhSrmNGKwaMAwoAbmV0d29ya19pZGkkAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:chorus_fruit" - }, - { - "id": "minecraft:popped_chorus_fruit" - }, - { - "id": "minecraft:sponge", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQTAAAACAQAbmFtZRAAbWluZWNyYWZ0OnNwb25nZQQJAG5hbWVfaGFzaLrd2ScYRDMiAwoAbmV0d29ya19pZFkFAAAKBgBzdGF0ZXMICwBzcG9uZ2VfdHlwZQMAZHJ5AAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:sponge", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQTAAAACAQAbmFtZRAAbWluZWNyYWZ0OnNwb25nZQQJAG5hbWVfaGFzaLrd2ScYRDMiAwoAbmV0d29ya19pZFoFAAAKBgBzdGF0ZXMICwBzcG9uZ2VfdHlwZQMAd2V0AAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkMyMAAAoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABibHVlAQgAZGVhZF9iaXQAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkNCMAAAoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABwaW5rAQgAZGVhZF9iaXQAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkNSMAAAoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgBwdXJwbGUBCABkZWFkX2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkNiMAAAoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yAwByZWQBCABkZWFkX2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkNyMAAAoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgB5ZWxsb3cBCABkZWFkX2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkOCMAAAoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABibHVlAQgAZGVhZF9iaXQBAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkOSMAAAoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABwaW5rAQgAZGVhZF9iaXQBAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkOiMAAAoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgBwdXJwbGUBCABkZWFkX2JpdAEAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkOyMAAAoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yAwByZWQBCABkZWFkX2JpdAEAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:coral_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkPCMAAAoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgB5ZWxsb3cBCABkZWFkX2JpdAEAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:sculk", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAgAACAQAbmFtZQ8AbWluZWNyYWZ0OnNjdWxrBAkAbmFtZV9oYXNo2Lq7T5yQF8kDCgBuZXR3b3JrX2lk4y8AAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:sculk_vein", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTKAgAACAQAbmFtZRQAbWluZWNyYWZ0OnNjdWxrX3ZlaW4ECQBuYW1lX2hhc2gJUdhVooV4zwMKAG5ldHdvcmtfaWTzMQAACgYAc3RhdGVzAxkAbXVsdGlfZmFjZV9kaXJlY3Rpb25fYml0cwAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:sculk_catalyst", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTLAgAACAQAbmFtZRgAbWluZWNyYWZ0OnNjdWxrX2NhdGFseXN0BAkAbmFtZV9oYXNo+gCpbrCHST4DCgBuZXR3b3JrX2lkcRcAAAoGAHN0YXRlcwEFAGJsb29tAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:sculk_shrieker", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTMAgAACAQAbmFtZRgAbWluZWNyYWZ0OnNjdWxrX3Nocmlla2VyBAkAbmFtZV9oYXNo5OXtyObniQ4DCgBuZXR3b3JrX2lkgwIAAAoGAHN0YXRlcwEGAGFjdGl2ZQABCgBjYW5fc3VtbW9uAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:sculk_sensor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQyAgAACAQAbmFtZRYAbWluZWNyYWZ0OnNjdWxrX3NlbnNvcgQJAG5hbWVfaGFzaCkmHreeTgNnAwoAbmV0d29ya19pZEMcAAAKBgBzdGF0ZXMDEgBzY3Vsa19zZW5zb3JfcGhhc2UAAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:calibrated_sculk_sensor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRDAwAACAQAbmFtZSEAbWluZWNyYWZ0OmNhbGlicmF0ZWRfc2N1bGtfc2Vuc29yBAkAbmFtZV9oYXNoffAcXXN/iJUDCgBuZXR3b3JrX2lkTCcAAAoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAxIAc2N1bGtfc2Vuc29yX3BoYXNlAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:reinforced_deepslate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTRAgAACAQAbmFtZR4AbWluZWNyYWZ0OnJlaW5mb3JjZWRfZGVlcHNsYXRlBAkAbmFtZV9oYXNoldDmj91EapQDCgBuZXR3b3JrX2lkNCcAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:leather_helmet" - }, - { - "id": "minecraft:chainmail_helmet" - }, - { - "id": "minecraft:iron_helmet" - }, - { - "id": "minecraft:golden_helmet" - }, - { - "id": "minecraft:diamond_helmet" - }, - { - "id": "minecraft:netherite_helmet" - }, - { - "id": "minecraft:leather_chestplate" - }, - { - "id": "minecraft:chainmail_chestplate" - }, - { - "id": "minecraft:iron_chestplate" - }, - { - "id": "minecraft:golden_chestplate" - }, - { - "id": "minecraft:diamond_chestplate" - }, - { - "id": "minecraft:netherite_chestplate" - }, - { - "id": "minecraft:leather_leggings" - }, - { - "id": "minecraft:chainmail_leggings" - }, - { - "id": "minecraft:iron_leggings" - }, - { - "id": "minecraft:golden_leggings" - }, - { - "id": "minecraft:diamond_leggings" - }, - { - "id": "minecraft:netherite_leggings" - }, - { - "id": "minecraft:leather_boots" - }, - { - "id": "minecraft:chainmail_boots" - }, - { - "id": "minecraft:iron_boots" - }, - { - "id": "minecraft:golden_boots" - }, - { - "id": "minecraft:diamond_boots" - }, - { - "id": "minecraft:netherite_boots" - }, - { - "id": "minecraft:wooden_sword" - }, - { - "id": "minecraft:stone_sword" - }, - { - "id": "minecraft:iron_sword" - }, - { - "id": "minecraft:golden_sword" - }, - { - "id": "minecraft:diamond_sword" - }, - { - "id": "minecraft:netherite_sword" - }, - { - "id": "minecraft:wooden_axe" - }, - { - "id": "minecraft:stone_axe" - }, - { - "id": "minecraft:iron_axe" - }, - { - "id": "minecraft:golden_axe" - }, - { - "id": "minecraft:diamond_axe" - }, - { - "id": "minecraft:netherite_axe" - }, - { - "id": "minecraft:wooden_pickaxe" - }, - { - "id": "minecraft:stone_pickaxe" - }, - { - "id": "minecraft:iron_pickaxe" - }, - { - "id": "minecraft:golden_pickaxe" - }, - { - "id": "minecraft:diamond_pickaxe" - }, - { - "id": "minecraft:netherite_pickaxe" - }, - { - "id": "minecraft:wooden_shovel" - }, - { - "id": "minecraft:stone_shovel" - }, - { - "id": "minecraft:iron_shovel" - }, - { - "id": "minecraft:golden_shovel" - }, - { - "id": "minecraft:diamond_shovel" - }, - { - "id": "minecraft:netherite_shovel" - }, - { - "id": "minecraft:wooden_hoe" - }, - { - "id": "minecraft:stone_hoe" - }, - { - "id": "minecraft:iron_hoe" - }, - { - "id": "minecraft:golden_hoe" - }, - { - "id": "minecraft:diamond_hoe" - }, - { - "id": "minecraft:netherite_hoe" - }, - { - "id": "minecraft:bow" - }, - { - "id": "minecraft:crossbow" - }, - { - "id": "minecraft:arrow" - }, - { - "id": "minecraft:arrow", - "damage": 6 - }, - { - "id": "minecraft:arrow", - "damage": 7 - }, - { - "id": "minecraft:arrow", - "damage": 8 - }, - { - "id": "minecraft:arrow", - "damage": 9 - }, - { - "id": "minecraft:arrow", - "damage": 10 - }, - { - "id": "minecraft:arrow", - "damage": 11 - }, - { - "id": "minecraft:arrow", - "damage": 12 - }, - { - "id": "minecraft:arrow", - "damage": 13 - }, - { - "id": "minecraft:arrow", - "damage": 14 - }, - { - "id": "minecraft:arrow", - "damage": 15 - }, - { - "id": "minecraft:arrow", - "damage": 16 - }, - { - "id": "minecraft:arrow", - "damage": 17 - }, - { - "id": "minecraft:arrow", - "damage": 18 - }, - { - "id": "minecraft:arrow", - "damage": 19 - }, - { - "id": "minecraft:arrow", - "damage": 20 - }, - { - "id": "minecraft:arrow", - "damage": 21 - }, - { - "id": "minecraft:arrow", - "damage": 22 - }, - { - "id": "minecraft:arrow", - "damage": 23 - }, - { - "id": "minecraft:arrow", - "damage": 24 - }, - { - "id": "minecraft:arrow", - "damage": 25 - }, - { - "id": "minecraft:arrow", - "damage": 26 - }, - { - "id": "minecraft:arrow", - "damage": 27 - }, - { - "id": "minecraft:arrow", - "damage": 28 - }, - { - "id": "minecraft:arrow", - "damage": 29 - }, - { - "id": "minecraft:arrow", - "damage": 30 - }, - { - "id": "minecraft:arrow", - "damage": 31 - }, - { - "id": "minecraft:arrow", - "damage": 32 - }, - { - "id": "minecraft:arrow", - "damage": 33 - }, - { - "id": "minecraft:arrow", - "damage": 34 - }, - { - "id": "minecraft:arrow", - "damage": 35 - }, - { - "id": "minecraft:arrow", - "damage": 36 - }, - { - "id": "minecraft:arrow", - "damage": 37 - }, - { - "id": "minecraft:arrow", - "damage": 38 - }, - { - "id": "minecraft:arrow", - "damage": 39 - }, - { - "id": "minecraft:arrow", - "damage": 40 - }, - { - "id": "minecraft:arrow", - "damage": 41 - }, - { - "id": "minecraft:arrow", - "damage": 42 - }, - { - "id": "minecraft:arrow", - "damage": 43 - }, - { - "id": "minecraft:shield" - }, - { - "id": "minecraft:cooked_chicken" - }, - { - "id": "minecraft:cooked_porkchop" - }, - { - "id": "minecraft:cooked_beef" - }, - { - "id": "minecraft:cooked_mutton" - }, - { - "id": "minecraft:cooked_rabbit" - }, - { - "id": "minecraft:cooked_cod" - }, - { - "id": "minecraft:cooked_salmon" - }, - { - "id": "minecraft:bread" - }, - { - "id": "minecraft:mushroom_stew" - }, - { - "id": "minecraft:beetroot_soup" - }, - { - "id": "minecraft:rabbit_stew" - }, - { - "id": "minecraft:baked_potato" - }, - { - "id": "minecraft:cookie" - }, - { - "id": "minecraft:pumpkin_pie" - }, - { - "id": "minecraft:cake" - }, - { - "id": "minecraft:dried_kelp" - }, - { - "id": "minecraft:fishing_rod" - }, - { - "id": "minecraft:carrot_on_a_stick" - }, - { - "id": "minecraft:warped_fungus_on_a_stick" - }, - { - "id": "minecraft:snowball" - }, - { - "id": "minecraft:shears" - }, - { - "id": "minecraft:flint_and_steel" - }, - { - "id": "minecraft:lead" - }, - { - "id": "minecraft:clock" - }, - { - "id": "minecraft:compass" - }, - { - "id": "minecraft:recovery_compass" - }, - { - "id": "minecraft:goat_horn" - }, - { - "id": "minecraft:goat_horn", - "damage": 1 - }, - { - "id": "minecraft:goat_horn", - "damage": 2 - }, - { - "id": "minecraft:goat_horn", - "damage": 3 - }, - { - "id": "minecraft:goat_horn", - "damage": 4 - }, - { - "id": "minecraft:goat_horn", - "damage": 5 - }, - { - "id": "minecraft:goat_horn", - "damage": 6 - }, - { - "id": "minecraft:goat_horn", - "damage": 7 - }, - { - "id": "minecraft:empty_map" - }, - { - "id": "minecraft:empty_map", - "damage": 2 - }, - { - "id": "minecraft:saddle" - }, - { - "id": "minecraft:leather_horse_armor" - }, - { - "id": "minecraft:iron_horse_armor" - }, - { - "id": "minecraft:golden_horse_armor" - }, - { - "id": "minecraft:diamond_horse_armor" - }, - { - "id": "minecraft:trident" - }, - { - "id": "minecraft:turtle_helmet" - }, - { - "id": "minecraft:elytra" - }, - { - "id": "minecraft:totem_of_undying" - }, - { - "id": "minecraft:glass_bottle" - }, - { - "id": "minecraft:experience_bottle" - }, - { - "id": "minecraft:potion" - }, - { - "id": "minecraft:potion", - "damage": 1 - }, - { - "id": "minecraft:potion", - "damage": 2 - }, - { - "id": "minecraft:potion", - "damage": 3 - }, - { - "id": "minecraft:potion", - "damage": 4 - }, - { - "id": "minecraft:potion", - "damage": 5 - }, - { - "id": "minecraft:potion", - "damage": 6 - }, - { - "id": "minecraft:potion", - "damage": 7 - }, - { - "id": "minecraft:potion", - "damage": 8 - }, - { - "id": "minecraft:potion", - "damage": 9 - }, - { - "id": "minecraft:potion", - "damage": 10 - }, - { - "id": "minecraft:potion", - "damage": 11 - }, - { - "id": "minecraft:potion", - "damage": 12 - }, - { - "id": "minecraft:potion", - "damage": 13 - }, - { - "id": "minecraft:potion", - "damage": 14 - }, - { - "id": "minecraft:potion", - "damage": 15 - }, - { - "id": "minecraft:potion", - "damage": 16 - }, - { - "id": "minecraft:potion", - "damage": 17 - }, - { - "id": "minecraft:potion", - "damage": 18 - }, - { - "id": "minecraft:potion", - "damage": 19 - }, - { - "id": "minecraft:potion", - "damage": 20 - }, - { - "id": "minecraft:potion", - "damage": 21 - }, - { - "id": "minecraft:potion", - "damage": 22 - }, - { - "id": "minecraft:potion", - "damage": 23 - }, - { - "id": "minecraft:potion", - "damage": 24 - }, - { - "id": "minecraft:potion", - "damage": 25 - }, - { - "id": "minecraft:potion", - "damage": 26 - }, - { - "id": "minecraft:potion", - "damage": 27 - }, - { - "id": "minecraft:potion", - "damage": 28 - }, - { - "id": "minecraft:potion", - "damage": 29 - }, - { - "id": "minecraft:potion", - "damage": 30 - }, - { - "id": "minecraft:potion", - "damage": 31 - }, - { - "id": "minecraft:potion", - "damage": 32 - }, - { - "id": "minecraft:potion", - "damage": 33 - }, - { - "id": "minecraft:potion", - "damage": 34 - }, - { - "id": "minecraft:potion", - "damage": 35 - }, - { - "id": "minecraft:potion", - "damage": 36 - }, - { - "id": "minecraft:potion", - "damage": 37 - }, - { - "id": "minecraft:potion", - "damage": 38 - }, - { - "id": "minecraft:potion", - "damage": 39 - }, - { - "id": "minecraft:potion", - "damage": 40 - }, - { - "id": "minecraft:potion", - "damage": 41 - }, - { - "id": "minecraft:potion", - "damage": 42 - }, - { - "id": "minecraft:splash_potion" - }, - { - "id": "minecraft:splash_potion", - "damage": 1 - }, - { - "id": "minecraft:splash_potion", - "damage": 2 - }, - { - "id": "minecraft:splash_potion", - "damage": 3 - }, - { - "id": "minecraft:splash_potion", - "damage": 4 - }, - { - "id": "minecraft:splash_potion", - "damage": 5 - }, - { - "id": "minecraft:splash_potion", - "damage": 6 - }, - { - "id": "minecraft:splash_potion", - "damage": 7 - }, - { - "id": "minecraft:splash_potion", - "damage": 8 - }, - { - "id": "minecraft:splash_potion", - "damage": 9 - }, - { - "id": "minecraft:splash_potion", - "damage": 10 - }, - { - "id": "minecraft:splash_potion", - "damage": 11 - }, - { - "id": "minecraft:splash_potion", - "damage": 12 - }, - { - "id": "minecraft:splash_potion", - "damage": 13 - }, - { - "id": "minecraft:splash_potion", - "damage": 14 - }, - { - "id": "minecraft:splash_potion", - "damage": 15 - }, - { - "id": "minecraft:splash_potion", - "damage": 16 - }, - { - "id": "minecraft:splash_potion", - "damage": 17 - }, - { - "id": "minecraft:splash_potion", - "damage": 18 - }, - { - "id": "minecraft:splash_potion", - "damage": 19 - }, - { - "id": "minecraft:splash_potion", - "damage": 20 - }, - { - "id": "minecraft:splash_potion", - "damage": 21 - }, - { - "id": "minecraft:splash_potion", - "damage": 22 - }, - { - "id": "minecraft:splash_potion", - "damage": 23 - }, - { - "id": "minecraft:splash_potion", - "damage": 24 - }, - { - "id": "minecraft:splash_potion", - "damage": 25 - }, - { - "id": "minecraft:splash_potion", - "damage": 26 - }, - { - "id": "minecraft:splash_potion", - "damage": 27 - }, - { - "id": "minecraft:splash_potion", - "damage": 28 - }, - { - "id": "minecraft:splash_potion", - "damage": 29 - }, - { - "id": "minecraft:splash_potion", - "damage": 30 - }, - { - "id": "minecraft:splash_potion", - "damage": 31 - }, - { - "id": "minecraft:splash_potion", - "damage": 32 - }, - { - "id": "minecraft:splash_potion", - "damage": 33 - }, - { - "id": "minecraft:splash_potion", - "damage": 34 - }, - { - "id": "minecraft:splash_potion", - "damage": 35 - }, - { - "id": "minecraft:splash_potion", - "damage": 36 - }, - { - "id": "minecraft:splash_potion", - "damage": 37 - }, - { - "id": "minecraft:splash_potion", - "damage": 38 - }, - { - "id": "minecraft:splash_potion", - "damage": 39 - }, - { - "id": "minecraft:splash_potion", - "damage": 40 - }, - { - "id": "minecraft:splash_potion", - "damage": 41 - }, - { - "id": "minecraft:splash_potion", - "damage": 42 - }, - { - "id": "minecraft:lingering_potion" - }, - { - "id": "minecraft:lingering_potion", - "damage": 1 - }, - { - "id": "minecraft:lingering_potion", - "damage": 2 - }, - { - "id": "minecraft:lingering_potion", - "damage": 3 - }, - { - "id": "minecraft:lingering_potion", - "damage": 4 - }, - { - "id": "minecraft:lingering_potion", - "damage": 5 - }, - { - "id": "minecraft:lingering_potion", - "damage": 6 - }, - { - "id": "minecraft:lingering_potion", - "damage": 7 - }, - { - "id": "minecraft:lingering_potion", - "damage": 8 - }, - { - "id": "minecraft:lingering_potion", - "damage": 9 - }, - { - "id": "minecraft:lingering_potion", - "damage": 10 - }, - { - "id": "minecraft:lingering_potion", - "damage": 11 - }, - { - "id": "minecraft:lingering_potion", - "damage": 12 - }, - { - "id": "minecraft:lingering_potion", - "damage": 13 - }, - { - "id": "minecraft:lingering_potion", - "damage": 14 - }, - { - "id": "minecraft:lingering_potion", - "damage": 15 - }, - { - "id": "minecraft:lingering_potion", - "damage": 16 - }, - { - "id": "minecraft:lingering_potion", - "damage": 17 - }, - { - "id": "minecraft:lingering_potion", - "damage": 18 - }, - { - "id": "minecraft:lingering_potion", - "damage": 19 - }, - { - "id": "minecraft:lingering_potion", - "damage": 20 - }, - { - "id": "minecraft:lingering_potion", - "damage": 21 - }, - { - "id": "minecraft:lingering_potion", - "damage": 22 - }, - { - "id": "minecraft:lingering_potion", - "damage": 23 - }, - { - "id": "minecraft:lingering_potion", - "damage": 24 - }, - { - "id": "minecraft:lingering_potion", - "damage": 25 - }, - { - "id": "minecraft:lingering_potion", - "damage": 26 - }, - { - "id": "minecraft:lingering_potion", - "damage": 27 - }, - { - "id": "minecraft:lingering_potion", - "damage": 28 - }, - { - "id": "minecraft:lingering_potion", - "damage": 29 - }, - { - "id": "minecraft:lingering_potion", - "damage": 30 - }, - { - "id": "minecraft:lingering_potion", - "damage": 31 - }, - { - "id": "minecraft:lingering_potion", - "damage": 32 - }, - { - "id": "minecraft:lingering_potion", - "damage": 33 - }, - { - "id": "minecraft:lingering_potion", - "damage": 34 - }, - { - "id": "minecraft:lingering_potion", - "damage": 35 - }, - { - "id": "minecraft:lingering_potion", - "damage": 36 - }, - { - "id": "minecraft:lingering_potion", - "damage": 37 - }, - { - "id": "minecraft:lingering_potion", - "damage": 38 - }, - { - "id": "minecraft:lingering_potion", - "damage": 39 - }, - { - "id": "minecraft:lingering_potion", - "damage": 40 - }, - { - "id": "minecraft:lingering_potion", - "damage": 41 - }, - { - "id": "minecraft:lingering_potion", - "damage": 42 - }, - { - "id": "minecraft:spyglass" - }, - { - "id": "minecraft:brush" - }, - { - "id": "minecraft:stick" - }, - { - "id": "minecraft:bed" - }, - { - "id": "minecraft:bed", - "damage": 8 - }, - { - "id": "minecraft:bed", - "damage": 7 - }, - { - "id": "minecraft:bed", - "damage": 15 - }, - { - "id": "minecraft:bed", - "damage": 12 - }, - { - "id": "minecraft:bed", - "damage": 14 - }, - { - "id": "minecraft:bed", - "damage": 1 - }, - { - "id": "minecraft:bed", - "damage": 4 - }, - { - "id": "minecraft:bed", - "damage": 5 - }, - { - "id": "minecraft:bed", - "damage": 13 - }, - { - "id": "minecraft:bed", - "damage": 9 - }, - { - "id": "minecraft:bed", - "damage": 3 - }, - { - "id": "minecraft:bed", - "damage": 11 - }, - { - "id": "minecraft:bed", - "damage": 10 - }, - { - "id": "minecraft:bed", - "damage": 2 - }, - { - "id": "minecraft:bed", - "damage": 6 - }, - { - "id": "minecraft:torch", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQyAAAACAQAbmFtZQ8AbWluZWNyYWZ0OnRvcmNoBAkAbmFtZV9oYXNoagn7rmDBzisDCgBuZXR3b3JrX2lkdwgAAAoGAHN0YXRlcwgWAHRvcmNoX2ZhY2luZ19kaXJlY3Rpb24HAHVua25vd24AAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:soul_torch", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQLAgAACAQAbmFtZRQAbWluZWNyYWZ0OnNvdWxfdG9yY2gECQBuYW1lX2hhc2huixOT04BRdQMKAG5ldHdvcmtfaWQRHwAACgYAc3RhdGVzCBYAdG9yY2hfZmFjaW5nX2RpcmVjdGlvbgcAdW5rbm93bgADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:sea_pickle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAQAACAQAbmFtZRQAbWluZWNyYWZ0OnNlYV9waWNrbGUECQBuYW1lX2hhc2iONEfZJB+glgMKAG5ldHdvcmtfaWRvJwAACgYAc3RhdGVzAw0AY2x1c3Rlcl9jb3VudAAAAAABCABkZWFkX2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:lantern", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTPAQAACAQAbmFtZREAbWluZWNyYWZ0OmxhbnRlcm4ECQBuYW1lX2hhc2hMw44VI2HWygMKAG5ldHdvcmtfaWQLMAAACgYAc3RhdGVzAQcAaGFuZ2luZwAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:soul_lantern", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQMAgAACAQAbmFtZRYAbWluZWNyYWZ0OnNvdWxfbGFudGVybgQJAG5hbWVfaGFzaGjIpjxk9z+RAwoAbmV0d29ya19pZF4lAAAKBgBzdGF0ZXMBBwBoYW5naW5nAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAgAACAQAbmFtZRAAbWluZWNyYWZ0OmNhbmRsZQQJAG5hbWVfaGFzaHPd+MsNdWTfAwoAbmV0d29ya19pZCUzAAAKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:white_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWScAgAACAQAbmFtZRYAbWluZWNyYWZ0OndoaXRlX2NhbmRsZQQJAG5hbWVfaGFzaN1EG5Q1mHiEAwoAbmV0d29ya19pZIQjAAAKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:orange_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSdAgAACAQAbmFtZRcAbWluZWNyYWZ0Om9yYW5nZV9jYW5kbGUECQBuYW1lX2hhc2jySEVWHgUIHQMKAG5ldHdvcmtfaWRYBAAACgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:magenta_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSeAgAACAQAbmFtZRgAbWluZWNyYWZ0Om1hZ2VudGFfY2FuZGxlBAkAbmFtZV9oYXNoG0u6YIOoBSEDCgBuZXR3b3JrX2lklAQAAAoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:light_blue_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSfAgAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY2FuZGxlBAkAbmFtZV9oYXNocXGeK0zgrG0DCgBuZXR3b3JrX2lkBB0AAAoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:yellow_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSgAgAACAQAbmFtZRcAbWluZWNyYWZ0OnllbGxvd19jYW5kbGUECQBuYW1lX2hhc2i00dtusU3CqQMKAG5ldHdvcmtfaWRMLAAACgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:lime_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWShAgAACAQAbmFtZRUAbWluZWNyYWZ0OmxpbWVfY2FuZGxlBAkAbmFtZV9oYXNokcmrw5xvz7ADCgBuZXR3b3JrX2lk/CwAAAoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:pink_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSiAgAACAQAbmFtZRUAbWluZWNyYWZ0OnBpbmtfY2FuZGxlBAkAbmFtZV9oYXNoQJdEY4sZ0dwDCgBuZXR3b3JrX2lkAzMAAAoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:gray_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSjAgAACAQAbmFtZRUAbWluZWNyYWZ0OmdyYXlfY2FuZGxlBAkAbmFtZV9oYXNoS5poSo9wBDEDCgBuZXR3b3JrX2lkXwkAAAoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:light_gray_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSkAgAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY2FuZGxlBAkAbmFtZV9oYXNo9ruTZLBNMasDCgBuZXR3b3JrX2lkaSwAAAoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:cyan_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAgAACAQAbmFtZRUAbWluZWNyYWZ0OmN5YW5fY2FuZGxlBAkAbmFtZV9oYXNoc/M8PNVcjOwDCgBuZXR3b3JrX2lkeDQAAAoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:purple_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSmAgAACAQAbmFtZRcAbWluZWNyYWZ0OnB1cnBsZV9jYW5kbGUECQBuYW1lX2hhc2jaI3xUW0/myQMKAG5ldHdvcmtfaWTmLwAACgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:blue_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSnAgAACAQAbmFtZRUAbWluZWNyYWZ0OmJsdWVfY2FuZGxlBAkAbmFtZV9oYXNoAASSPW6TgQADCgBuZXR3b3JrX2lkAgAAAAoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:brown_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAgAACAQAbmFtZRYAbWluZWNyYWZ0OmJyb3duX2NhbmRsZQQJAG5hbWVfaGFzaDia0l6s1+WYAwoAbmV0d29ya19pZCQpAAAKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:green_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSpAgAACAQAbmFtZRYAbWluZWNyYWZ0OmdyZWVuX2NhbmRsZQQJAG5hbWVfaGFzaLeFPO1l+fIoAwoAbmV0d29ya19pZKcHAAAKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:red_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSqAgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9jYW5kbGUECQBuYW1lX2hhc2jjAQpGf59ZdwMKAG5ldHdvcmtfaWQ2HwAACgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:black_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSrAgAACAQAbmFtZRYAbWluZWNyYWZ0OmJsYWNrX2NhbmRsZQQJAG5hbWVfaGFzaB+wRDpOqREKAwoAbmV0d29ya19pZE0CAAAKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:crafting_table", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ6AAAACAQAbmFtZRgAbWluZWNyYWZ0OmNyYWZ0aW5nX3RhYmxlBAkAbmFtZV9oYXNoe76VAmjvbpYDCgBuZXR3b3JrX2lkbicAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:cartography_table", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTHAQAACAQAbmFtZRsAbWluZWNyYWZ0OmNhcnRvZ3JhcGh5X3RhYmxlBAkAbmFtZV9oYXNomaWiiD/znP8DCgBuZXR3b3JrX2lkFDcAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:fletching_table", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTIAQAACAQAbmFtZRkAbWluZWNyYWZ0OmZsZXRjaGluZ190YWJsZQQJAG5hbWVfaGFzaPFibh8unKyUAwoAbmV0d29ya19pZDUnAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:smithing_table", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAQAACAQAbmFtZRgAbWluZWNyYWZ0OnNtaXRoaW5nX3RhYmxlBAkAbmFtZV9oYXNo4tFES2xOXEYDCgBuZXR3b3JrX2lk6RcAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:beehive", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTaAQAACAQAbmFtZREAbWluZWNyYWZ0OmJlZWhpdmUECQBuYW1lX2hhc2hCcqn12UbNpwMKAG5ldHdvcmtfaWQHLAAACgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAMLAGhvbmV5X2xldmVsAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:suspicious_sand", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQQAwAACAQAbmFtZRkAbWluZWNyYWZ0OnN1c3BpY2lvdXNfc2FuZAQJAG5hbWVfaGFzaL67QsuvLP00AwoAbmV0d29ya19pZCYKAAAKBgBzdGF0ZXMDEABicnVzaGVkX3Byb2dyZXNzAAAAAAEHAGhhbmdpbmcBAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:suspicious_gravel", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ8AwAACAQAbmFtZRsAbWluZWNyYWZ0OnN1c3BpY2lvdXNfZ3JhdmVsBAkAbmFtZV9oYXNoJSVbGNk7C3oDCgBuZXR3b3JrX2lkix8AAAoGAHN0YXRlcwMQAGJydXNoZWRfcHJvZ3Jlc3MAAAAAAQcAaGFuZ2luZwEAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:campfire" - }, - { - "id": "minecraft:soul_campfire" - }, - { - "id": "minecraft:furnace", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ9AAAACAQAbmFtZREAbWluZWNyYWZ0OmZ1cm5hY2UECQBuYW1lX2hhc2ioOQrludYY8wMKAG5ldHdvcmtfaWQaNQAACgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:blast_furnace", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTDAQAACAQAbmFtZRcAbWluZWNyYWZ0OmJsYXN0X2Z1cm5hY2UECQBuYW1lX2hhc2ivDbnjkpGm5QMKAG5ldHdvcmtfaWTUMwAACgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:smoker", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTFAQAACAQAbmFtZRAAbWluZWNyYWZ0OnNtb2tlcgQJAG5hbWVfaGFzaJd1rDMkRWomAwoAbmV0d29ya19pZO0GAAAKBgBzdGF0ZXMIHABtaW5lY3JhZnQ6Y2FyZGluYWxfZGlyZWN0aW9uBQBzb3V0aAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:respawn_anchor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQPAgAACAQAbmFtZRgAbWluZWNyYWZ0OnJlc3Bhd25fYW5jaG9yBAkAbmFtZV9oYXNoZOdcjW05qigDCgBuZXR3b3JrX2lkoQcAAAoGAHN0YXRlcwMVAHJlc3Bhd25fYW5jaG9yX2NoYXJnZQAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:brewing_stand" - }, - { - "id": "minecraft:anvil", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmFudmlsBAkAbmFtZV9oYXNoNqB3fgcUCbwDCgBuZXR3b3JrX2lkRC4AAAoGAHN0YXRlcwgGAGRhbWFnZQkAdW5kYW1hZ2VkCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:anvil", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmFudmlsBAkAbmFtZV9oYXNoNqB3fgcUCbwDCgBuZXR3b3JrX2lkSC4AAAoGAHN0YXRlcwgGAGRhbWFnZRAAc2xpZ2h0bHlfZGFtYWdlZAgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:anvil", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmFudmlsBAkAbmFtZV9oYXNoNqB3fgcUCbwDCgBuZXR3b3JrX2lkTC4AAAoGAHN0YXRlcwgGAGRhbWFnZQwAdmVyeV9kYW1hZ2VkCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:grindstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTCAQAACAQAbmFtZRQAbWluZWNyYWZ0OmdyaW5kc3RvbmUECQBuYW1lX2hhc2id56zc0nk99wMKAG5ldHdvcmtfaWT6NQAACgYAc3RhdGVzCAoAYXR0YWNobWVudAgAc3RhbmRpbmcDCQBkaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:enchanting_table", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR0AAAACAQAbmFtZRoAbWluZWNyYWZ0OmVuY2hhbnRpbmdfdGFibGUECQBuYW1lX2hhc2jgIx24VLvMvwMKAG5ldHdvcmtfaWSaLgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:bookshelf", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQvAAAACAQAbmFtZRMAbWluZWNyYWZ0OmJvb2tzaGVsZgQJAG5hbWVfaGFzaDU04DrgJCS9AwoAbmV0d29ya19pZGouAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:chiseled_bookshelf", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQNAwAACAQAbmFtZRwAbWluZWNyYWZ0OmNoaXNlbGVkX2Jvb2tzaGVsZgQJAG5hbWVfaGFzaNXDBnsIsywYAwoAbmV0d29ya19pZA0DAAAKBgBzdGF0ZXMDDABib29rc19zdG9yZWQAAAAAAwkAZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:lectern", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTBAQAACAQAbmFtZREAbWluZWNyYWZ0OmxlY3Rlcm4ECQBuYW1lX2hhc2j5Z4Mmi/1QxAMKAG5ldHdvcmtfaWR8LwAACgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgBCwBwb3dlcmVkX2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:cauldron" - }, - { - "id": "minecraft:composter", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTUAQAACAQAbmFtZRMAbWluZWNyYWZ0OmNvbXBvc3RlcgQJAG5hbWVfaGFzaPAADHptzeWJAwoAbmV0d29ya19pZO4jAAAKBgBzdGF0ZXMDFABjb21wb3N0ZXJfZmlsbF9sZXZlbAAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:chest", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ2AAAACAQAbmFtZQ8AbWluZWNyYWZ0OmNoZXN0BAkAbmFtZV9oYXNog9ozMxlcA88DCgBuZXR3b3JrX2lkWDAAAAoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAG5vcnRoAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:trapped_chest", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSSAAAACAQAbmFtZRcAbWluZWNyYWZ0OnRyYXBwZWRfY2hlc3QECQBuYW1lX2hhc2g2qpF9stsEjgMKAG5ldHdvcmtfaWS5JAAACgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAbm9ydGgAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:ender_chest", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSCAAAACAQAbmFtZRUAbWluZWNyYWZ0OmVuZGVyX2NoZXN0BAkAbmFtZV9oYXNohEZzOFdg0WUDCgBuZXR3b3JrX2lkMhwAAAoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAG5vcnRoAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:barrel", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTKAQAACAQAbmFtZRAAbWluZWNyYWZ0OmJhcnJlbAQJAG5hbWVfaGFzaHDkRPGymiRqAwoAbmV0d29ya19pZM8cAAAKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:undyed_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTNAAAACAQAbmFtZRwAbWluZWNyYWZ0OnVuZHllZF9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaOC9mypm/MlBAwoAbmV0d29ya19pZLkXAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:white_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTaAAAACAQAbmFtZRsAbWluZWNyYWZ0OndoaXRlX3NodWxrZXJfYm94BAkAbmFtZV9oYXNosK79m1rPUBwDCgBuZXR3b3JrX2lkVQQAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:light_gray_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRrAwAACAQAbmFtZSAAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2iBe5zq7PxHmgMKAG5ldHdvcmtfaWRGKQAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:gray_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRqAwAACAQAbmFtZRoAbWluZWNyYWZ0OmdyYXlfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2ga2s8ctjHUhgMKAG5ldHdvcmtfaWSoIwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:black_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRyAwAACAQAbmFtZRsAbWluZWNyYWZ0OmJsYWNrX3NodWxrZXJfYm94BAkAbmFtZV9oYXNoPm03OZphrp8DCgBuZXR3b3JrX2lklysAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:brown_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRvAwAACAQAbmFtZRsAbWluZWNyYWZ0OmJyb3duX3NodWxrZXJfYm94BAkAbmFtZV9oYXNoT3DD6qAL9cADCgBuZXR3b3JrX2lkPy8AAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:red_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRxAwAACAQAbmFtZRkAbWluZWNyYWZ0OnJlZF9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaMIlKSCzqSZoAwoAbmV0d29ya19pZHMcAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:orange_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRkAwAACAQAbmFtZRwAbWluZWNyYWZ0Om9yYW5nZV9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaG2MAXU67wGrAwoAbmV0d29ya19pZGgsAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:yellow_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRnAwAACAQAbmFtZRwAbWluZWNyYWZ0OnllbGxvd19zaHVsa2VyX2JveAQJAG5hbWVfaGFzaIsLwQHYjcIEAwoAbmV0d29ya19pZHsAAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:lime_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRoAwAACAQAbmFtZRoAbWluZWNyYWZ0OmxpbWVfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2hUwBkg+faUGAMKAG5ldHdvcmtfaWQWBAAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:green_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRwAwAACAQAbmFtZRsAbWluZWNyYWZ0OmdyZWVuX3NodWxrZXJfYm94BAkAbmFtZV9oYXNoZgUeT3LupLUDCgBuZXR3b3JrX2lkpS0AAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:cyan_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRsAwAACAQAbmFtZRoAbWluZWNyYWZ0OmN5YW5fc2h1bGtlcl9ib3gECQBuYW1lX2hhc2gSfbjteXg5yAMKAG5ldHdvcmtfaWTZLwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:light_blue_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRmAwAACAQAbmFtZSAAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2h0VFCX0qsRxQMKAG5ldHdvcmtfaWSXLwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:blue_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRuAwAACAQAbmFtZRoAbWluZWNyYWZ0OmJsdWVfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2hn9gS0XIe6rAMKAG5ldHdvcmtfaWSZLAAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:purple_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRtAwAACAQAbmFtZRwAbWluZWNyYWZ0OnB1cnBsZV9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaEV/lkNPxRDdAwoAbmV0d29ya19pZAszAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:magenta_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRlAwAACAQAbmFtZR0AbWluZWNyYWZ0Om1hZ2VudGFfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2iqWM7IJHxcFgMKAG5ldHdvcmtfaWTgAgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:pink_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRpAwAACAQAbmFtZRoAbWluZWNyYWZ0OnBpbmtfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2in1tkJ1GNcZgMKAG5ldHdvcmtfaWQ6HAAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:armor_stand" - }, - { - "id": "minecraft:noteblock", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQZAAAACAQAbmFtZRMAbWluZWNyYWZ0Om5vdGVibG9jawQJAG5hbWVfaGFzaHPA8dBBH0UaAwoAbmV0d29ya19pZEUEAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:jukebox", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRUAAAACAQAbmFtZREAbWluZWNyYWZ0Omp1a2Vib3gECQBuYW1lX2hhc2ieAIPExf/ZfgMKAG5ldHdvcmtfaWS1IQAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:music_disc_13" - }, - { - "id": "minecraft:music_disc_cat" - }, - { - "id": "minecraft:music_disc_blocks" - }, - { - "id": "minecraft:music_disc_chirp" - }, - { - "id": "minecraft:music_disc_far" - }, - { - "id": "minecraft:music_disc_mall" - }, - { - "id": "minecraft:music_disc_mellohi" - }, - { - "id": "minecraft:music_disc_stal" - }, - { - "id": "minecraft:music_disc_strad" - }, - { - "id": "minecraft:music_disc_ward" - }, - { - "id": "minecraft:music_disc_11" - }, - { - "id": "minecraft:music_disc_wait" - }, - { - "id": "minecraft:music_disc_otherside" - }, - { - "id": "minecraft:music_disc_5" - }, - { - "id": "minecraft:music_disc_pigstep" - }, - { - "id": "minecraft:music_disc_relic" - }, - { - "id": "minecraft:disc_fragment_5" - }, - { - "id": "minecraft:glowstone_dust" - }, - { - "id": "minecraft:glowstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRZAAAACAQAbmFtZRMAbWluZWNyYWZ0Omdsb3dzdG9uZQQJAG5hbWVfaGFzaFYqXNkefIlPAwoAbmV0d29ya19pZA0aAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:redstone_lamp", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR7AAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZHN0b25lX2xhbXAECQBuYW1lX2hhc2hJ9V80caPvEgMKAG5ldHdvcmtfaWSnAgAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:sea_lantern", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSpAAAACAQAbmFtZRUAbWluZWNyYWZ0OnNlYV9sYW50ZXJuBAkAbmFtZV9oYXNoLPsv1TX9M+QDCgBuZXR3b3JrX2lkuzMAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:oak_sign" - }, - { - "id": "minecraft:spruce_sign" - }, - { - "id": "minecraft:birch_sign" - }, - { - "id": "minecraft:jungle_sign" - }, - { - "id": "minecraft:acacia_sign" - }, - { - "id": "minecraft:dark_oak_sign" - }, - { - "id": "minecraft:mangrove_sign" - }, - { - "id": "minecraft:cherry_sign" - }, - { - "id": "minecraft:bamboo_sign" - }, - { - "id": "minecraft:crimson_sign" - }, - { - "id": "minecraft:warped_sign" - }, - { - "id": "minecraft:oak_hanging_sign" - }, - { - "id": "minecraft:spruce_hanging_sign" - }, - { - "id": "minecraft:birch_hanging_sign" - }, - { - "id": "minecraft:jungle_hanging_sign" - }, - { - "id": "minecraft:acacia_hanging_sign" - }, - { - "id": "minecraft:dark_oak_hanging_sign" - }, - { - "id": "minecraft:mangrove_hanging_sign" - }, - { - "id": "minecraft:cherry_hanging_sign" - }, - { - "id": "minecraft:bamboo_hanging_sign" - }, - { - "id": "minecraft:crimson_hanging_sign" - }, - { - "id": "minecraft:warped_hanging_sign" - }, - { - "id": "minecraft:painting" - }, - { - "id": "minecraft:frame" - }, - { - "id": "minecraft:glow_frame" - }, - { - "id": "minecraft:honey_bottle" - }, - { - "id": "minecraft:flower_pot" - }, - { - "id": "minecraft:bowl" - }, - { - "id": "minecraft:bucket" - }, - { - "id": "minecraft:milk_bucket" - }, - { - "id": "minecraft:water_bucket" - }, - { - "id": "minecraft:lava_bucket" - }, - { - "id": "minecraft:cod_bucket" - }, - { - "id": "minecraft:salmon_bucket" - }, - { - "id": "minecraft:tropical_fish_bucket" - }, - { - "id": "minecraft:pufferfish_bucket" - }, - { - "id": "minecraft:powder_snow_bucket" - }, - { - "id": "minecraft:axolotl_bucket" - }, - { - "id": "minecraft:tadpole_bucket" - }, - { - "id": "minecraft:skull", - "damage": 3 - }, - { - "id": "minecraft:skull", - "damage": 2 - }, - { - "id": "minecraft:skull", - "damage": 4 - }, - { - "id": "minecraft:skull", - "damage": 5 - }, - { - "id": "minecraft:skull" - }, - { - "id": "minecraft:skull", - "damage": 1 - }, - { - "id": "minecraft:skull", - "damage": 6 - }, - { - "id": "minecraft:beacon", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSKAAAACAQAbmFtZRAAbWluZWNyYWZ0OmJlYWNvbgQJAG5hbWVfaGFzaACwhhfSkdkHAwoAbmV0d29ya19pZDMCAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:bell", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTNAQAACAQAbmFtZQ4AbWluZWNyYWZ0OmJlbGwECQBuYW1lX2hhc2iPqsgDXRcsxAMKAG5ldHdvcmtfaWRcLwAACgYAc3RhdGVzCAoAYXR0YWNobWVudAgAc3RhbmRpbmcDCQBkaXJlY3Rpb24AAAAAAQoAdG9nZ2xlX2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:conduit", - "block_state_b64": "CgAAAwgAYmxvY2tfaWScAQAACAQAbmFtZREAbWluZWNyYWZ0OmNvbmR1aXQECQBuYW1lX2hhc2jqxKAxq2EaWQMKAG5ldHdvcmtfaWR1GwAACgYAc3RhdGVzAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:stonecutter_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTEAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lY3V0dGVyX2Jsb2NrBAkAbmFtZV9oYXNoQAXTbAM3MeYDCgBuZXR3b3JrX2lk2zMAAAoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAG5vcnRoAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:end_portal_frame", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR4AAAACAQAbmFtZRoAbWluZWNyYWZ0OmVuZF9wb3J0YWxfZnJhbWUECQBuYW1lX2hhc2gqofyUIjGOpQMKAG5ldHdvcmtfaWTHKwAACgYAc3RhdGVzARIAZW5kX3BvcnRhbF9leWVfYml0AAgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:coal" - }, - { - "id": "minecraft:charcoal" - }, - { - "id": "minecraft:diamond" - }, - { - "id": "minecraft:iron_nugget" - }, - { - "id": "minecraft:raw_iron" - }, - { - "id": "minecraft:raw_gold" - }, - { - "id": "minecraft:raw_copper" - }, - { - "id": "minecraft:copper_ingot" - }, - { - "id": "minecraft:iron_ingot" - }, - { - "id": "minecraft:netherite_scrap" - }, - { - "id": "minecraft:netherite_ingot" - }, - { - "id": "minecraft:gold_nugget" - }, - { - "id": "minecraft:gold_ingot" - }, - { - "id": "minecraft:emerald" - }, - { - "id": "minecraft:quartz" - }, - { - "id": "minecraft:clay_ball" - }, - { - "id": "minecraft:brick" - }, - { - "id": "minecraft:netherbrick" - }, - { - "id": "minecraft:prismarine_shard" - }, - { - "id": "minecraft:amethyst_shard" - }, - { - "id": "minecraft:prismarine_crystals" - }, - { - "id": "minecraft:nautilus_shell" - }, - { - "id": "minecraft:heart_of_the_sea" - }, - { - "id": "minecraft:turtle_scute" - }, - { - "id": "minecraft:phantom_membrane" - }, - { - "id": "minecraft:string" - }, - { - "id": "minecraft:feather" - }, - { - "id": "minecraft:flint" - }, - { - "id": "minecraft:gunpowder" - }, - { - "id": "minecraft:leather" - }, - { - "id": "minecraft:rabbit_hide" - }, - { - "id": "minecraft:rabbit_foot" - }, - { - "id": "minecraft:fire_charge" - }, - { - "id": "minecraft:blaze_rod" - }, - { - "id": "minecraft:blaze_powder" - }, - { - "id": "minecraft:magma_cream" - }, - { - "id": "minecraft:fermented_spider_eye" - }, - { - "id": "minecraft:echo_shard" - }, - { - "id": "minecraft:dragon_breath" - }, - { - "id": "minecraft:shulker_shell" - }, - { - "id": "minecraft:ghast_tear" - }, - { - "id": "minecraft:slime_ball" - }, - { - "id": "minecraft:ender_pearl" - }, - { - "id": "minecraft:ender_eye" - }, - { - "id": "minecraft:nether_star" - }, - { - "id": "minecraft:end_rod", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTQAAAACAQAbmFtZREAbWluZWNyYWZ0OmVuZF9yb2QECQBuYW1lX2hhc2jx/q5cEA0hmQMKAG5ldHdvcmtfaWQ0KQAACgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:lightning_rod", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ3AgAACAQAbmFtZRcAbWluZWNyYWZ0OmxpZ2h0bmluZ19yb2QECQBuYW1lX2hhc2ioXQF1xvfHNQMKAG5ldHdvcmtfaWQ+CgAACgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:end_crystal" - }, - { - "id": "minecraft:paper" - }, - { - "id": "minecraft:book" - }, - { - "id": "minecraft:writable_book" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQBAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQCAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQDAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQEAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQFAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQFAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQFAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQGAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQGAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQGAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQHAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQHAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQHAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQIAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQJAAIDAGx2bAUAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQKAAIDAGx2bAUAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQLAAIDAGx2bAUAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQMAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQMAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQNAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQNAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQOAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQOAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQOAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQPAAIDAGx2bAUAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQQAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQRAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQRAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQRAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQSAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQSAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQSAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQTAAIDAGx2bAUAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQUAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQUAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQVAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQWAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQXAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQXAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQXAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQYAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQYAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQYAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQZAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQZAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQaAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQbAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQcAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQdAAIDAGx2bAUAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQeAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQeAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQeAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQfAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQfAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQfAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQgAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQhAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQiAAIDAGx2bAQAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQjAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQjAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQjAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQkAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQkAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQkAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQlAAIDAGx2bAEAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQlAAIDAGx2bAIAAAA=" - }, - { - "id": "minecraft:enchanted_book", - "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQlAAIDAGx2bAMAAAA=" - }, - { - "id": "minecraft:oak_boat" - }, - { - "id": "minecraft:spruce_boat" - }, - { - "id": "minecraft:birch_boat" - }, - { - "id": "minecraft:jungle_boat" - }, - { - "id": "minecraft:acacia_boat" - }, - { - "id": "minecraft:dark_oak_boat" - }, - { - "id": "minecraft:mangrove_boat" - }, - { - "id": "minecraft:cherry_boat" - }, - { - "id": "minecraft:bamboo_raft" - }, - { - "id": "minecraft:oak_chest_boat" - }, - { - "id": "minecraft:spruce_chest_boat" - }, - { - "id": "minecraft:birch_chest_boat" - }, - { - "id": "minecraft:jungle_chest_boat" - }, - { - "id": "minecraft:acacia_chest_boat" - }, - { - "id": "minecraft:dark_oak_chest_boat" - }, - { - "id": "minecraft:mangrove_chest_boat" - }, - { - "id": "minecraft:cherry_chest_boat" - }, - { - "id": "minecraft:bamboo_chest_raft" - }, - { - "id": "minecraft:rail", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRCAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnJhaWwECQBuYW1lX2hhc2hUzmhUXYJDUQMKAG5ldHdvcmtfaWQxGgAACgYAc3RhdGVzAw4AcmFpbF9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:golden_rail", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQbAAAACAQAbmFtZRUAbWluZWNyYWZ0OmdvbGRlbl9yYWlsBAkAbmFtZV9oYXNoOoV5MaKipoUDCgBuZXR3b3JrX2lklSMAAAoGAHN0YXRlcwENAHJhaWxfZGF0YV9iaXQAAw4AcmFpbF9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:detector_rail", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQcAAAACAQAbmFtZRcAbWluZWNyYWZ0OmRldGVjdG9yX3JhaWwECQBuYW1lX2hhc2gVUk31qOysUQMKAG5ldHdvcmtfaWQGGwAACgYAc3RhdGVzAQ0AcmFpbF9kYXRhX2JpdAADDgByYWlsX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:activator_rail", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR+AAAACAQAbmFtZRgAbWluZWNyYWZ0OmFjdGl2YXRvcl9yYWlsBAkAbmFtZV9oYXNosIL91qriCRkDCgBuZXR3b3JrX2lkHgQAAAoGAHN0YXRlcwENAHJhaWxfZGF0YV9iaXQAAw4AcmFpbF9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:minecart" - }, - { - "id": "minecraft:chest_minecart" - }, - { - "id": "minecraft:hopper_minecart" - }, - { - "id": "minecraft:tnt_minecart" - }, - { - "id": "minecraft:redstone" - }, - { - "id": "minecraft:redstone_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSYAAAACAQAbmFtZRgAbWluZWNyYWZ0OnJlZHN0b25lX2Jsb2NrBAkAbmFtZV9oYXNoRhULL0r8o0sDCgBuZXR3b3JrX2lkIxgAAAoGAHN0YXRlcwADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:redstone_torch", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRMAAAACAQAbmFtZRgAbWluZWNyYWZ0OnJlZHN0b25lX3RvcmNoBAkAbmFtZV9oYXNoizFRjpYMIDgDCgBuZXR3b3JrX2lkgxUAAAoGAHN0YXRlcwgWAHRvcmNoX2ZhY2luZ19kaXJlY3Rpb24HAHVua25vd24AAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:lever", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRFAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmxldmVyBAkAbmFtZV9oYXNoGMJeLJsUMLYDCgBuZXR3b3JrX2lktS0AAAoGAHN0YXRlcwgPAGxldmVyX2RpcmVjdGlvbg4AZG93bl9lYXN0X3dlc3QBCABvcGVuX2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:wooden_button", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSPAAAACAQAbmFtZRcAbWluZWNyYWZ0Ondvb2Rlbl9idXR0b24ECQBuYW1lX2hhc2hR7PgSTQt0sQMKAG5ldHdvcmtfaWQULQAACgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:spruce_button", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSPAQAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9idXR0b24ECQBuYW1lX2hhc2jBW9Z8aYE7YQMKAG5ldHdvcmtfaWT4GwAACgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:birch_button", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSMAQAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX2J1dHRvbgQJAG5hbWVfaGFzaJXYgGuSHbTwAwoAbmV0d29ya19pZMU0AAAKBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:jungle_button", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSOAQAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9idXR0b24ECQBuYW1lX2hhc2iCgNANcJs+BQMKAG5ldHdvcmtfaWSAAAAACgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:acacia_button", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAQAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9idXR0b24ECQBuYW1lX2hhc2gVvmcT7LTO0wMKAG5ldHdvcmtfaWRqMgAACgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:dark_oak_button", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSNAQAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX2J1dHRvbgQJAG5hbWVfaGFzaIV10ZGGrCIEAwoAbmV0d29ya19pZGYAAAAKBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:mangrove_button", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTmAgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX2J1dHRvbgQJAG5hbWVfaGFzaNzeYYKLgOzJAwoAbmV0d29ya19pZP4vAAAKBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:cherry_button", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQRAwAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9idXR0b24ECQBuYW1lX2hhc2j2/IHjeAbUcwMKAG5ldHdvcmtfaWRQHQAACgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:bamboo_button", - "block_state_b64": "CgAAAwgAYmxvY2tfaWT+AgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19idXR0b24ECQBuYW1lX2hhc2j7AddMi+6nsgMKAG5ldHdvcmtfaWSOLQAACgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:stone_button", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRNAAAACAQAbmFtZRYAbWluZWNyYWZ0OnN0b25lX2J1dHRvbgQJAG5hbWVfaGFzaM4ejMctmvohAwoAbmV0d29ya19pZEkFAAAKBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:crimson_button", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAgAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fYnV0dG9uBAkAbmFtZV9oYXNofnjYHaYIeWgDCgBuZXR3b3JrX2lkdxwAAAoGAHN0YXRlcwESAGJ1dHRvbl9wcmVzc2VkX2JpdAADEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:warped_button", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQEAgAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9idXR0b24ECQBuYW1lX2hhc2jwkV2EU6Cn1QMKAG5ldHdvcmtfaWR8MgAACgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:polished_blackstone_button", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQnAgAACAQAbmFtZSQAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnV0dG9uBAkAbmFtZV9oYXNojmxzQKS0S/EDCgBuZXR3b3JrX2lk3TQAAAoGAHN0YXRlcwESAGJ1dHRvbl9wcmVzc2VkX2JpdAADEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:tripwire_hook", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAAAACAQAbmFtZRcAbWluZWNyYWZ0OnRyaXB3aXJlX2hvb2sECQBuYW1lX2hhc2gQdp+oGZLNnAMKAG5ldHdvcmtfaWR7KQAACgYAc3RhdGVzAQwAYXR0YWNoZWRfYml0AAMJAGRpcmVjdGlvbgAAAAABCwBwb3dlcmVkX2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:wooden_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRIAAAACAQAbmFtZR8AbWluZWNyYWZ0Ondvb2Rlbl9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaGkGs5kCuA74AwoAbmV0d29ya19pZBM2AAAKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:spruce_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSZAQAACAQAbmFtZR8AbWluZWNyYWZ0OnNwcnVjZV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaNmwuq549fJKAwoAbmV0d29ya19pZBEYAAAKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:birch_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSWAQAACAQAbmFtZR4AbWluZWNyYWZ0OmJpcmNoX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNorQkT9kDdlTwDCgBuZXR3b3JrX2lkNBcAAAoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:jungle_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSYAQAACAQAbmFtZR8AbWluZWNyYWZ0Omp1bmdsZV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaJ7DcteCkb8/AwoAbmV0d29ya19pZIoXAAAKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:acacia_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSVAQAACAQAbmFtZR8AbWluZWNyYWZ0OmFjYWNpYV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaC2frZtfoYqCAwoAbmV0d29ya19pZD4jAAAKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:dark_oak_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSXAQAACAQAbmFtZSEAbWluZWNyYWZ0OmRhcmtfb2FrX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoHUCJsTy52pwDCgBuZXR3b3JrX2lkpSkAAAoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:mangrove_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTpAgAACAQAbmFtZSEAbWluZWNyYWZ0Om1hbmdyb3ZlX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoiDsTfJaX100DCgBuZXR3b3JrX2lk/BkAAAoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:cherry_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQZAwAACAQAbmFtZR8AbWluZWNyYWZ0OmNoZXJyeV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaALMqYEZDUQHAwoAbmV0d29ya19pZJoAAAAKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:bamboo_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQBAwAACAQAbmFtZR8AbWluZWNyYWZ0OmJhbWJvb19wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaNvxJ7NIAaqlAwoAbmV0d29ya19pZM8rAAAKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:crimson_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQFAgAACAQAbmFtZSAAbWluZWNyYWZ0OmNyaW1zb25fcHJlc3N1cmVfcGxhdGUECQBuYW1lX2hhc2hqBDVDAd31/gMKAG5ldHdvcmtfaWQANwAACgYAc3RhdGVzAw8AcmVkc3RvbmVfc2lnbmFsAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:warped_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAgAACAQAbmFtZR8AbWluZWNyYWZ0OndhcnBlZF9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaBxFoQksWtYUAwoAbmV0d29ya19pZMECAAAKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:stone_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRGAAAACAQAbmFtZR4AbWluZWNyYWZ0OnN0b25lX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNounJuTBUTrU8DCgBuZXR3b3JrX2lkDhoAAAoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:light_weighted_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSTAAAACAQAbmFtZScAbWluZWNyYWZ0OmxpZ2h0X3dlaWdodGVkX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoOyOJkNxLtkEDCgBuZXR3b3JrX2lkqRcAAAoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:heavy_weighted_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSUAAAACAQAbmFtZScAbWluZWNyYWZ0OmhlYXZ5X3dlaWdodGVkX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoltgDmDvTajUDCgBuZXR3b3JrX2lkLQoAAAoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:polished_blackstone_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAgAACAQAbmFtZSwAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfcHJlc3N1cmVfcGxhdGUECQBuYW1lX2hhc2h65Ci6/CeGqwMKAG5ldHdvcmtfaWRxLAAACgYAc3RhdGVzAw8AcmVkc3RvbmVfc2lnbmFsAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:observer", - "block_state_b64": "CgAAAwgAYmxvY2tfaWT7AAAACAQAbmFtZRIAbWluZWNyYWZ0Om9ic2VydmVyBAkAbmFtZV9oYXNoYhlh1lpmHTgDCgBuZXR3b3JrX2lkdxUAAAoGAHN0YXRlcwgaAG1pbmVjcmFmdDpmYWNpbmdfZGlyZWN0aW9uBABkb3duAQsAcG93ZXJlZF9iaXQAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:daylight_detector", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSXAAAACAQAbmFtZRsAbWluZWNyYWZ0OmRheWxpZ2h0X2RldGVjdG9yBAkAbmFtZV9oYXNoV0F0s7B7PVgDCgBuZXR3b3JrX2lkUhsAAAoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:repeater" - }, - { - "id": "minecraft:comparator" - }, - { - "id": "minecraft:hopper" - }, - { - "id": "minecraft:dropper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR9AAAACAQAbmFtZREAbWluZWNyYWZ0OmRyb3BwZXIECQBuYW1lX2hhc2joXP7XqU0l3QMKAG5ldHdvcmtfaWQTMwAACgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgMAAAABDQB0cmlnZ2VyZWRfYml0AAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:dispenser", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQXAAAACAQAbmFtZRMAbWluZWNyYWZ0OmRpc3BlbnNlcgQJAG5hbWVfaGFzaP1RR+zAbYP2AwoAbmV0d29ya19pZO81AAAKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAwAAAAENAHRyaWdnZXJlZF9iaXQAAAMHAHZlcnNpb24BPBQBAA==" - }, - { - "id": "minecraft:piston", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQhAAAACAQAbmFtZRAAbWluZWNyYWZ0OnBpc3RvbgQJAG5hbWVfaGFzaDs3AFh1fL0uAwoAbmV0d29ya19pZE0JAAAKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAQAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:sticky_piston", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQdAAAACAQAbmFtZRcAbWluZWNyYWZ0OnN0aWNreV9waXN0b24ECQBuYW1lX2hhc2hPFJFJSiJ0ZQMKAG5ldHdvcmtfaWQrHAAACgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgEAAAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:tnt", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQuAAAACAQAbmFtZQ0AbWluZWNyYWZ0OnRudAQJAG5hbWVfaGFzaEYOHwCvJH29AwoAbmV0d29ya19pZIMuAAAKBgBzdGF0ZXMBFABhbGxvd191bmRlcndhdGVyX2JpdAABCwBleHBsb2RlX2JpdAAAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:name_tag" - }, - { - "id": "minecraft:loom", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTLAQAACAQAbmFtZQ4AbWluZWNyYWZ0Omxvb20ECQBuYW1lX2hhc2i7DKjAXNq8TAMKAG5ldHdvcmtfaWTVGQAACgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:banner" - }, - { - "id": "minecraft:banner", - "damage": 8 - }, - { - "id": "minecraft:banner", - "damage": 7 - }, - { - "id": "minecraft:banner", - "damage": 15 - }, - { - "id": "minecraft:banner", - "damage": 12 - }, - { - "id": "minecraft:banner", - "damage": 14 - }, - { - "id": "minecraft:banner", - "damage": 1 - }, - { - "id": "minecraft:banner", - "damage": 4 - }, - { - "id": "minecraft:banner", - "damage": 5 - }, - { - "id": "minecraft:banner", - "damage": 13 - }, - { - "id": "minecraft:banner", - "damage": 9 - }, - { - "id": "minecraft:banner", - "damage": 3 - }, - { - "id": "minecraft:banner", - "damage": 11 - }, - { - "id": "minecraft:banner", - "damage": 10 - }, - { - "id": "minecraft:banner", - "damage": 2 - }, - { - "id": "minecraft:banner", - "damage": 6 - }, - { - "id": "minecraft:banner", - "damage": 15, - "nbt_b64": "CgAAAwQAVHlwZQEAAAAA" - }, - { - "id": "minecraft:creeper_banner_pattern" - }, - { - "id": "minecraft:skull_banner_pattern" - }, - { - "id": "minecraft:flower_banner_pattern" - }, - { - "id": "minecraft:mojang_banner_pattern" - }, - { - "id": "minecraft:field_masoned_banner_pattern" - }, - { - "id": "minecraft:bordure_indented_banner_pattern" - }, - { - "id": "minecraft:piglin_banner_pattern" - }, - { - "id": "minecraft:globe_banner_pattern" - }, - { - "id": "minecraft:angler_pottery_sherd" - }, - { - "id": "minecraft:archer_pottery_sherd" - }, - { - "id": "minecraft:arms_up_pottery_sherd" - }, - { - "id": "minecraft:blade_pottery_sherd" - }, - { - "id": "minecraft:brewer_pottery_sherd" - }, - { - "id": "minecraft:burn_pottery_sherd" - }, - { - "id": "minecraft:danger_pottery_sherd" - }, - { - "id": "minecraft:explorer_pottery_sherd" - }, - { - "id": "minecraft:friend_pottery_sherd" - }, - { - "id": "minecraft:heart_pottery_sherd" - }, - { - "id": "minecraft:heartbreak_pottery_sherd" - }, - { - "id": "minecraft:howl_pottery_sherd" - }, - { - "id": "minecraft:miner_pottery_sherd" - }, - { - "id": "minecraft:mourner_pottery_sherd" - }, - { - "id": "minecraft:plenty_pottery_sherd" - }, - { - "id": "minecraft:prize_pottery_sherd" - }, - { - "id": "minecraft:sheaf_pottery_sherd" - }, - { - "id": "minecraft:shelter_pottery_sherd" - }, - { - "id": "minecraft:skull_pottery_sherd" - }, - { - "id": "minecraft:snort_pottery_sherd" - }, - { - "id": "minecraft:netherite_upgrade_smithing_template" - }, - { - "id": "minecraft:sentry_armor_trim_smithing_template" - }, - { - "id": "minecraft:vex_armor_trim_smithing_template" - }, - { - "id": "minecraft:wild_armor_trim_smithing_template" - }, - { - "id": "minecraft:coast_armor_trim_smithing_template" - }, - { - "id": "minecraft:dune_armor_trim_smithing_template" - }, - { - "id": "minecraft:wayfinder_armor_trim_smithing_template" - }, - { - "id": "minecraft:shaper_armor_trim_smithing_template" - }, - { - "id": "minecraft:raiser_armor_trim_smithing_template" - }, - { - "id": "minecraft:host_armor_trim_smithing_template" - }, - { - "id": "minecraft:ward_armor_trim_smithing_template" - }, - { - "id": "minecraft:silence_armor_trim_smithing_template" - }, - { - "id": "minecraft:tide_armor_trim_smithing_template" - }, - { - "id": "minecraft:snout_armor_trim_smithing_template" - }, - { - "id": "minecraft:rib_armor_trim_smithing_template" - }, - { - "id": "minecraft:eye_armor_trim_smithing_template" - }, - { - "id": "minecraft:spire_armor_trim_smithing_template" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwAAAAAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAABwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAIBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAHBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAPBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAMBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAOBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAABBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAEBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAFBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAANBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAJBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAADBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAALBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAKBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAACBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_rocket", - "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwoBAAAABw0ARmlyZXdvcmtDb2xvcgEAAAAGBwwARmlyZXdvcmtGYWRlAAAAAAEPAEZpcmV3b3JrRmxpY2tlcgABDQBGaXJld29ya1RyYWlsAAEMAEZpcmV3b3JrVHlwZQAAAQYARmxpZ2h0AQAA" - }, - { - "id": "minecraft:firework_star", - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yIR0d/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 8, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yUk9H/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 7, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yl52d/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 15, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9y8PDw/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 12, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9y2rM6/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 14, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yHYD5/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 1, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yJi6w/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 4, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABAcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yqkQ8/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 5, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yuDKJ/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 13, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yvU7H/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 9, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACQcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yqovz/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 3, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yMlSD/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 11, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACwcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yPdj+/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 10, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yH8eA/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 2, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9yFnxe/wA=" - }, - { - "id": "minecraft:firework_star", - "damage": 6, - "nbt_b64": "CgAACg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABgcMAEZpcmV3b3JrRmFkZQAAAAABDwBGaXJld29ya0ZsaWNrZXIAAQ0ARmlyZXdvcmtUcmFpbAABDABGaXJld29ya1R5cGUAAAMLAGN1c3RvbUNvbG9ynJwW/wA=" - }, - { - "id": "minecraft:chain" - }, - { - "id": "minecraft:target", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTuAQAACAQAbmFtZRAAbWluZWNyYWZ0OnRhcmdldAQJAG5hbWVfaGFzaJc66SVbYlaxAwoAbmV0d29ya19pZBMtAAAKBgBzdGF0ZXMAAwcAdmVyc2lvbgE8FAEA" - }, - { - "id": "minecraft:decorated_pot", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAwAACAQAbmFtZRcAbWluZWNyYWZ0OmRlY29yYXRlZF9wb3QECQBuYW1lX2hhc2jjQgckn8VTvwMKAG5ldHdvcmtfaWSWLgAACgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uATwUAQA=" - }, - { - "id": "minecraft:lodestone_compass" - }, - { - "id": "minecraft:wither_spawn_egg" - }, - { - "id": "minecraft:ender_dragon_spawn_egg" - } - ] -} \ No newline at end of file diff --git a/core/src/main/resources/bedrock/creative_items.1_20_70.json b/core/src/main/resources/bedrock/creative_items.1_21_0.json similarity index 78% rename from core/src/main/resources/bedrock/creative_items.1_20_70.json rename to core/src/main/resources/bedrock/creative_items.1_21_0.json index ed498b782..4bd0ab60e 100644 --- a/core/src/main/resources/bedrock/creative_items.1_20_70.json +++ b/core/src/main/resources/bedrock/creative_items.1_21_0.json @@ -2,443 +2,443 @@ "items": [ { "id": "minecraft:oak_planks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQFAAAACAQAbmFtZRQAbWluZWNyYWZ0Om9ha19wbGFua3MECQBuYW1lX2hhc2ilMDLR92rQ4wMKAG5ldHdvcmtfaWS2GotyCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQFAAAACAQAbmFtZRQAbWluZWNyYWZ0Om9ha19wbGFua3MECQBuYW1lX2hhc2ilMDLR92rQ4wMKAG5ldHdvcmtfaWS2GotyCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:spruce_planks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTiAwAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9wbGFua3MECQBuYW1lX2hhc2iumBkmFGFE8gMKAG5ldHdvcmtfaWSo8TFgCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTiAwAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9wbGFua3MECQBuYW1lX2hhc2iumBkmFGFE8gMKAG5ldHdvcmtfaWSo8TFgCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:birch_planks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTjAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX3BsYW5rcwQJAG5hbWVfaGFzaLrrAKJqV2WFAwoAbmV0d29ya19pZL+e3ZAKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTjAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX3BsYW5rcwQJAG5hbWVfaGFzaLrrAKJqV2WFAwoAbmV0d29ya19pZL+e3ZAKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:jungle_planks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTkAwAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9wbGFua3MECQBuYW1lX2hhc2iBM3k4T3FAugMKAG5ldHdvcmtfaWSXUmBCCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTkAwAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9wbGFua3MECQBuYW1lX2hhc2iBM3k4T3FAugMKAG5ldHdvcmtfaWSXUmBCCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:acacia_planks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTlAwAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9wbGFua3MECQBuYW1lX2hhc2g60edJxO5/aAMKAG5ldHdvcmtfaWTUXozECgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTlAwAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9wbGFua3MECQBuYW1lX2hhc2g60edJxO5/aAMKAG5ldHdvcmtfaWTUXozECgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:dark_oak_planks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTmAwAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX3BsYW5rcwQJAG5hbWVfaGFzaAr64wkQ9cA7AwoAbmV0d29ya19pZFbMeR0KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTmAwAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX3BsYW5rcwQJAG5hbWVfaGFzaAr64wkQ9cA7AwoAbmV0d29ya19pZFbMeR0KBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:mangrove_planks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTlAgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX3BsYW5rcwQJAG5hbWVfaGFzaPvLtcEA0F8xAwoAbmV0d29ya19pZEvnlCYKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTlAgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX3BsYW5rcwQJAG5hbWVfaGFzaPvLtcEA0F8xAwoAbmV0d29ya19pZEvnlCYKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:cherry_planks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAwAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9wbGFua3MECQBuYW1lX2hhc2hNIvVh/lVW7gMKAG5ldHdvcmtfaWQTXpRoCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAwAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9wbGFua3MECQBuYW1lX2hhc2hNIvVh/lVW7gMKAG5ldHdvcmtfaWQTXpRoCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:bamboo_planks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWT9AgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19wbGFua3MECQBuYW1lX2hhc2gYnjNz7SCCjgMKAG5ldHdvcmtfaWTi8ySSCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWT9AgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19wbGFua3MECQBuYW1lX2hhc2gYnjNz7SCCjgMKAG5ldHdvcmtfaWTi8ySSCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:bamboo_mosaic", - "block_state_b64": "CgAAAwgAYmxvY2tfaWT8AgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19tb3NhaWMECQBuYW1lX2hhc2izSEgiMKOp/AMKAG5ldHdvcmtfaWQZ/p8xCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWT8AgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19tb3NhaWMECQBuYW1lX2hhc2izSEgiMKOp/AMKAG5ldHdvcmtfaWQZ/p8xCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:crimson_planks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTxAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fcGxhbmtzBAkAbmFtZV9oYXNoJc5IKqNXJnwDCgBuZXR3b3JrX2lkwtJDdQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTxAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fcGxhbmtzBAkAbmFtZV9oYXNoJc5IKqNXJnwDCgBuZXR3b3JrX2lkwtJDdQoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:warped_planks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTyAQAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9wbGFua3MECQBuYW1lX2hhc2g3yGXEWhe6LgMKAG5ldHdvcmtfaWStTABvCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTyAQAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9wbGFua3MECQBuYW1lX2hhc2g3yGXEWhe6LgMKAG5ldHdvcmtfaWStTABvCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWSE4JosCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCwBjb2JibGVzdG9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWSE4JosCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCwBjb2JibGVzdG9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWTUvV6XCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlEQBtb3NzeV9jb2JibGVzdG9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWTUvV6XCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlEQBtb3NzeV9jb2JibGVzdG9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWT4opb2CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlBwBncmFuaXRlCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWT4opb2CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlBwBncmFuaXRlCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQAMQTVCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlBwBkaW9yaXRlCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQAMQTVCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlBwBkaW9yaXRlCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQIbDOcCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCABhbmRlc2l0ZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQIbDOcCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCABhbmRlc2l0ZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWSZKhusCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCQBzYW5kc3RvbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWSZKhusCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCQBzYW5kc3RvbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWSp4zgCCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlDQByZWRfc2FuZHN0b25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWSp4zgCCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlDQByZWRfc2FuZHN0b25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRbqVHTCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCwBzdG9uZV9icmljawgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRbqVHTCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCwBzdG9uZV9icmljawgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRr0ZT/CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlEQBtb3NzeV9zdG9uZV9icmljawgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRr0ZT/CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlEQBtb3NzeV9zdG9uZV9icmljawgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRnLis3CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlBQBicmljawgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRnLis3CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlBQBicmljawgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQNLzfSCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlDABuZXRoZXJfYnJpY2sIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQNLzfSCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlDABuZXRoZXJfYnJpY2sIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQ5h0xwCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlEAByZWRfbmV0aGVyX2JyaWNrCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWQ5h0xwCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlEAByZWRfbmV0aGVyX2JyaWNrCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWS9J0B2CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCQBlbmRfYnJpY2sIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWS9J0B2CgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCQBlbmRfYnJpY2sIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:cobblestone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRPbkJeCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCgBwcmlzbWFyaW5lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3dhbGwECQBuYW1lX2hhc2hZu/xE7lYtNgMKAG5ldHdvcmtfaWRPbkJeCgYAc3RhdGVzCA8Ad2FsbF9ibG9ja190eXBlCgBwcmlzbWFyaW5lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:blackstone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQUAgAACAQAbmFtZRkAbWluZWNyYWZ0OmJsYWNrc3RvbmVfd2FsbAQJAG5hbWVfaGFzaMP8XppUSU1RAwoAbmV0d29ya19pZMbeBBsKBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQUAgAACAQAbmFtZRkAbWluZWNyYWZ0OmJsYWNrc3RvbmVfd2FsbAQJAG5hbWVfaGFzaMP8XppUSU1RAwoAbmV0d29ya19pZMbeBBsKBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:polished_blackstone_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQoAgAACAQAbmFtZSIAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfd2FsbAQJAG5hbWVfaGFzaP6SwV08YwzAAwoAbmV0d29ya19pZAJLsz8KBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQoAgAACAQAbmFtZSIAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfd2FsbAQJAG5hbWVfaGFzaP6SwV08YwzAAwoAbmV0d29ya19pZAJLsz8KBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:polished_blackstone_brick_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQVAgAACAQAbmFtZSgAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tfd2FsbAQJAG5hbWVfaGFzaBBIDZbHxiEzAwoAbmV0d29ya19pZEbLV8cKBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQVAgAACAQAbmFtZSgAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tfd2FsbAQJAG5hbWVfaGFzaBBIDZbHxiEzAwoAbmV0d29ya19pZEbLV8cKBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:cobbled_deepslate_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR9AgAACAQAbmFtZSAAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlX3dhbGwECQBuYW1lX2hhc2iECY5oKxeT+gMKAG5ldHdvcmtfaWRCnPrFCgYAc3RhdGVzCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWR9AgAACAQAbmFtZSAAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlX3dhbGwECQBuYW1lX2hhc2iECY5oKxeT+gMKAG5ldHdvcmtfaWRCnPrFCgYAc3RhdGVzCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:deepslate_tile_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAgAACAQAbmFtZR0AbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlX3dhbGwECQBuYW1lX2hhc2jz7N+PeuEXgQMKAG5ldHdvcmtfaWTqw4s4CgYAc3RhdGVzCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAgAACAQAbmFtZR0AbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlX3dhbGwECQBuYW1lX2hhc2jz7N+PeuEXgQMKAG5ldHdvcmtfaWTqw4s4CgYAc3RhdGVzCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfZWFzdAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX25vcnRoBABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfc291dGgEAG5vbmUIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV93ZXN0BABub25lAQ0Ad2FsbF9wb3N0X2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:polished_deepslate_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSBAgAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZV93YWxsBAkAbmFtZV9oYXNoHxjTdj9pevMDCgBuZXR3b3JrX2lkIvBYYwoGAHN0YXRlcwgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSBAgAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZV93YWxsBAkAbmFtZV9oYXNoHxjTdj9pevMDCgBuZXR3b3JrX2lkIvBYYwoGAHN0YXRlcwgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:deepslate_brick_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSJAgAACAQAbmFtZR4AbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja193YWxsBAkAbmFtZV9oYXNoEs3EQrjroyEDCgBuZXR3b3JrX2lkwlrCGwoGAHN0YXRlcwgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSJAgAACAQAbmFtZR4AbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja193YWxsBAkAbmFtZV9oYXNoEs3EQrjroyEDCgBuZXR3b3JrX2lkwlrCGwoGAHN0YXRlcwgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:mud_brick_wall", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTgAgAACAQAbmFtZRgAbWluZWNyYWZ0Om11ZF9icmlja193YWxsBAkAbmFtZV9oYXNov9b98ATpUSwDCgBuZXR3b3JrX2lkH/1WZQoGAHN0YXRlcwgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTgAgAACAQAbmFtZRgAbWluZWNyYWZ0Om11ZF9icmlja193YWxsBAkAbmFtZV9oYXNov9b98ATpUSwDCgBuZXR3b3JrX2lkH/1WZQoGAHN0YXRlcwgZAHdhbGxfY29ubmVjdGlvbl90eXBlX2Vhc3QEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9ub3J0aAQAbm9uZQgaAHdhbGxfY29ubmVjdGlvbl90eXBlX3NvdXRoBABub25lCBkAd2FsbF9jb25uZWN0aW9uX3R5cGVfd2VzdAQAbm9uZQENAHdhbGxfcG9zdF9iaXQAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:oak_fence", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRVAAAACAQAbmFtZRMAbWluZWNyYWZ0Om9ha19mZW5jZQQJAG5hbWVfaGFzaGEmid7AaCWRAwoAbmV0d29ya19pZDvPEXcKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRVAAAACAQAbmFtZRMAbWluZWNyYWZ0Om9ha19mZW5jZQQJAG5hbWVfaGFzaGEmid7AaCWRAwoAbmV0d29ya19pZDvPEXcKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:spruce_fence", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRCAwAACAQAbmFtZRYAbWluZWNyYWZ0OnNwcnVjZV9mZW5jZQQJAG5hbWVfaGFzaPQCm+aX1ZQeAwoAbmV0d29ya19pZD1QUEoKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRCAwAACAQAbmFtZRYAbWluZWNyYWZ0OnNwcnVjZV9mZW5jZQQJAG5hbWVfaGFzaPQCm+aX1ZQeAwoAbmV0d29ya19pZD1QUEoKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:birch_fence", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ/AwAACAQAbmFtZRUAbWluZWNyYWZ0OmJpcmNoX2ZlbmNlBAkAbmFtZV9oYXNo6CJ2ATpANfgDCgBuZXR3b3JrX2lkmCUV2QoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ/AwAACAQAbmFtZRUAbWluZWNyYWZ0OmJpcmNoX2ZlbmNlBAkAbmFtZV9oYXNo6CJ2ATpANfgDCgBuZXR3b3JrX2lkmCUV2QoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:jungle_fence", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRBAwAACAQAbmFtZRYAbWluZWNyYWZ0Omp1bmdsZV9mZW5jZQQJAG5hbWVfaGFzaOX4cD9uAmsdAwoAbmV0d29ya19pZHz1VxkKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRBAwAACAQAbmFtZRYAbWluZWNyYWZ0Omp1bmdsZV9mZW5jZQQJAG5hbWVfaGFzaOX4cD9uAmsdAwoAbmV0d29ya19pZHz1VxkKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:acacia_fence", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ+AwAACAQAbmFtZRYAbWluZWNyYWZ0OmFjYWNpYV9mZW5jZQQJAG5hbWVfaGFzaGjn+RlKVDH6AwoAbmV0d29ya19pZNVGubwKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ+AwAACAQAbmFtZRYAbWluZWNyYWZ0OmFjYWNpYV9mZW5jZQQJAG5hbWVfaGFzaGjn+RlKVDH6AwoAbmV0d29ya19pZNVGubwKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:dark_oak_fence", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRAAwAACAQAbmFtZRgAbWluZWNyYWZ0OmRhcmtfb2FrX2ZlbmNlBAkAbmFtZV9oYXNoGPj0gCgM0c0DCgBuZXR3b3JrX2lk2w+gEwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRAAwAACAQAbmFtZRgAbWluZWNyYWZ0OmRhcmtfb2FrX2ZlbmNlBAkAbmFtZV9oYXNoGPj0gCgM0c0DCgBuZXR3b3JrX2lk2w+gEwoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:mangrove_fence", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTqAgAACAQAbmFtZRgAbWluZWNyYWZ0Om1hbmdyb3ZlX2ZlbmNlBAkAbmFtZV9oYXNowwAd7tPu9bsDCgBuZXR3b3JrX2lkKEcd0goGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTqAgAACAQAbmFtZRgAbWluZWNyYWZ0Om1hbmdyb3ZlX2ZlbmNlBAkAbmFtZV9oYXNowwAd7tPu9bsDCgBuZXR3b3JrX2lkKEcd0goGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:cherry_fence", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQTAwAACAQAbmFtZRYAbWluZWNyYWZ0OmNoZXJyeV9mZW5jZQQJAG5hbWVfaGFzaFmtUfHfTxcxAwoAbmV0d29ya19pZPCBxAIKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQTAwAACAQAbmFtZRYAbWluZWNyYWZ0OmNoZXJyeV9mZW5jZQQJAG5hbWVfaGFzaFmtUfHfTxcxAwoAbmV0d29ya19pZPCBxAIKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:bamboo_fence", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQCAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJhbWJvb19mZW5jZQQJAG5hbWVfaGFzaCKRbxfXsfkiAwoAbmV0d29ya19pZJNXKFcKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQCAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJhbWJvb19mZW5jZQQJAG5hbWVfaGFzaCKRbxfXsfkiAwoAbmV0d29ya19pZJNXKFcKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:nether_brick_fence", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRxAAAACAQAbmFtZRwAbWluZWNyYWZ0Om5ldGhlcl9icmlja19mZW5jZQQJAG5hbWVfaGFzaA6030ngawxcAwoAbmV0d29ya19pZLnjLF4KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRxAAAACAQAbmFtZRwAbWluZWNyYWZ0Om5ldGhlcl9icmlja19mZW5jZQQJAG5hbWVfaGFzaA6030ngawxcAwoAbmV0d29ya19pZLnjLF4KBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:crimson_fence", - "block_state_b64": "CgAAAwgAYmxvY2tfaWT/AQAACAQAbmFtZRcAbWluZWNyYWZ0OmNyaW1zb25fZmVuY2UECQBuYW1lX2hhc2jhUhKv1HGj9AMKAG5ldHdvcmtfaWR3OH3OCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWT/AQAACAQAbmFtZRcAbWluZWNyYWZ0OmNyaW1zb25fZmVuY2UECQBuYW1lX2hhc2jhUhKv1HGj9AMKAG5ldHdvcmtfaWR3OH3OCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:warped_fence", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQAAgAACAQAbmFtZRYAbWluZWNyYWZ0OndhcnBlZF9mZW5jZQQJAG5hbWVfaGFzaJfb3/YuKmOWAwoAbmV0d29ya19pZCpaGC8KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQAAgAACAQAbmFtZRYAbWluZWNyYWZ0OndhcnBlZF9mZW5jZQQJAG5hbWVfaGFzaJfb3/YuKmOWAwoAbmV0d29ya19pZCpaGC8KBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:fence_gate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRrAAAACAQAbmFtZRQAbWluZWNyYWZ0OmZlbmNlX2dhdGUECQBuYW1lX2hhc2hTxpjEDmRzAwMKAG5ldHdvcmtfaWR+T9kTCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRrAAAACAQAbmFtZRQAbWluZWNyYWZ0OmZlbmNlX2dhdGUECQBuYW1lX2hhc2hTxpjEDmRzAwMKAG5ldHdvcmtfaWR+T9kTCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:spruce_fence_gate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS3AAAACAQAbmFtZRsAbWluZWNyYWZ0OnNwcnVjZV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoanTVB84HRbkDCgBuZXR3b3JrX2lkEnw5egoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWS3AAAACAQAbmFtZRsAbWluZWNyYWZ0OnNwcnVjZV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoanTVB84HRbkDCgBuZXR3b3JrX2lkEnw5egoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:birch_fence_gate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS4AAAACAQAbmFtZRoAbWluZWNyYWZ0OmJpcmNoX2ZlbmNlX2dhdGUECQBuYW1lX2hhc2jmfPklI8azSwMKAG5ldHdvcmtfaWQL77/BCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWS4AAAACAQAbmFtZRoAbWluZWNyYWZ0OmJpcmNoX2ZlbmNlX2dhdGUECQBuYW1lX2hhc2jmfPklI8azSwMKAG5ldHdvcmtfaWQL77/BCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:jungle_fence_gate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS5AAAACAQAbmFtZRsAbWluZWNyYWZ0Omp1bmdsZV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNobYVQkfBomIcDCgBuZXR3b3JrX2lkA1zgtgoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWS5AAAACAQAbmFtZRsAbWluZWNyYWZ0Omp1bmdsZV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNobYVQkfBomIcDCgBuZXR3b3JrX2lkA1zgtgoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:acacia_fence_gate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS7AAAACAQAbmFtZRsAbWluZWNyYWZ0OmFjYWNpYV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoZnrLUx/XSekDCgBuZXR3b3JrX2lkHg/kTgoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWS7AAAACAQAbmFtZRsAbWluZWNyYWZ0OmFjYWNpYV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoZnrLUx/XSekDCgBuZXR3b3JrX2lkHg/kTgoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:dark_oak_fence_gate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS6AAAACAQAbmFtZR0AbWluZWNyYWZ0OmRhcmtfb2FrX2ZlbmNlX2dhdGUECQBuYW1lX2hhc2j2PTvdJJHcVQMKAG5ldHdvcmtfaWTwjOCeCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWS6AAAACAQAbmFtZR0AbWluZWNyYWZ0OmRhcmtfb2FrX2ZlbmNlX2dhdGUECQBuYW1lX2hhc2j2PTvdJJHcVQMKAG5ldHdvcmtfaWTwjOCeCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:mangrove_fence_gate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTrAgAACAQAbmFtZR0AbWluZWNyYWZ0Om1hbmdyb3ZlX2ZlbmNlX2dhdGUECQBuYW1lX2hhc2i/kOhBKiI/dAMKAG5ldHdvcmtfaWSfweCSCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTrAgAACAQAbmFtZR0AbWluZWNyYWZ0Om1hbmdyb3ZlX2ZlbmNlX2dhdGUECQBuYW1lX2hhc2i/kOhBKiI/dAMKAG5ldHdvcmtfaWSfweCSCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAELAGluX3dhbGxfYml0AAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:cherry_fence_gate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQUAwAACAQAbmFtZRsAbWluZWNyYWZ0OmNoZXJyeV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoKWLgCk0z+PsDCgBuZXR3b3JrX2lk/9bTZQoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQUAwAACAQAbmFtZRsAbWluZWNyYWZ0OmNoZXJyeV9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoKWLgCk0z+PsDCgBuZXR3b3JrX2lk/9bTZQoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:bamboo_fence_gate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAwAACAQAbmFtZRsAbWluZWNyYWZ0OmJhbWJvb19mZW5jZV9nYXRlBAkAbmFtZV9oYXNopH1JrUgwdIADCgBuZXR3b3JrX2lkzIpPywoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAwAACAQAbmFtZRsAbWluZWNyYWZ0OmJhbWJvb19mZW5jZV9nYXRlBAkAbmFtZV9oYXNopH1JrUgwdIADCgBuZXR3b3JrX2lkzIpPywoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:crimson_fence_gate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQBAgAACAQAbmFtZRwAbWluZWNyYWZ0OmNyaW1zb25fZmVuY2VfZ2F0ZQQJAG5hbWVfaGFzaHE3Gfd0Z2d2AwoAbmV0d29ya19pZDQzVbEKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQsAaW5fd2FsbF9iaXQAAQgAb3Blbl9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQBAgAACAQAbmFtZRwAbWluZWNyYWZ0OmNyaW1zb25fZmVuY2VfZ2F0ZQQJAG5hbWVfaGFzaHE3Gfd0Z2d2AwoAbmV0d29ya19pZDQzVbEKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQsAaW5fd2FsbF9iaXQAAQgAb3Blbl9iaXQAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:warped_fence_gate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQCAgAACAQAbmFtZRsAbWluZWNyYWZ0OndhcnBlZF9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoy0oIBjDIG4kDCgBuZXR3b3JrX2lkkf+/3QoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQCAgAACAQAbmFtZRsAbWluZWNyYWZ0OndhcnBlZF9mZW5jZV9nYXRlBAkAbmFtZV9oYXNoy0oIBjDIG4kDCgBuZXR3b3JrX2lkkf+/3QoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCwBpbl93YWxsX2JpdAABCABvcGVuX2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:normal_stone_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAQAACAQAbmFtZR0AbWluZWNyYWZ0Om5vcm1hbF9zdG9uZV9zdGFpcnMECQBuYW1lX2hhc2hAEktZZOkGIwMKAG5ldHdvcmtfaWQeH1ALCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAQAACAQAbmFtZR0AbWluZWNyYWZ0Om5vcm1hbF9zdG9uZV9zdGFpcnMECQBuYW1lX2hhc2hAEktZZOkGIwMKAG5ldHdvcmtfaWQeH1ALCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:stone_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRDAAAACAQAbmFtZRYAbWluZWNyYWZ0OnN0b25lX3N0YWlycwQJAG5hbWVfaGFzaNRjqVC5GRVDAwoAbmV0d29ya19pZDcCv+MKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRDAAAACAQAbmFtZRYAbWluZWNyYWZ0OnN0b25lX3N0YWlycwQJAG5hbWVfaGFzaNRjqVC5GRVDAwoAbmV0d29ya19pZDcCv+MKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:mossy_cobblestone_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSyAQAACAQAbmFtZSIAbWluZWNyYWZ0Om1vc3N5X2NvYmJsZXN0b25lX3N0YWlycwQJAG5hbWVfaGFzaMVSTq5z9n1RAwoAbmV0d29ya19pZFIfrhkKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSyAQAACAQAbmFtZSIAbWluZWNyYWZ0Om1vc3N5X2NvYmJsZXN0b25lX3N0YWlycwQJAG5hbWVfaGFzaMVSTq5z9n1RAwoAbmV0d29ya19pZFIfrhkKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:oak_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ1AAAACAQAbmFtZRQAbWluZWNyYWZ0Om9ha19zdGFpcnMECQBuYW1lX2hhc2jk/HFzdXy0FQMKAG5ldHdvcmtfaWQJjyzBCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ1AAAACAQAbmFtZRQAbWluZWNyYWZ0Om9ha19zdGFpcnMECQBuYW1lX2hhc2jk/HFzdXy0FQMKAG5ldHdvcmtfaWQJjyzBCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:spruce_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSGAAAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9zdGFpcnMECQBuYW1lX2hhc2iznygw7uBPBQMKAG5ldHdvcmtfaWTv+is3CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSGAAAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9zdGFpcnMECQBuYW1lX2hhc2iznygw7uBPBQMKAG5ldHdvcmtfaWTv+is3CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:birch_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSHAAAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX3N0YWlycwQJAG5hbWVfaGFzaPfhbL619a3GAwoAbmV0d29ya19pZFyPlHAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSHAAAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX3N0YWlycwQJAG5hbWVfaGFzaPfhbL619a3GAwoAbmV0d29ya19pZFyPlHAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:jungle_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSIAAAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9zdGFpcnMECQBuYW1lX2hhc2jodJsHUbOVxQMKAG5ldHdvcmtfaWR0z5d4CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSIAAAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9zdGFpcnMECQBuYW1lX2hhc2jodJsHUbOVxQMKAG5ldHdvcmtfaWR0z5d4CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:acacia_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSjAAAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9zdGFpcnMECQBuYW1lX2hhc2h3x1NmD43IqQMKAG5ldHdvcmtfaWS7Jwz6CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSjAAAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9zdGFpcnMECQBuYW1lX2hhc2h3x1NmD43IqQMKAG5ldHdvcmtfaWS7Jwz6CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:dark_oak_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSkAAAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX3N0YWlycwQJAG5hbWVfaGFzaMfwkbYPbNmAAwoAbmV0d29ya19pZCmBYKAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSkAAAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX3N0YWlycwQJAG5hbWVfaGFzaMfwkbYPbNmAAwoAbmV0d29ya19pZCmBYKAKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:mangrove_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTnAgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX3N0YWlycwQJAG5hbWVfaGFzaNpUDY+uGMpyAwoAbmV0d29ya19pZChzUAsKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTnAgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX3N0YWlycwQJAG5hbWVfaGFzaNpUDY+uGMpyAwoAbmV0d29ya19pZChzUAsKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:cherry_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQcAwAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9zdGFpcnMECQBuYW1lX2hhc2jMtr0v9JY4zwMKAG5ldHdvcmtfaWRQwq31CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQcAwAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9zdGFpcnMECQBuYW1lX2hhc2jMtr0v9JY4zwMKAG5ldHdvcmtfaWRQwq31CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:bamboo_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWT/AgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19zdGFpcnMECQBuYW1lX2hhc2jFOzWL8PalKwMKAG5ldHdvcmtfaWTVPh42CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWT/AgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19zdGFpcnMECQBuYW1lX2hhc2jFOzWL8PalKwMKAG5ldHdvcmtfaWTVPh42CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:bamboo_mosaic_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQKAwAACAQAbmFtZR4AbWluZWNyYWZ0OmJhbWJvb19tb3NhaWNfc3RhaXJzBAkAbmFtZV9oYXNoNLPiveSHPaoDCgBuZXR3b3JrX2lk44PHjgoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQKAwAACAQAbmFtZR4AbWluZWNyYWZ0OmJhbWJvb19tb3NhaWNfc3RhaXJzBAkAbmFtZV9oYXNoNLPiveSHPaoDCgBuZXR3b3JrX2lk44PHjgoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:stone_brick_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRtAAAACAQAbmFtZRwAbWluZWNyYWZ0OnN0b25lX2JyaWNrX3N0YWlycwQJAG5hbWVfaGFzaN6tQViRo5cwAwoAbmV0d29ya19pZDMyMgIKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRtAAAACAQAbmFtZRwAbWluZWNyYWZ0OnN0b25lX2JyaWNrX3N0YWlycwQJAG5hbWVfaGFzaN6tQViRo5cwAwoAbmV0d29ya19pZDMyMgIKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:mossy_stone_brick_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSuAQAACAQAbmFtZSIAbWluZWNyYWZ0Om1vc3N5X3N0b25lX2JyaWNrX3N0YWlycwQJAG5hbWVfaGFzaIB/Zv5YBPuYAwoAbmV0d29ya19pZANTOsMKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSuAQAACAQAbmFtZSIAbWluZWNyYWZ0Om1vc3N5X3N0b25lX2JyaWNrX3N0YWlycwQJAG5hbWVfaGFzaIB/Zv5YBPuYAwoAbmV0d29ya19pZANTOsMKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:sandstone_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSAAAAACAQAbmFtZRoAbWluZWNyYWZ0OnNhbmRzdG9uZV9zdGFpcnMECQBuYW1lX2hhc2hOyA0BoYUOPQMKAG5ldHdvcmtfaWSV/834CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSAAAAACAQAbmFtZRoAbWluZWNyYWZ0OnNhbmRzdG9uZV9zdGFpcnMECQBuYW1lX2hhc2hOyA0BoYUOPQMKAG5ldHdvcmtfaWSV/834CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:smooth_sandstone_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSwAQAACAQAbmFtZSEAbWluZWNyYWZ0OnNtb290aF9zYW5kc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNoB+CuCd8Ruz8DCgBuZXR3b3JrX2lksR+m8QoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSwAQAACAQAbmFtZSEAbWluZWNyYWZ0OnNtb290aF9zYW5kc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNoB+CuCd8Ruz8DCgBuZXR3b3JrX2lksR+m8QoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:red_sandstone_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS0AAAACAQAbmFtZR4AbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNoPs0LpHPL24YDCgBuZXR3b3JrX2lkLYVt3woGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWS0AAAACAQAbmFtZR4AbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNoPs0LpHPL24YDCgBuZXR3b3JrX2lkLYVt3woGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:smooth_red_sandstone_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAQAACAQAbmFtZSUAbWluZWNyYWZ0OnNtb290aF9yZWRfc2FuZHN0b25lX3N0YWlycwQJAG5hbWVfaGFzaBvjtQv5pf+MAwoAbmV0d29ya19pZMHNND8KBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAQAACAQAbmFtZSUAbWluZWNyYWZ0OnNtb290aF9yZWRfc2FuZHN0b25lX3N0YWlycwQJAG5hbWVfaGFzaBvjtQv5pf+MAwoAbmV0d29ya19pZMHNND8KBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:granite_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAQAACAQAbmFtZRgAbWluZWNyYWZ0OmdyYW5pdGVfc3RhaXJzBAkAbmFtZV9oYXNoGzpvtoqKQjgDCgBuZXR3b3JrX2lkPkcB1goGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAQAACAQAbmFtZRgAbWluZWNyYWZ0OmdyYW5pdGVfc3RhaXJzBAkAbmFtZV9oYXNoGzpvtoqKQjgDCgBuZXR3b3JrX2lkPkcB1goGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:polished_granite_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSrAQAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2dyYW5pdGVfc3RhaXJzBAkAbmFtZV9oYXNo3PvbSfEQklIDCgBuZXR3b3JrX2lkMmEm3AoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSrAQAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2dyYW5pdGVfc3RhaXJzBAkAbmFtZV9oYXNo3PvbSfEQklIDCgBuZXR3b3JrX2lkMmEm3AoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:diorite_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSpAQAACAQAbmFtZRgAbWluZWNyYWZ0OmRpb3JpdGVfc3RhaXJzBAkAbmFtZV9oYXNoi73T8VQuZmcDCgBuZXR3b3JrX2lk6i6nBQoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSpAQAACAQAbmFtZRgAbWluZWNyYWZ0OmRpb3JpdGVfc3RhaXJzBAkAbmFtZV9oYXNoi73T8VQuZmcDCgBuZXR3b3JrX2lk6i6nBQoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:polished_diorite_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSsAQAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2Rpb3JpdGVfc3RhaXJzBAkAbmFtZV9oYXNoFKRJd5Wk5L0DCgBuZXR3b3JrX2lkbt2ioAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSsAQAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2Rpb3JpdGVfc3RhaXJzBAkAbmFtZV9oYXNoFKRJd5Wk5L0DCgBuZXR3b3JrX2lkbt2ioAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:andesite_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSqAQAACAQAbmFtZRkAbWluZWNyYWZ0OmFuZGVzaXRlX3N0YWlycwQJAG5hbWVfaGFzaO5w2FKBw76EAwoAbmV0d29ya19pZKhXEgUKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSqAQAACAQAbmFtZRkAbWluZWNyYWZ0OmFuZGVzaXRlX3N0YWlycwQJAG5hbWVfaGFzaO5w2FKBw76EAwoAbmV0d29ya19pZKhXEgUKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:polished_andesite_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWStAQAACAQAbmFtZSIAbWluZWNyYWZ0OnBvbGlzaGVkX2FuZGVzaXRlX3N0YWlycwQJAG5hbWVfaGFzaNcZZ/zmLInIAwoAbmV0d29ya19pZJTHrlEKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWStAQAACAQAbmFtZSIAbWluZWNyYWZ0OnBvbGlzaGVkX2FuZGVzaXRlX3N0YWlycwQJAG5hbWVfaGFzaNcZZ/zmLInIAwoAbmV0d29ya19pZJTHrlEKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:brick_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRsAAAACAQAbmFtZRYAbWluZWNyYWZ0OmJyaWNrX3N0YWlycwQJAG5hbWVfaGFzaMyt+cRDk5O2AwoAbmV0d29ya19pZNeMh58KBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRsAAAACAQAbmFtZRYAbWluZWNyYWZ0OmJyaWNrX3N0YWlycwQJAG5hbWVfaGFzaMyt+cRDk5O2AwoAbmV0d29ya19pZNeMh58KBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:nether_brick_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRyAAAACAQAbmFtZR0AbWluZWNyYWZ0Om5ldGhlcl9icmlja19zdGFpcnMECQBuYW1lX2hhc2jRqIoOXgifBAMKAG5ldHdvcmtfaWQDiw5yCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRyAAAACAQAbmFtZR0AbWluZWNyYWZ0Om5ldGhlcl9icmlja19zdGFpcnMECQBuYW1lX2hhc2jRqIoOXgifBAMKAG5ldHdvcmtfaWQDiw5yCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:red_nether_brick_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS3AQAACAQAbmFtZSEAbWluZWNyYWZ0OnJlZF9uZXRoZXJfYnJpY2tfc3RhaXJzBAkAbmFtZV9oYXNogQvosSbcj7kDCgBuZXR3b3JrX2lkx2IMtAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWS3AQAACAQAbmFtZSEAbWluZWNyYWZ0OnJlZF9uZXRoZXJfYnJpY2tfc3RhaXJzBAkAbmFtZV9oYXNogQvosSbcj7kDCgBuZXR3b3JrX2lkx2IMtAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:end_brick_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSxAQAACAQAbmFtZRoAbWluZWNyYWZ0OmVuZF9icmlja19zdGFpcnMECQBuYW1lX2hhc2hmlAk+QhsUsQMKAG5ldHdvcmtfaWTN7KFaCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSxAQAACAQAbmFtZRoAbWluZWNyYWZ0OmVuZF9icmlja19zdGFpcnMECQBuYW1lX2hhc2hmlAk+QhsUsQMKAG5ldHdvcmtfaWTN7KFaCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:quartz_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWScAAAACAQAbmFtZRcAbWluZWNyYWZ0OnF1YXJ0el9zdGFpcnMECQBuYW1lX2hhc2hmvpvOqGi6egMKAG5ldHdvcmtfaWRmUTh7CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWScAAAACAQAbmFtZRcAbWluZWNyYWZ0OnF1YXJ0el9zdGFpcnMECQBuYW1lX2hhc2hmvpvOqGi6egMKAG5ldHdvcmtfaWRmUTh7CgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:smooth_quartz_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS4AQAACAQAbmFtZR4AbWluZWNyYWZ0OnNtb290aF9xdWFydHpfc3RhaXJzBAkAbmFtZV9oYXNoNZZ9rX0qZOsDCgBuZXR3b3JrX2lkzsgQyQoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWS4AQAACAQAbmFtZR4AbWluZWNyYWZ0OnNtb290aF9xdWFydHpfc3RhaXJzBAkAbmFtZV9oYXNoNZZ9rX0qZOsDCgBuZXR3b3JrX2lkzsgQyQoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:purpur_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTLAAAACAQAbmFtZRcAbWluZWNyYWZ0OnB1cnB1cl9zdGFpcnMECQBuYW1lX2hhc2ifwDxeezXD7gMKAG5ldHdvcmtfaWTT+rxiCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTLAAAACAQAbmFtZRcAbWluZWNyYWZ0OnB1cnB1cl9zdGFpcnMECQBuYW1lX2hhc2ifwDxeezXD7gMKAG5ldHdvcmtfaWTT+rxiCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:prismarine_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQBAQAACAQAbmFtZRsAbWluZWNyYWZ0OnByaXNtYXJpbmVfc3RhaXJzBAkAbmFtZV9oYXNooTHSZ+IrYtcDCgBuZXR3b3JrX2lkxTJfeAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQBAQAACAQAbmFtZRsAbWluZWNyYWZ0OnByaXNtYXJpbmVfc3RhaXJzBAkAbmFtZV9oYXNooTHSZ+IrYtcDCgBuZXR3b3JrX2lkxTJfeAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:dark_prismarine_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQCAQAACAQAbmFtZSAAbWluZWNyYWZ0OmRhcmtfcHJpc21hcmluZV9zdGFpcnMECQBuYW1lX2hhc2hIciLmam4o4AMKAG5ldHdvcmtfaWTVu7TCCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQCAQAACAQAbmFtZSAAbWluZWNyYWZ0OmRhcmtfcHJpc21hcmluZV9zdGFpcnMECQBuYW1lX2hhc2hIciLmam4o4AMKAG5ldHdvcmtfaWTVu7TCCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:prismarine_bricks_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAQAACAQAbmFtZSIAbWluZWNyYWZ0OnByaXNtYXJpbmVfYnJpY2tzX3N0YWlycwQJAG5hbWVfaGFzaNIjq1oBlZMMAwoAbmV0d29ya19pZGEFwLYKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAQAACAQAbmFtZSIAbWluZWNyYWZ0OnByaXNtYXJpbmVfYnJpY2tzX3N0YWlycwQJAG5hbWVfaGFzaNIjq1oBlZMMAwoAbmV0d29ya19pZGEFwLYKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:crimson_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWT9AQAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fc3RhaXJzBAkAbmFtZV9oYXNoZJqIzCBpCq4DCgBuZXR3b3JrX2lktXE00AoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWT9AQAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fc3RhaXJzBAkAbmFtZV9oYXNoZJqIzCBpCq4DCgBuZXR3b3JrX2lktXE00AoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:warped_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWT+AQAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9zdGFpcnMECQBuYW1lX2hhc2hOkY27jLD4RQMKAG5ldHdvcmtfaWQ+E5VrCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWT+AQAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9zdGFpcnMECQBuYW1lX2hhc2hOkY27jLD4RQMKAG5ldHdvcmtfaWQ+E5VrCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:blackstone_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQTAgAACAQAbmFtZRsAbWluZWNyYWZ0OmJsYWNrc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNokdoUb76p9McDCgBuZXR3b3JrX2lk5fWI5goGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQTAgAACAQAbmFtZRsAbWluZWNyYWZ0OmJsYWNrc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNokdoUb76p9McDCgBuZXR3b3JrX2lk5fWI5goGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:polished_blackstone_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQjAgAACAQAbmFtZSQAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNolCFtFIE8MmADCgBuZXR3b3JrX2lkGTf7sgoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQjAgAACAQAbmFtZSQAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfc3RhaXJzBAkAbmFtZV9oYXNolCFtFIE8MmADCgBuZXR3b3JrX2lkGTf7sgoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:polished_blackstone_brick_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQSAgAACAQAbmFtZSoAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tfc3RhaXJzBAkAbmFtZV9oYXNonks6UlfpOmkDCgBuZXR3b3JrX2lkgYeOdAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQSAgAACAQAbmFtZSoAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tfc3RhaXJzBAkAbmFtZV9oYXNonks6UlfpOmkDCgBuZXR3b3JrX2lkgYeOdAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:cut_copper_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAgAACAQAbmFtZRsAbWluZWNyYWZ0OmN1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNoHfoAXYq5G3MDCgBuZXR3b3JrX2lkeetf7woGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAgAACAQAbmFtZRsAbWluZWNyYWZ0OmN1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNoHfoAXYq5G3MDCgBuZXR3b3JrX2lkeetf7woGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:exposed_cut_copper_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAgAACAQAbmFtZSMAbWluZWNyYWZ0OmV4cG9zZWRfY3V0X2NvcHBlcl9zdGFpcnMECQBuYW1lX2hhc2howneQGtZ9cgMKAG5ldHdvcmtfaWSg73zdCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAgAACAQAbmFtZSMAbWluZWNyYWZ0OmV4cG9zZWRfY3V0X2NvcHBlcl9zdGFpcnMECQBuYW1lX2hhc2howneQGtZ9cgMKAG5ldHdvcmtfaWSg73zdCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:weathered_cut_copper_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAgAACAQAbmFtZSUAbWluZWNyYWZ0OndlYXRoZXJlZF9jdXRfY29wcGVyX3N0YWlycwQJAG5hbWVfaGFzaP+R5loXxrVgAwoAbmV0d29ya19pZOnbRf4KBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAgAACAQAbmFtZSUAbWluZWNyYWZ0OndlYXRoZXJlZF9jdXRfY29wcGVyX3N0YWlycwQJAG5hbWVfaGFzaP+R5loXxrVgAwoAbmV0d29ya19pZOnbRf4KBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:oxidized_cut_copper_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRkAgAACAQAbmFtZSQAbWluZWNyYWZ0Om94aWRpemVkX2N1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNo6Jeoq5rsPxsDCgBuZXR3b3JrX2lkmRjDnQoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRkAgAACAQAbmFtZSQAbWluZWNyYWZ0Om94aWRpemVkX2N1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNo6Jeoq5rsPxsDCgBuZXR3b3JrX2lkmRjDnQoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:waxed_cut_copper_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRlAgAACAQAbmFtZSEAbWluZWNyYWZ0OndheGVkX2N1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNoh07CQj0/SR8DCgBuZXR3b3JrX2lkmYqoqAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRlAgAACAQAbmFtZSEAbWluZWNyYWZ0OndheGVkX2N1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNoh07CQj0/SR8DCgBuZXR3b3JrX2lkmYqoqAoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:waxed_exposed_cut_copper_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRmAgAACAQAbmFtZSkAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY3V0X2NvcHBlcl9zdGFpcnMECQBuYW1lX2hhc2guVct1ilmxTwMKAG5ldHdvcmtfaWQgCPROCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRmAgAACAQAbmFtZSkAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY3V0X2NvcHBlcl9zdGFpcnMECQBuYW1lX2hhc2guVct1ilmxTwMKAG5ldHdvcmtfaWQgCPROCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:waxed_weathered_cut_copper_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRnAgAACAQAbmFtZSsAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jdXRfY29wcGVyX3N0YWlycwQJAG5hbWVfaGFzaPXC8Sz/phCpAwoAbmV0d29ya19pZHlwHVsKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRnAgAACAQAbmFtZSsAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jdXRfY29wcGVyX3N0YWlycwQJAG5hbWVfaGFzaPXC8Sz/phCpAwoAbmV0d29ya19pZHlwHVsKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:waxed_oxidized_cut_copper_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS/AgAACAQAbmFtZSoAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2N1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNoaqGdkuhxVZUDCgBuZXR3b3JrX2lkYQXzzgoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWS/AgAACAQAbmFtZSoAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2N1dF9jb3BwZXJfc3RhaXJzBAkAbmFtZV9oYXNoaqGdkuhxVZUDCgBuZXR3b3JrX2lkYQXzzgoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:cobbled_deepslate_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR8AgAACAQAbmFtZSIAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlX3N0YWlycwQJAG5hbWVfaGFzaPIfa+TpyJcIAwoAbmV0d29ya19pZJUvOYIKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWR8AgAACAQAbmFtZSIAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlX3N0YWlycwQJAG5hbWVfaGFzaPIfa+TpyJcIAwoAbmV0d29ya19pZJUvOYIKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:deepslate_tile_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAgAACAQAbmFtZR8AbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlX3N0YWlycwQJAG5hbWVfaGFzaGFRFzB72mN2AwoAbmV0d29ya19pZJEOgIsKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAgAACAQAbmFtZR8AbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlX3N0YWlycwQJAG5hbWVfaGFzaGFRFzB72mN2AwoAbmV0d29ya19pZJEOgIsKBgBzdGF0ZXMBDwB1cHNpZGVfZG93bl9iaXQAAxAAd2VpcmRvX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:polished_deepslate_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSAAgAACAQAbmFtZSMAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZV9zdGFpcnMECQBuYW1lX2hhc2iNCYxVik9sGAMKAG5ldHdvcmtfaWSRVPnYCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSAAgAACAQAbmFtZSMAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZV9zdGFpcnMECQBuYW1lX2hhc2iNCYxVik9sGAMKAG5ldHdvcmtfaWSRVPnYCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:deepslate_brick_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSIAgAACAQAbmFtZSAAbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja19zdGFpcnMECQBuYW1lX2hhc2hIasOahEf83wMKAG5ldHdvcmtfaWQ1qEDCCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSIAgAACAQAbmFtZSAAbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja19zdGFpcnMECQBuYW1lX2hhc2hIasOahEf83wMKAG5ldHdvcmtfaWQ1qEDCCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:mud_brick_stairs", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTfAgAACAQAbmFtZRoAbWluZWNyYWZ0Om11ZF9icmlja19zdGFpcnMECQBuYW1lX2hhc2gt3qxK1NWajAMKAG5ldHdvcmtfaWSm9N3MCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTfAgAACAQAbmFtZRoAbWluZWNyYWZ0Om11ZF9icmlja19zdGFpcnMECQBuYW1lX2hhc2gt3qxK1NWajAMKAG5ldHdvcmtfaWSm9N3MCgYAc3RhdGVzAQ8AdXBzaWRlX2Rvd25fYml0AAMQAHdlaXJkb19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:wooden_door" @@ -478,1575 +478,1727 @@ }, { "id": "minecraft:trapdoor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRgAAAACAQAbmFtZRIAbWluZWNyYWZ0OnRyYXBkb29yBAkAbmFtZV9oYXNotYiAJGtN0xADCgBuZXR3b3JrX2lkyTAWkAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRgAAAACAQAbmFtZRIAbWluZWNyYWZ0OnRyYXBkb29yBAkAbmFtZV9oYXNotYiAJGtN0xADCgBuZXR3b3JrX2lkyTAWkAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:spruce_trapdoor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSUAQAACAQAbmFtZRkAbWluZWNyYWZ0OnNwcnVjZV90cmFwZG9vcgQJAG5hbWVfaGFzaOwlfbgBkUW4AwoAbmV0d29ya19pZPHy1K0KBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSUAQAACAQAbmFtZRkAbWluZWNyYWZ0OnNwcnVjZV90cmFwZG9vcgQJAG5hbWVfaGFzaOwlfbgBkUW4AwoAbmV0d29ya19pZPHy1K0KBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:birch_trapdoor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAQAACAQAbmFtZRgAbWluZWNyYWZ0OmJpcmNoX3RyYXBkb29yBAkAbmFtZV9oYXNoSLtLweOLJ7wDCgBuZXR3b3JrX2lkeJWDfgoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAQAACAQAbmFtZRgAbWluZWNyYWZ0OmJpcmNoX3RyYXBkb29yBAkAbmFtZV9oYXNoSLtLweOLJ7wDCgBuZXR3b3JrX2lkeJWDfgoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:jungle_trapdoor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSTAQAACAQAbmFtZRkAbWluZWNyYWZ0Omp1bmdsZV90cmFwZG9vcgQJAG5hbWVfaGFzaDP/TnM9wyCIAwoAbmV0d29ya19pZEy2fJoKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSTAQAACAQAbmFtZRkAbWluZWNyYWZ0Omp1bmdsZV90cmFwZG9vcgQJAG5hbWVfaGFzaDP/TnM9wyCIAwoAbmV0d29ya19pZEy2fJoKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:acacia_trapdoor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSQAQAACAQAbmFtZRkAbWluZWNyYWZ0OmFjYWNpYV90cmFwZG9vcgQJAG5hbWVfaGFzaMj8xi3vmEKOAwoAbmV0d29ya19pZOHj8E8KBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSQAQAACAQAbmFtZRkAbWluZWNyYWZ0OmFjYWNpYV90cmFwZG9vcgQJAG5hbWVfaGFzaMj8xi3vmEKOAwoAbmV0d29ya19pZOHj8E8KBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:dark_oak_trapdoor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSSAQAACAQAbmFtZRsAbWluZWNyYWZ0OmRhcmtfb2FrX3RyYXBkb29yBAkAbmFtZV9oYXNomB2GGJQ2aOMDCgBuZXR3b3JrX2lko5ZHTwoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSSAQAACAQAbmFtZRsAbWluZWNyYWZ0OmRhcmtfb2FrX3RyYXBkb29yBAkAbmFtZV9oYXNomB2GGJQ2aOMDCgBuZXR3b3JrX2lko5ZHTwoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:mangrove_trapdoor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTvAgAACAQAbmFtZRsAbWluZWNyYWZ0Om1hbmdyb3ZlX3RyYXBkb29yBAkAbmFtZV9oYXNooV3kQsQUUmkDCgBuZXR3b3JrX2lkkF/mxAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTvAgAACAQAbmFtZRsAbWluZWNyYWZ0Om1hbmdyb3ZlX3RyYXBkb29yBAkAbmFtZV9oYXNooV3kQsQUUmkDCgBuZXR3b3JrX2lkkF/mxAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:cherry_trapdoor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQeAwAACAQAbmFtZRkAbWluZWNyYWZ0OmNoZXJyeV90cmFwZG9vcgQJAG5hbWVfaGFzaH/PefpfdHgtAwoAbmV0d29ya19pZOA7eNgKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQeAwAACAQAbmFtZRkAbWluZWNyYWZ0OmNoZXJyeV90cmFwZG9vcgQJAG5hbWVfaGFzaH/PefpfdHgtAwoAbmV0d29ya19pZOA7eNgKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:bamboo_trapdoor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQHAwAACAQAbmFtZRkAbWluZWNyYWZ0OmJhbWJvb190cmFwZG9vcgQJAG5hbWVfaGFzaJrEOpsTwtKCAwoAbmV0d29ya19pZLvbPz8KBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQHAwAACAQAbmFtZRkAbWluZWNyYWZ0OmJhbWJvb190cmFwZG9vcgQJAG5hbWVfaGFzaJrEOpsTwtKCAwoAbmV0d29ya19pZLvbPz8KBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:iron_trapdoor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSnAAAACAQAbmFtZRcAbWluZWNyYWZ0Omlyb25fdHJhcGRvb3IECQBuYW1lX2hhc2gwA+IumsEiGQMKAG5ldHdvcmtfaWTvSVl/CgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAEPAHVwc2lkZV9kb3duX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSnAAAACAQAbmFtZRcAbWluZWNyYWZ0Omlyb25fdHJhcGRvb3IECQBuYW1lX2hhc2gwA+IumsEiGQMKAG5ldHdvcmtfaWTvSVl/CgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAEPAHVwc2lkZV9kb3duX2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:crimson_trapdoor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWT1AQAACAQAbmFtZRoAbWluZWNyYWZ0OmNyaW1zb25fdHJhcGRvb3IECQBuYW1lX2hhc2jHXufTnwUkYgMKAG5ldHdvcmtfaWQLjMYVCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAEPAHVwc2lkZV9kb3duX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWT1AQAACAQAbmFtZRoAbWluZWNyYWZ0OmNyaW1zb25fdHJhcGRvb3IECQBuYW1lX2hhc2jHXufTnwUkYgMKAG5ldHdvcmtfaWQLjMYVCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAEPAHVwc2lkZV9kb3duX2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:warped_trapdoor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWT2AQAACAQAbmFtZRkAbWluZWNyYWZ0OndhcnBlZF90cmFwZG9vcgQJAG5hbWVfaGFzaA20wG/+vkd6AwoAbmV0d29ya19pZHKR/hYKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWT2AQAACAQAbmFtZRkAbWluZWNyYWZ0OndhcnBlZF90cmFwZG9vcgQJAG5hbWVfaGFzaA20wG/+vkd6AwoAbmV0d29ya19pZHKR/hYKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:iron_bars", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRlAAAACAQAbmFtZRMAbWluZWNyYWZ0Omlyb25fYmFycwQJAG5hbWVfaGFzaPuefWSNAe56AwoAbmV0d29ya19pZN2LB5IKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRlAAAACAQAbmFtZRMAbWluZWNyYWZ0Omlyb25fYmFycwQJAG5hbWVfaGFzaPuefWSNAe56AwoAbmV0d29ya19pZN2LB5IKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQUAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmdsYXNzBAkAbmFtZV9oYXNowGJByfWff6gDCgBuZXR3b3JrX2lk0hdLNwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQUAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmdsYXNzBAkAbmFtZV9oYXNowGJByfWff6gDCgBuZXR3b3JrX2lk0hdLNwoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:white_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTxAAAACAQAbmFtZR0AbWluZWNyYWZ0OndoaXRlX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2iHubqoMbu9fAMKAG5ldHdvcmtfaWRndBrUCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTxAAAACAQAbmFtZR0AbWluZWNyYWZ0OndoaXRlX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2iHubqoMbu9fAMKAG5ldHdvcmtfaWRndBrUCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:light_gray_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSnAwAACAQAbmFtZSIAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaKKa+LrRsHQhAwoAbmV0d29ya19pZEv2giYKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSnAwAACAQAbmFtZSIAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaKKa+LrRsHQhAwoAbmV0d29ya19pZEv2giYKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:gray_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSmAwAACAQAbmFtZRwAbWluZWNyYWZ0OmdyYXlfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaIETy7Y/HZREAwoAbmV0d29ya19pZDomVrUKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSmAwAACAQAbmFtZRwAbWluZWNyYWZ0OmdyYXlfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaIETy7Y/HZREAwoAbmV0d29ya19pZDomVrUKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:black_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSuAwAACAQAbmFtZR0AbWluZWNyYWZ0OmJsYWNrX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2iV6BCwpfDMmwMKAG5ldHdvcmtfaWSV7doJCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSuAwAACAQAbmFtZR0AbWluZWNyYWZ0OmJsYWNrX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2iV6BCwpfDMmwMKAG5ldHdvcmtfaWSV7doJCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:brown_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSrAwAACAQAbmFtZR0AbWluZWNyYWZ0OmJyb3duX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2igsEiq5np8JgMKAG5ldHdvcmtfaWRMzE/lCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSrAwAACAQAbmFtZR0AbWluZWNyYWZ0OmJyb3duX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2igsEiq5np8JgMKAG5ldHdvcmtfaWRMzE/lCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:red_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWStAwAACAQAbmFtZRsAbWluZWNyYWZ0OnJlZF9zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNoCa2J12/lQoIDCgBuZXR3b3JrX2lk283lWAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWStAwAACAQAbmFtZRsAbWluZWNyYWZ0OnJlZF9zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNoCa2J12/lQoIDCgBuZXR3b3JrX2lk283lWAoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:orange_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSgAwAACAQAbmFtZR4AbWluZWNyYWZ0Om9yYW5nZV9zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNozgjAuvzhxGsDCgBuZXR3b3JrX2lkW5CkhQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSgAwAACAQAbmFtZR4AbWluZWNyYWZ0Om9yYW5nZV9zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNozgjAuvzhxGsDCgBuZXR3b3JrX2lkW5CkhQoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:yellow_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSjAwAACAQAbmFtZR4AbWluZWNyYWZ0OnllbGxvd19zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNo7EbHMd5WVugDCgBuZXR3b3JrX2lkkdDyXQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSjAwAACAQAbmFtZR4AbWluZWNyYWZ0OnllbGxvd19zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNo7EbHMd5WVugDCgBuZXR3b3JrX2lkkdDyXQoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:lime_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSkAwAACAQAbmFtZRwAbWluZWNyYWZ0OmxpbWVfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaBtZA1nZtwcFAwoAbmV0d29ya19pZDxX85UKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSkAwAACAQAbmFtZRwAbWluZWNyYWZ0OmxpbWVfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaBtZA1nZtwcFAwoAbmV0d29ya19pZDxX85UKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:green_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSsAwAACAQAbmFtZR0AbWluZWNyYWZ0OmdyZWVuX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2h91ptDgbehWwMKAG5ldHdvcmtfaWTlDhnECgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSsAwAACAQAbmFtZR0AbWluZWNyYWZ0OmdyZWVuX3N0YWluZWRfZ2xhc3MECQBuYW1lX2hhc2h91ptDgbehWwMKAG5ldHdvcmtfaWTlDhnECgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:cyan_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAwAACAQAbmFtZRwAbWluZWNyYWZ0OmN5YW5fc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaBkIYQ8nQLqbAwoAbmV0d29ya19pZOL1lHsKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAwAACAQAbmFtZRwAbWluZWNyYWZ0OmN5YW5fc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaBkIYQ8nQLqbAwoAbmV0d29ya19pZOL1lHsKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:light_blue_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSiAwAACAQAbmFtZSIAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaLt05n1G0fiSAwoAbmV0d29ya19pZNbwulIKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSiAwAACAQAbmFtZSIAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaLt05n1G0fiSAwoAbmV0d29ya19pZNbwulIKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:blue_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSqAwAACAQAbmFtZRwAbWluZWNyYWZ0OmJsdWVfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaPhLocSfzduRAwoAbmV0d29ya19pZENsjFwKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSqAwAACAQAbmFtZRwAbWluZWNyYWZ0OmJsdWVfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaPhLocSfzduRAwoAbmV0d29ya19pZENsjFwKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:purple_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSpAwAACAQAbmFtZR4AbWluZWNyYWZ0OnB1cnBsZV9zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNoJk0DhRO0szUDCgBuZXR3b3JrX2lkD98ZxgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSpAwAACAQAbmFtZR4AbWluZWNyYWZ0OnB1cnBsZV9zdGFpbmVkX2dsYXNzBAkAbmFtZV9oYXNoJk0DhRO0szUDCgBuZXR3b3JrX2lkD98ZxgoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:magenta_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWShAwAACAQAbmFtZR8AbWluZWNyYWZ0Om1hZ2VudGFfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaFEDeFiJj3zSAwoAbmV0d29ya19pZG+iFRoKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAwAACAQAbmFtZR8AbWluZWNyYWZ0Om1hZ2VudGFfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaFEDeFiJj3zSAwoAbmV0d29ya19pZG+iFRoKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:pink_stained_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAwAACAQAbmFtZRwAbWluZWNyYWZ0OnBpbmtfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaDijTX87ywxhAwoAbmV0d29ya19pZKdEricKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAwAACAQAbmFtZRwAbWluZWNyYWZ0OnBpbmtfc3RhaW5lZF9nbGFzcwQJAG5hbWVfaGFzaDijTX87ywxhAwoAbmV0d29ya19pZKdEricKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:tinted_glass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRNAgAACAQAbmFtZRYAbWluZWNyYWZ0OnRpbnRlZF9nbGFzcwQJAG5hbWVfaGFzaAFZWSamk6KdAwoAbmV0d29ya19pZGSvWX8KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRNAgAACAQAbmFtZRYAbWluZWNyYWZ0OnRpbnRlZF9nbGFzcwQJAG5hbWVfaGFzaAFZWSamk6KdAwoAbmV0d29ya19pZGSvWX8KBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRmAAAACAQAbmFtZRQAbWluZWNyYWZ0OmdsYXNzX3BhbmUECQBuYW1lX2hhc2gRSBHwNMQ4gQMKAG5ldHdvcmtfaWRGwixuCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRmAAAACAQAbmFtZRQAbWluZWNyYWZ0OmdsYXNzX3BhbmUECQBuYW1lX2hhc2gRSBHwNMQ4gQMKAG5ldHdvcmtfaWRGwixuCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:white_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSgAAAACAQAbmFtZSIAbWluZWNyYWZ0OndoaXRlX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaHgxQmgJVtRrAwoAbmV0d29ya19pZBEr/DYKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSgAAAACAQAbmFtZSIAbWluZWNyYWZ0OndoaXRlX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaHgxQmgJVtRrAwoAbmV0d29ya19pZBEr/DYKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:light_gray_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSJAwAACAQAbmFtZScAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNon0aQw9lNkSEDCgBuZXR3b3JrX2lk9dp5VgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSJAwAACAQAbmFtZScAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNon0aQw9lNkSEDCgBuZXR3b3JrX2lk9dp5VgoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:gray_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSIAwAACAQAbmFtZSEAbWluZWNyYWZ0OmdyYXlfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNors74IIw+2MMDCgBuZXR3b3JrX2lkmrGO5woGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSIAwAACAQAbmFtZSEAbWluZWNyYWZ0OmdyYXlfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNors74IIw+2MMDCgBuZXR3b3JrX2lkmrGO5woGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:black_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSQAwAACAQAbmFtZSIAbWluZWNyYWZ0OmJsYWNrX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaOK/5ZRRd+M1AwoAbmV0d29ya19pZDv++oQKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSQAwAACAQAbmFtZSIAbWluZWNyYWZ0OmJsYWNrX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaOK/5ZRRd+M1AwoAbmV0d29ya19pZDv++oQKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:brown_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSNAwAACAQAbmFtZSIAbWluZWNyYWZ0OmJyb3duX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaLHeGJyRFTIWAwoAbmV0d29ya19pZMz9L0wKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSNAwAACAQAbmFtZSIAbWluZWNyYWZ0OmJyb3duX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaLHeGJyRFTIWAwoAbmV0d29ya19pZMz9L0wKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:red_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSPAwAACAQAbmFtZSAAbWluZWNyYWZ0OnJlZF9zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2gGr4x6JheAywMKAG5ldHdvcmtfaWQBjCTmCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSPAwAACAQAbmFtZSAAbWluZWNyYWZ0OnJlZF9zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2gGr4x6JheAywMKAG5ldHdvcmtfaWQBjCTmCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:orange_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSCAwAACAQAbmFtZSMAbWluZWNyYWZ0Om9yYW5nZV9zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2hbHxPD2gEbEAMKAG5ldHdvcmtfaWSt/7a5CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSCAwAACAQAbmFtZSMAbWluZWNyYWZ0Om9yYW5nZV9zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2hbHxPD2gEbEAMKAG5ldHdvcmtfaWSt/7a5CgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:yellow_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAwAACAQAbmFtZSMAbWluZWNyYWZ0OnllbGxvd19zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2g9tl4aOCyZBwMKAG5ldHdvcmtfaWTXRAS7CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAwAACAQAbmFtZSMAbWluZWNyYWZ0OnllbGxvd19zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2g9tl4aOCyZBwMKAG5ldHdvcmtfaWTXRAS7CgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:lime_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSGAwAACAQAbmFtZSEAbWluZWNyYWZ0OmxpbWVfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNo3CtUyLwoGegDCgBuZXR3b3JrX2lkYJDnggoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSGAwAACAQAbmFtZSEAbWluZWNyYWZ0OmxpbWVfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNo3CtUyLwoGegDCgBuZXR3b3JrX2lkYJDnggoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:green_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSOAwAACAQAbmFtZSIAbWluZWNyYWZ0OmdyZWVuX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaJo6YP7IMy9SAwoAbmV0d29ya19pZHOnixoKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSOAwAACAQAbmFtZSIAbWluZWNyYWZ0OmdyZWVuX3N0YWluZWRfZ2xhc3NfcGFuZQQJAG5hbWVfaGFzaJo6YP7IMy9SAwoAbmV0d29ya19pZHOnixoKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:cyan_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSKAwAACAQAbmFtZSEAbWluZWNyYWZ0OmN5YW5fc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNoti97c6QrbLQDCgBuZXR3b3JrX2lkUqFUeQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSKAwAACAQAbmFtZSEAbWluZWNyYWZ0OmN5YW5fc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNoti97c6QrbLQDCgBuZXR3b3JrX2lkUqFUeQoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:light_blue_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAwAACAQAbmFtZScAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNovDg/gQle104DCgBuZXR3b3JrX2lkFuy4MQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAwAACAQAbmFtZScAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNovDg/gQle104DCgBuZXR3b3JrX2lkFuy4MQoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:blue_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSMAwAACAQAbmFtZSEAbWluZWNyYWZ0OmJsdWVfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNoGc57tiexbQMDCgBuZXR3b3JrX2lk1eBLUAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSMAwAACAQAbmFtZSEAbWluZWNyYWZ0OmJsdWVfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNoGc57tiexbQMDCgBuZXR3b3JrX2lk1eBLUAoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:purple_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAwAACAQAbmFtZSMAbWluZWNyYWZ0OnB1cnBsZV9zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2hDJHYdd0FdfQMKAG5ldHdvcmtfaWSNsdK5CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAwAACAQAbmFtZSMAbWluZWNyYWZ0OnB1cnBsZV9zdGFpbmVkX2dsYXNzX3BhbmUECQBuYW1lX2hhc2hDJHYdd0FdfQMKAG5ldHdvcmtfaWSNsdK5CgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:magenta_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAwAACAQAbmFtZSQAbWluZWNyYWZ0Om1hZ2VudGFfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNo3pcOw5bs5XoDCgBuZXR3b3JrX2lkVbOR7AoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAwAACAQAbmFtZSQAbWluZWNyYWZ0Om1hZ2VudGFfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNo3pcOw5bs5XoDCgBuZXR3b3JrX2lkVbOR7AoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:pink_stained_glass_pane", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSHAwAACAQAbmFtZSEAbWluZWNyYWZ0OnBpbmtfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNoWRhSACMWgswDCgBuZXR3b3JrX2lkIR92xwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSHAwAACAQAbmFtZSEAbWluZWNyYWZ0OnBpbmtfc3RhaW5lZF9nbGFzc19wYW5lBAkAbmFtZV9oYXNoWRhSACMWgswDCgBuZXR3b3JrX2lkIR92xwoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:ladder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRBAAAACAQAbmFtZRAAbWluZWNyYWZ0OmxhZGRlcgQJAG5hbWVfaGFzaKBhqheJVOz+AwoAbmV0d29ya19pZCgvzlsKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRBAAAACAQAbmFtZRAAbWluZWNyYWZ0OmxhZGRlcgQJAG5hbWVfaGFzaKBhqheJVOz+AwoAbmV0d29ya19pZCgvzlsKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:scaffolding", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSkAQAACAQAbmFtZRUAbWluZWNyYWZ0OnNjYWZmb2xkaW5nBAkAbmFtZV9oYXNoYrkevrqcljwDCgBuZXR3b3JrX2lkD13mlAoGAHN0YXRlcwMJAHN0YWJpbGl0eQAAAAABDwBzdGFiaWxpdHlfY2hlY2sAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSkAQAACAQAbmFtZRUAbWluZWNyYWZ0OnNjYWZmb2xkaW5nBAkAbmFtZV9oYXNoYrkevrqcljwDCgBuZXR3b3JrX2lkD13mlAoGAHN0YXRlcwMJAHN0YWJpbGl0eQAAAAABDwBzdGFiaWxpdHlfY2hlY2sAAAMHAHZlcnNpb24DABUBAA==" }, { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWTkNl0JCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQwAc21vb3RoX3N0b25lAAMHAHZlcnNpb24ERhQBAA==" + "id": "minecraft:smooth_stone_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRsAbWluZWNyYWZ0OnNtb290aF9zdG9uZV9zbGFiBAkAbmFtZV9oYXNon5I1yVw74uMDCgBuZXR3b3JrX2lkqvjcBQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:stone_block_slab4", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkQJoxlgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNAUAc3RvbmUAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkQJoxlgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNAUAc3RvbmUAAwcAdmVyc2lvbgMAFQEA" }, { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWRHh04KCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQsAY29iYmxlc3RvbmUAAwcAdmVyc2lvbgRGFAEA" + "id": "minecraft:cobblestone_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRoBAAACAQAbmFtZRoAbWluZWNyYWZ0OmNvYmJsZXN0b25lX3NsYWIECQBuYW1lX2hhc2h5CXtW7vlQVgMKAG5ldHdvcmtfaWRDGyj2CgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkVRZB+woGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhEAbW9zc3lfY29iYmxlc3RvbmUAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkVRZB+woGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhEAbW9zc3lfY29iYmxlc3RvbmUAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:oak_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSeAAAACAQAbmFtZRIAbWluZWNyYWZ0Om9ha19zbGFiBAkAbmFtZV9oYXNoJp1Cp1M4jlwDCgBuZXR3b3JrX2lkZH6+owoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSeAAAACAQAbmFtZRIAbWluZWNyYWZ0Om9ha19zbGFiBAkAbmFtZV9oYXNoJp1Cp1M4jlwDCgBuZXR3b3JrX2lkZH6+owoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:spruce_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQjBAAACAQAbmFtZRUAbWluZWNyYWZ0OnNwcnVjZV9zbGFiBAkAbmFtZV9oYXNodQi70jB238cDCgBuZXR3b3JrX2lkrriOYQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQjBAAACAQAbmFtZRUAbWluZWNyYWZ0OnNwcnVjZV9zbGFiBAkAbmFtZV9oYXNodQi70jB238cDCgBuZXR3b3JrX2lkrriOYQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:birch_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQkBAAACAQAbmFtZRQAbWluZWNyYWZ0OmJpcmNoX3NsYWIECQBuYW1lX2hhc2gZPpfMxoOsTAMKAG5ldHdvcmtfaWThR9jyCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQkBAAACAQAbmFtZRQAbWluZWNyYWZ0OmJpcmNoX3NsYWIECQBuYW1lX2hhc2gZPpfMxoOsTAMKAG5ldHdvcmtfaWThR9jyCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:jungle_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQlBAAACAQAbmFtZRUAbWluZWNyYWZ0Omp1bmdsZV9zbGFiBAkAbmFtZV9oYXNo6gLs79NXak4DCgBuZXR3b3JrX2lk5ZiKgwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQlBAAACAQAbmFtZRUAbWluZWNyYWZ0Omp1bmdsZV9zbGFiBAkAbmFtZV9oYXNo6gLs79NXak4DCgBuZXR3b3JrX2lk5ZiKgwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:acacia_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQmBAAACAQAbmFtZRUAbWluZWNyYWZ0OmFjYWNpYV9zbGFiBAkAbmFtZV9oYXNomSdFmDnv4OUDCgBuZXR3b3JrX2lkHttaXAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQmBAAACAQAbmFtZRUAbWluZWNyYWZ0OmFjYWNpYV9zbGFiBAkAbmFtZV9oYXNomSdFmDnv4OUDCgBuZXR3b3JrX2lkHttaXAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:dark_oak_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQnBAAACAQAbmFtZRcAbWluZWNyYWZ0OmRhcmtfb2FrX3NsYWIECQBuYW1lX2hhc2hJjTohRFyhIQMKAG5ldHdvcmtfaWRMzDTyCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQnBAAACAQAbmFtZRcAbWluZWNyYWZ0OmRhcmtfb2FrX3NsYWIECQBuYW1lX2hhc2hJjTohRFyhIQMKAG5ldHdvcmtfaWRMzDTyCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:mangrove_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWToAgAACAQAbmFtZRcAbWluZWNyYWZ0Om1hbmdyb3ZlX3NsYWIECQBuYW1lX2hhc2jYCcmhJPeNMwMKAG5ldHdvcmtfaWQx6U1yCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWToAgAACAQAbmFtZRcAbWluZWNyYWZ0Om1hbmdyb3ZlX3NsYWIECQBuYW1lX2hhc2jYCcmhJPeNMwMKAG5ldHdvcmtfaWQx6U1yCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:cherry_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQaAwAACAQAbmFtZRUAbWluZWNyYWZ0OmNoZXJyeV9zbGFiBAkAbmFtZV9oYXNoTt0MmVn/mqoDCgBuZXR3b3JrX2lk2VVsZQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQaAwAACAQAbmFtZRUAbWluZWNyYWZ0OmNoZXJyeV9zbGFiBAkAbmFtZV9oYXNoTt0MmVn/mqoDCgBuZXR3b3JrX2lk2VVsZQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:bamboo_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQAAwAACAQAbmFtZRUAbWluZWNyYWZ0OmJhbWJvb19zbGFiBAkAbmFtZV9oYXNoo1xuFqINeLYDCgBuZXR3b3JrX2lkVC+0twoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQAAwAACAQAbmFtZRUAbWluZWNyYWZ0OmJhbWJvb19zbGFiBAkAbmFtZV9oYXNoo1xuFqINeLYDCgBuZXR3b3JrX2lkVC+0twoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:bamboo_mosaic_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQLAwAACAQAbmFtZRwAbWluZWNyYWZ0OmJhbWJvb19tb3NhaWNfc2xhYgQJAG5hbWVfaGFzaNbVRBZ/ChI3AwoAbmV0d29ya19pZOLZHFMKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQLAwAACAQAbmFtZRwAbWluZWNyYWZ0OmJhbWJvb19tb3NhaWNfc2xhYgQJAG5hbWVfaGFzaNbVRBZ/ChI3AwoAbmV0d29ya19pZOLZHFMKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DABUBAA==" }, { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWQSiInOCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQsAc3RvbmVfYnJpY2sAAwcAdmVyc2lvbgRGFAEA" + "id": "minecraft:stone_brick_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRqBAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2JyaWNrX3NsYWIECQBuYW1lX2hhc2js6EexuKuzrQMKAG5ldHdvcmtfaWRSsMxaCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:stone_block_slab4", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkoF89tgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNBEAbW9zc3lfc3RvbmVfYnJpY2sAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkoF89tgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNBEAbW9zc3lfc3RvbmVfYnJpY2sAAwcAdmVyc2lvbgMAFQEA" }, { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWSkoAE4CgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQkAc2FuZHN0b25lAAMHAHZlcnNpb24ERhQBAA==" + "id": "minecraft:sandstone_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRnBAAACAQAbmFtZRgAbWluZWNyYWZ0OnNhbmRzdG9uZV9zbGFiBAkAbmFtZV9oYXNo/GMI0MZnrhsDCgBuZXR3b3JrX2lkFP8WmwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:stone_block_slab4", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkWfF7pgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNA0AY3V0X3NhbmRzdG9uZQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkWfF7pgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNA0AY3V0X3NhbmRzdG9uZQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkbKRChAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAc21vb3RoX3NhbmRzdG9uZQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkbKRChAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAc21vb3RoX3NhbmRzdG9uZQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkBlrvqAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMg0AcmVkX3NhbmRzdG9uZQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkBlrvqAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMg0AcmVkX3NhbmRzdG9uZQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:stone_block_slab4", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkRWFXuwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNBEAY3V0X3JlZF9zYW5kc3RvbmUAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkRWFXuwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNBEAY3V0X3JlZF9zYW5kc3RvbmUAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkom8neQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxQAc21vb3RoX3JlZF9zYW5kc3RvbmUAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkom8neQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxQAc21vb3RoX3JlZF9zYW5kc3RvbmUAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkd1ZaWgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMwcAZ3Jhbml0ZQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkd1ZaWgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMwcAZ3Jhbml0ZQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkISH4iwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxAAcG9saXNoZWRfZ3Jhbml0ZQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkISH4iwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxAAcG9saXNoZWRfZ3Jhbml0ZQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkqxEDMwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMwcAZGlvcml0ZQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkqxEDMwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMwcAZGlvcml0ZQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkSYs86QoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxAAcG9saXNoZWRfZGlvcml0ZQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkSYs86QoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxAAcG9saXNoZWRfZGlvcml0ZQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkq6BU6goGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMwgAYW5kZXNpdGUAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkq6BU6goGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMwgAYW5kZXNpdGUAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkTSXY8AoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxEAcG9saXNoZWRfYW5kZXNpdGUAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkTSXY8AoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMxEAcG9saXNoZWRfYW5kZXNpdGUAAwcAdmVyc2lvbgMAFQEA" }, { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWQiYHKTCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQUAYnJpY2sAAwcAdmVyc2lvbgRGFAEA" + "id": "minecraft:brick_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRpBAAACAQAbmFtZRQAbWluZWNyYWZ0OmJyaWNrX3NsYWIECQBuYW1lX2hhc2hO/Da4jU2v4wMKAG5ldHdvcmtfaWRG/qphCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uAwAVAQA=" }, { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWTk/0LfCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQwAbmV0aGVyX2JyaWNrAAMHAHZlcnNpb24ERhQBAA==" + "id": "minecraft:nether_brick_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRsBAAACAQAbmFtZRsAbWluZWNyYWZ0Om5ldGhlcl9icmlja19zbGFiBAkAbmFtZV9oYXNonymoa2zbbqMDCgBuZXR3b3JrX2lkquvR1QoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lk/hXQ7AoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAcmVkX25ldGhlcl9icmljawADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lk/hXQ7AoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAcmVkX25ldGhlcl9icmljawADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:stone_block_slab3", - "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkYJNxrwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMw8AZW5kX3N0b25lX2JyaWNrAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIzBAkAbmFtZV9oYXNoMw3274NQmpMDCgBuZXR3b3JrX2lkYJNxrwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMw8AZW5kX3N0b25lX2JyaWNrAAMHAHZlcnNpb24DABUBAA==" }, { - "id": "minecraft:stone_block_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAAAACAQAbmFtZRoAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIECQBuYW1lX2hhc2gAP8n+Ya6BWgMKAG5ldHdvcmtfaWRlj0/sCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQgPAHN0b25lX3NsYWJfdHlwZQYAcXVhcnR6AAMHAHZlcnNpb24ERhQBAA==" + "id": "minecraft:quartz_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRrBAAACAQAbmFtZRUAbWluZWNyYWZ0OnF1YXJ0el9zbGFiBAkAbmFtZV9oYXNo9JMj3upfsbwDCgBuZXR3b3JrX2lkn2g2VAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:stone_block_slab4", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkMae+2goGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNA0Ac21vb3RoX3F1YXJ0egADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWI0BAkAbmFtZV9oYXNoNA3274NQmpMDCgBuZXR3b3JrX2lkMae+2goGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfNA0Ac21vb3RoX3F1YXJ0egADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lk+kMHGAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMgYAcHVycHVyAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lk+kMHGAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMgYAcHVycHVyAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkKOSOMAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAcHJpc21hcmluZV9yb3VnaAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkKOSOMAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAcHJpc21hcmluZV9yb3VnaAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lk8igLCQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMg8AcHJpc21hcmluZV9kYXJrAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lk8igLCQoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMg8AcHJpc21hcmluZV9kYXJrAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:stone_block_slab2", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkSFbyEwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAcHJpc21hcmluZV9icmljawADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lX2Jsb2NrX3NsYWIyBAkAbmFtZV9oYXNoMg3274NQmpMDCgBuZXR3b3JrX2lkSFbyEwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20IEQBzdG9uZV9zbGFiX3R5cGVfMhAAcHJpc21hcmluZV9icmljawADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:crimson_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQHAgAACAQAbmFtZRYAbWluZWNyYWZ0OmNyaW1zb25fc2xhYgQJAG5hbWVfaGFzaKZ+EfP0ZYOZAwoAbmV0d29ya19pZAxRUWAKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQHAgAACAQAbmFtZRYAbWluZWNyYWZ0OmNyaW1zb25fc2xhYgQJAG5hbWVfaGFzaKZ+EfP0ZYOZAwoAbmV0d29ya19pZAxRUWAKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:warped_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQIAgAACAQAbmFtZRUAbWluZWNyYWZ0OndhcnBlZF9zbGFiBAkAbmFtZV9oYXNo/AT0e/Z9W7UDCgBuZXR3b3JrX2lk1yq11AoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQIAgAACAQAbmFtZRUAbWluZWNyYWZ0OndhcnBlZF9zbGFiBAkAbmFtZV9oYXNo/AT0e/Z9W7UDCgBuZXR3b3JrX2lk1yq11AoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:blackstone_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQZAgAACAQAbmFtZRkAbWluZWNyYWZ0OmJsYWNrc3RvbmVfc2xhYgQJAG5hbWVfaGFzaF/DD4ZUlNgtAwoAbmV0d29ya19pZGy1DjwKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQZAgAACAQAbmFtZRkAbWluZWNyYWZ0OmJsYWNrc3RvbmVfc2xhYgQJAG5hbWVfaGFzaF/DD4ZUlNgtAwoAbmV0d29ya19pZGy1DjwKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:polished_blackstone_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQkAgAACAQAbmFtZSIAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfc2xhYgQJAG5hbWVfaGFzaDYnuUs86EWfAwoAbmV0d29ya19pZJj2bXIKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQkAgAACAQAbmFtZSIAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfc2xhYgQJAG5hbWVfaGFzaDYnuUs86EWfAwoAbmV0d29ya19pZJj2bXIKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:polished_blackstone_brick_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQbAgAACAQAbmFtZSgAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tfc2xhYgQJAG5hbWVfaGFzaKySLqvHc4xXAwoAbmV0d29ya19pZOyWX94KBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQbAgAACAQAbmFtZSgAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tfc2xhYgQJAG5hbWVfaGFzaKySLqvHc4xXAwoAbmV0d29ya19pZOyWX94KBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:cut_copper_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRoAgAACAQAbmFtZRkAbWluZWNyYWZ0OmN1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaDsNpb2qs4iBAwoAbmV0d29ya19pZOTm2nsKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRoAgAACAQAbmFtZRkAbWluZWNyYWZ0OmN1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaDsNpb2qs4iBAwoAbmV0d29ya19pZOTm2nsKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:exposed_cut_copper_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRpAgAACAQAbmFtZSEAbWluZWNyYWZ0OmV4cG9zZWRfY3V0X2NvcHBlcl9zbGFiBAkAbmFtZV9oYXNoahQ5OwIQb7kDCgBuZXR3b3JrX2lkrUlZLwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRpAgAACAQAbmFtZSEAbWluZWNyYWZ0OmV4cG9zZWRfY3V0X2NvcHBlcl9zbGFiBAkAbmFtZV9oYXNoahQ5OwIQb7kDCgBuZXR3b3JrX2lkrUlZLwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:weathered_cut_copper_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRqAgAACAQAbmFtZSMAbWluZWNyYWZ0OndlYXRoZXJlZF9jdXRfY29wcGVyX3NsYWIECQBuYW1lX2hhc2hBIuGIOVVXogMKAG5ldHdvcmtfaWQgnaDiCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRqAgAACAQAbmFtZSMAbWluZWNyYWZ0OndlYXRoZXJlZF9jdXRfY29wcGVyX3NsYWIECQBuYW1lX2hhc2hBIuGIOVVXogMKAG5ldHdvcmtfaWQgnaDiCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:oxidized_cut_copper_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRrAgAACAQAbmFtZSIAbWluZWNyYWZ0Om94aWRpemVkX2N1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaOptj9ycfpaDAwoAbmV0d29ya19pZMzFSRgKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRrAgAACAQAbmFtZSIAbWluZWNyYWZ0Om94aWRpemVkX2N1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaOptj9ycfpaDAwoAbmV0d29ya19pZMzFSRgKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:waxed_cut_copper_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRsAgAACAQAbmFtZR8AbWluZWNyYWZ0OndheGVkX2N1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaAlx6DZOCTHzAwoAbmV0d29ya19pZFRBvDAKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRsAgAACAQAbmFtZR8AbWluZWNyYWZ0OndheGVkX2N1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaAlx6DZOCTHzAwoAbmV0d29ya19pZFRBvDAKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:waxed_exposed_cut_copper_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRtAgAACAQAbmFtZScAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY3V0X2NvcHBlcl9zbGFiBAkAbmFtZV9oYXNo3KqS5OnhtRIDCgBuZXR3b3JrX2lkHTGcTgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRtAgAACAQAbmFtZScAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY3V0X2NvcHBlcl9zbGFiBAkAbmFtZV9oYXNo3KqS5OnhtRIDCgBuZXR3b3JrX2lkHTGcTgoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:waxed_weathered_cut_copper_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRuAgAACAQAbmFtZSkAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jdXRfY29wcGVyX3NsYWIECQBuYW1lX2hhc2gzZ1oX0HCFtwMKAG5ldHdvcmtfaWSgJR+XCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRuAgAACAQAbmFtZSkAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jdXRfY29wcGVyX3NsYWIECQBuYW1lX2hhc2gzZ1oX0HCFtwMKAG5ldHdvcmtfaWSgJR+XCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:waxed_oxidized_cut_copper_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTAAgAACAQAbmFtZSgAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2N1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaMjjTnLu1KcqAwoAbmV0d29ya19pZIxsnFYKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTAAgAACAQAbmFtZSgAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2N1dF9jb3BwZXJfc2xhYgQJAG5hbWVfaGFzaMjjTnLu1KcqAwoAbmV0d29ya19pZIxsnFYKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:cobbled_deepslate_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR7AgAACAQAbmFtZSAAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlX3NsYWIECQBuYW1lX2hhc2gwJIVWK1TM2QMKAG5ldHdvcmtfaWTYAoX5CgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWR7AgAACAQAbmFtZSAAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlX3NsYWIECQBuYW1lX2hhc2gwJIVWK1TM2QMKAG5ldHdvcmtfaWTYAoX5CgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:polished_deepslate_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR/AgAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZV9zbGFiBAkAbmFtZV9oYXNoC/Adiz8k6RYDCgBuZXR3b3JrX2lkuFYMAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWR/AgAACAQAbmFtZSEAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZV9zbGFiBAkAbmFtZV9oYXNoC/Adiz8k6RYDCgBuZXR3b3JrX2lkuFYMAAoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:deepslate_tile_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAgAACAQAbmFtZR0AbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlX3NsYWIECQBuYW1lX2hhc2hPydV6emzIXAMKAG5ldHdvcmtfaWQwlbFCCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAgAACAQAbmFtZR0AbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlX3NsYWIECQBuYW1lX2hhc2hPydV6emzIXAMKAG5ldHdvcmtfaWQwlbFCCgYAc3RhdGVzCBcAbWluZWNyYWZ0OnZlcnRpY2FsX2hhbGYGAGJvdHRvbQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:deepslate_brick_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSHAgAACAQAbmFtZR4AbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja19zbGFiBAkAbmFtZV9oYXNoSv62V7iw10UDCgBuZXR3b3JrX2lkWMoragoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSHAgAACAQAbmFtZR4AbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja19zbGFiBAkAbmFtZV9oYXNoSv62V7iw10UDCgBuZXR3b3JrX2lkWMoragoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:mud_brick_slab", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTdAgAACAQAbmFtZRgAbWluZWNyYWZ0Om11ZF9icmlja19zbGFiBAkAbmFtZV9oYXNoq/tGBQWkv08DCgBuZXR3b3JrX2lkl4nnMwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTdAgAACAQAbmFtZRgAbWluZWNyYWZ0Om11ZF9icmlja19zbGFiBAkAbmFtZV9oYXNoq/tGBQWkv08DCgBuZXR3b3JrX2lkl4nnMwoGAHN0YXRlcwgXAG1pbmVjcmFmdDp2ZXJ0aWNhbF9oYWxmBgBib3R0b20AAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:brick_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQtAAAACAQAbmFtZRUAbWluZWNyYWZ0OmJyaWNrX2Jsb2NrBAkAbmFtZV9oYXNo5Qc2E005S3oDCgBuZXR3b3JrX2lkqeGWRgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQtAAAACAQAbmFtZRUAbWluZWNyYWZ0OmJyaWNrX2Jsb2NrBAkAbmFtZV9oYXNo5Qc2E005S3oDCgBuZXR3b3JrX2lkqeGWRgoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:chiseled_nether_bricks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQtAgAACAQAbmFtZSAAbWluZWNyYWZ0OmNoaXNlbGVkX25ldGhlcl9icmlja3MECQBuYW1lX2hhc2g31SBPTcUK1QMKAG5ldHdvcmtfaWS8TJ+TCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQtAgAACAQAbmFtZSAAbWluZWNyYWZ0OmNoaXNlbGVkX25ldGhlcl9icmlja3MECQBuYW1lX2hhc2g31SBPTcUK1QMKAG5ldHdvcmtfaWS8TJ+TCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:cracked_nether_bricks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQuAgAACAQAbmFtZR8AbWluZWNyYWZ0OmNyYWNrZWRfbmV0aGVyX2JyaWNrcwQJAG5hbWVfaGFzaAdC6eKzXT5tAwoAbmV0d29ya19pZIUSejwKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQuAgAACAQAbmFtZR8AbWluZWNyYWZ0OmNyYWNrZWRfbmV0aGVyX2JyaWNrcwQJAG5hbWVfaGFzaAdC6eKzXT5tAwoAbmV0d29ya19pZIUSejwKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:quartz_bricks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQvAgAACAQAbmFtZRcAbWluZWNyYWZ0OnF1YXJ0el9icmlja3MECQBuYW1lX2hhc2jSZO590dd8sAMKAG5ldHdvcmtfaWSc5xCLCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQvAgAACAQAbmFtZRcAbWluZWNyYWZ0OnF1YXJ0el9icmlja3MECQBuYW1lX2hhc2jSZO590dd8sAMKAG5ldHdvcmtfaWSc5xCLCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:stonebrick", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAAAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWQ5kni1CgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQcAZGVmYXVsdAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAAAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWQ5kni1CgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQcAZGVmYXVsdAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:stonebrick", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAAAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWTDw813CgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQUAbW9zc3kAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAAAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWTDw813CgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQUAbW9zc3kAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:stonebrick", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAAAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWSTvQGECgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQcAY3JhY2tlZAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAAAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWSTvQGECgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQcAY3JhY2tlZAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:stonebrick", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAAAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWQIM0OwCgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQgAY2hpc2VsZWQAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAAAACAQAbmFtZRQAbWluZWNyYWZ0OnN0b25lYnJpY2sECQBuYW1lX2hhc2ii9DAAVXKptwMKAG5ldHdvcmtfaWQIM0OwCgYAc3RhdGVzCBAAc3RvbmVfYnJpY2tfdHlwZQgAY2hpc2VsZWQAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:end_bricks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTOAAAACAQAbmFtZRQAbWluZWNyYWZ0OmVuZF9icmlja3MECQBuYW1lX2hhc2hIUFfxNLZaFgMKAG5ldHdvcmtfaWQ/vDihCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTOAAAACAQAbmFtZRQAbWluZWNyYWZ0OmVuZF9icmlja3MECQBuYW1lX2hhc2hIUFfxNLZaFgMKAG5ldHdvcmtfaWQ/vDihCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:prismarine", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAAAACAQAbmFtZRQAbWluZWNyYWZ0OnByaXNtYXJpbmUECQBuYW1lX2hhc2jcnQCHi9CspQMKAG5ldHdvcmtfaWSH021WCgYAc3RhdGVzCBUAcHJpc21hcmluZV9ibG9ja190eXBlBgBicmlja3MAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAAAACAQAbmFtZRQAbWluZWNyYWZ0OnByaXNtYXJpbmUECQBuYW1lX2hhc2jcnQCHi9CspQMKAG5ldHdvcmtfaWSH021WCgYAc3RhdGVzCBUAcHJpc21hcmluZV9ibG9ja190eXBlBgBicmlja3MAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:polished_blackstone_bricks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQRAgAACAQAbmFtZSQAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tzBAkAbmFtZV9oYXNoIHgsgIdzKXcDCgBuZXR3b3JrX2lkUw9b3woGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQRAgAACAQAbmFtZSQAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnJpY2tzBAkAbmFtZV9oYXNoIHgsgIdzKXcDCgBuZXR3b3JrX2lkUw9b3woGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:cracked_polished_blackstone_bricks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQXAgAACAQAbmFtZSwAbWluZWNyYWZ0OmNyYWNrZWRfcG9saXNoZWRfYmxhY2tzdG9uZV9icmlja3MECQBuYW1lX2hhc2jQIO1GQDk80AMKAG5ldHdvcmtfaWQ3UlRYCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQXAgAACAQAbmFtZSwAbWluZWNyYWZ0OmNyYWNrZWRfcG9saXNoZWRfYmxhY2tzdG9uZV9icmlja3MECQBuYW1lX2hhc2jQIO1GQDk80AMKAG5ldHdvcmtfaWQ3UlRYCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:gilded_blackstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAgAACAQAbmFtZRsAbWluZWNyYWZ0OmdpbGRlZF9ibGFja3N0b25lBAkAbmFtZV9oYXNoNoWt1ocG0HEDCgBuZXR3b3JrX2lktL8gUwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAgAACAQAbmFtZRsAbWluZWNyYWZ0OmdpbGRlZF9ibGFja3N0b25lBAkAbmFtZV9oYXNoNoWt1ocG0HEDCgBuZXR3b3JrX2lktL8gUwoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:chiseled_polished_blackstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQWAgAACAQAbmFtZSYAbWluZWNyYWZ0OmNoaXNlbGVkX3BvbGlzaGVkX2JsYWNrc3RvbmUECQBuYW1lX2hhc2gzFa+kEjCJgAMKAG5ldHdvcmtfaWR2NJX2CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQWAgAACAQAbmFtZSYAbWluZWNyYWZ0OmNoaXNlbGVkX3BvbGlzaGVkX2JsYWNrc3RvbmUECQBuYW1lX2hhc2gzFa+kEjCJgAMKAG5ldHdvcmtfaWR2NJX2CgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:deepslate_tiles", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSCAgAACAQAbmFtZRkAbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlcwQJAG5hbWVfaGFzaGcLLx3NXAFvAwoAbmV0d29ya19pZI/G/xYKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSCAgAACAQAbmFtZRkAbWluZWNyYWZ0OmRlZXBzbGF0ZV90aWxlcwQJAG5hbWVfaGFzaGcLLx3NXAFvAwoAbmV0d29ya19pZI/G/xYKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:cracked_deepslate_tiles", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSYAgAACAQAbmFtZSEAbWluZWNyYWZ0OmNyYWNrZWRfZGVlcHNsYXRlX3RpbGVzBAkAbmFtZV9oYXNo9zWgkFuMM1QDCgBuZXR3b3JrX2lkGwY6OgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSYAgAACAQAbmFtZSEAbWluZWNyYWZ0OmNyYWNrZWRfZGVlcHNsYXRlX3RpbGVzBAkAbmFtZV9oYXNo9zWgkFuMM1QDCgBuZXR3b3JrX2lkGwY6OgoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:deepslate_bricks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSGAgAACAQAbmFtZRoAbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja3MECQBuYW1lX2hhc2gucvFmPdZxigMKAG5ldHdvcmtfaWSH4HDPCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSGAgAACAQAbmFtZRoAbWluZWNyYWZ0OmRlZXBzbGF0ZV9icmlja3MECQBuYW1lX2hhc2gucvFmPdZxigMKAG5ldHdvcmtfaWSH4HDPCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:cracked_deepslate_bricks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSZAgAACAQAbmFtZSIAbWluZWNyYWZ0OmNyYWNrZWRfZGVlcHNsYXRlX2JyaWNrcwQJAG5hbWVfaGFzaN40aqhh9WqHAwoAbmV0d29ya19pZO9GPBQKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSZAgAACAQAbmFtZSIAbWluZWNyYWZ0OmNyYWNrZWRfZGVlcHNsYXRlX2JyaWNrcwQJAG5hbWVfaGFzaN40aqhh9WqHAwoAbmV0d29ya19pZO9GPBQKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:chiseled_deepslate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSKAgAACAQAbmFtZRwAbWluZWNyYWZ0OmNoaXNlbGVkX2RlZXBzbGF0ZQQJAG5hbWVfaGFzaEU7/uRG8HSBAwoAbmV0d29ya19pZEqmI0EKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSKAgAACAQAbmFtZRwAbWluZWNyYWZ0OmNoaXNlbGVkX2RlZXBzbGF0ZQQJAG5hbWVfaGFzaEU7/uRG8HSBAwoAbmV0d29ya19pZEqmI0EKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:cobblestone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQEAAAACAQAbmFtZRUAbWluZWNyYWZ0OmNvYmJsZXN0b25lBAkAbmFtZV9oYXNoPoK7mGlSUz4DCgBuZXR3b3JrX2lkLm7RZwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQEAAAACAQAbmFtZRUAbWluZWNyYWZ0OmNvYmJsZXN0b25lBAkAbmFtZV9oYXNoPoK7mGlSUz4DCgBuZXR3b3JrX2lkLm7RZwoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:mossy_cobblestone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQwAAAACAQAbmFtZRsAbWluZWNyYWZ0Om1vc3N5X2NvYmJsZXN0b25lBAkAbmFtZV9oYXNoGJ67FCbkChMDCgBuZXR3b3JrX2lk/pYs1AoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQwAAAACAQAbmFtZRsAbWluZWNyYWZ0Om1vc3N5X2NvYmJsZXN0b25lBAkAbmFtZV9oYXNoGJ67FCbkChMDCgBuZXR3b3JrX2lk/pYs1AoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:cobbled_deepslate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR6AgAACAQAbmFtZRsAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlBAkAbmFtZV9oYXNoLUz9Y/ywmLwDCgBuZXR3b3JrX2lkNwzZ+AoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWR6AgAACAQAbmFtZRsAbWluZWNyYWZ0OmNvYmJsZWRfZGVlcHNsYXRlBAkAbmFtZV9oYXNoLUz9Y/ywmLwDCgBuZXR3b3JrX2lkNwzZ+AoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:smooth_stone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AQAACAQAbmFtZRYAbWluZWNyYWZ0OnNtb290aF9zdG9uZQQJAG5hbWVfaGFzaMwf87/JaTNvAwoAbmV0d29ya19pZLkZICEKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWS2AQAACAQAbmFtZRYAbWluZWNyYWZ0OnNtb290aF9zdG9uZQQJAG5hbWVfaGFzaMwf87/JaTNvAwoAbmV0d29ya19pZLkZICEKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:sandstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZB2wApMKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGUHAGRlZmF1bHQAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZB2wApMKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGUHAGRlZmF1bHQAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:sandstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZB7E+eQKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGULAGhlaXJvZ2x5cGhzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZB7E+eQKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGULAGhlaXJvZ2x5cGhzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:sandstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZFQnDaEKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGUDAGN1dAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZFQnDaEKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGUDAGN1dAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:sandstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZPO4A3IKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGUGAHNtb290aAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNhbmRzdG9uZQQJAG5hbWVfaGFzaFEmWsEHFI1AAwoAbmV0d29ya19pZPO4A3IKBgBzdGF0ZXMIDwBzYW5kX3N0b25lX3R5cGUGAHNtb290aAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:red_sandstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWRhNYiFCgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlBwBkZWZhdWx0AAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWRhNYiFCgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlBwBkZWZhdWx0AAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:red_sandstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWTqXJr1CgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlCwBoZWlyb2dseXBocwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWTqXJr1CgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlCwBoZWlyb2dseXBocwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:red_sandstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWTQRGkFCgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlAwBjdXQAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWTQRGkFCgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlAwBjdXQAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:red_sandstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWTvAHWDCgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlBgBzbW9vdGgAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSzAAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZF9zYW5kc3RvbmUECQBuYW1lX2hhc2jBO4Gv2v59uAMKAG5ldHdvcmtfaWTvAHWDCgYAc3RhdGVzCA8Ac2FuZF9zdG9uZV90eXBlBgBzbW9vdGgAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:coal_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWStAAAACAQAbmFtZRQAbWluZWNyYWZ0OmNvYWxfYmxvY2sECQBuYW1lX2hhc2jH8QQP3t5PiAMKAG5ldHdvcmtfaWRo+sR+CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWStAAAACAQAbmFtZRQAbWluZWNyYWZ0OmNvYWxfYmxvY2sECQBuYW1lX2hhc2jH8QQP3t5PiAMKAG5ldHdvcmtfaWRo+sR+CgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:dried_kelp_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSKAQAACAQAbmFtZRoAbWluZWNyYWZ0OmRyaWVkX2tlbHBfYmxvY2sECQBuYW1lX2hhc2iRoucexkrl8wMKAG5ldHdvcmtfaWQQCCrvCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSKAQAACAQAbmFtZRoAbWluZWNyYWZ0OmRyaWVkX2tlbHBfYmxvY2sECQBuYW1lX2hhc2iRoucexkrl8wMKAG5ldHdvcmtfaWQQCCrvCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:gold_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQpAAAACAQAbmFtZRQAbWluZWNyYWZ0OmdvbGRfYmxvY2sECQBuYW1lX2hhc2iYLshvjtXzFwMKAG5ldHdvcmtfaWTDJGBcCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQpAAAACAQAbmFtZRQAbWluZWNyYWZ0OmdvbGRfYmxvY2sECQBuYW1lX2hhc2iYLshvjtXzFwMKAG5ldHdvcmtfaWTDJGBcCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:iron_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQqAAAACAQAbmFtZRQAbWluZWNyYWZ0Omlyb25fYmxvY2sECQBuYW1lX2hhc2jYINmJQbvV/gMKAG5ldHdvcmtfaWRf7AbICgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQqAAAACAQAbmFtZRQAbWluZWNyYWZ0Omlyb25fYmxvY2sECQBuYW1lX2hhc2jYINmJQbvV/gMKAG5ldHdvcmtfaWRf7AbICgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:copper_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRTAgAACAQAbmFtZRYAbWluZWNyYWZ0OmNvcHBlcl9ibG9jawQJAG5hbWVfaGFzaDVxnehsGaZ1AwoAbmV0d29ya19pZIiUodwKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRTAgAACAQAbmFtZRYAbWluZWNyYWZ0OmNvcHBlcl9ibG9jawQJAG5hbWVfaGFzaDVxnehsGaZ1AwoAbmV0d29ya19pZIiUodwKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" + }, + { + "id": "minecraft:copper_door" + }, + { + "id": "minecraft:copper_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQXBAAACAQAbmFtZRkAbWluZWNyYWZ0OmNvcHBlcl90cmFwZG9vcgQJAG5hbWVfaGFzaO9fXio+svKVAwoAbmV0d29ya19pZMCoRjEKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uAwAVAQA=" + }, + { + "id": "minecraft:copper_grate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT/AwAACAQAbmFtZRYAbWluZWNyYWZ0OmNvcHBlcl9ncmF0ZQQJAG5hbWVfaGFzaC/JEFOWnmEcAwoAbmV0d29ya19pZC6YiiMKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:exposed_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRUAgAACAQAbmFtZRgAbWluZWNyYWZ0OmV4cG9zZWRfY29wcGVyBAkAbmFtZV9oYXNoQH3Fukmu3CEDCgBuZXR3b3JrX2lk72jFIwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRUAgAACAQAbmFtZRgAbWluZWNyYWZ0OmV4cG9zZWRfY29wcGVyBAkAbmFtZV9oYXNoQH3Fukmu3CEDCgBuZXR3b3JrX2lk72jFIwoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" + }, + { + "id": "minecraft:exposed_copper_door" + }, + { + "id": "minecraft:exposed_copper_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQYBAAACAQAbmFtZSEAbWluZWNyYWZ0OmV4cG9zZWRfY29wcGVyX3RyYXBkb29yBAkAbmFtZV9oYXNoYhDFUysN7qUDCgBuZXR3b3JrX2lkMzwGJgoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24DABUBAA==" + }, + { + "id": "minecraft:exposed_copper_grate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQABAAACAQAbmFtZR4AbWluZWNyYWZ0OmV4cG9zZWRfY29wcGVyX2dyYXRlBAkAbmFtZV9oYXNolFIBYLYU0IcDCgBuZXR3b3JrX2lk4UqptAoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:weathered_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRVAgAACAQAbmFtZRoAbWluZWNyYWZ0OndlYXRoZXJlZF9jb3BwZXIECQBuYW1lX2hhc2hJCQXbvobv+gMKAG5ldHdvcmtfaWQwM0lJCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRVAgAACAQAbmFtZRoAbWluZWNyYWZ0OndlYXRoZXJlZF9jb3BwZXIECQBuYW1lX2hhc2hJCQXbvobv+gMKAG5ldHdvcmtfaWQwM0lJCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" + }, + { + "id": "minecraft:weathered_copper_door" + }, + { + "id": "minecraft:weathered_copper_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQZBAAACAQAbmFtZSMAbWluZWNyYWZ0OndlYXRoZXJlZF9jb3BwZXJfdHJhcGRvb3IECQBuYW1lX2hhc2hFnEC282a1tgMKAG5ldHdvcmtfaWTk70oiCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAEPAHVwc2lkZV9kb3duX2JpdAAAAwcAdmVyc2lvbgMAFQEA" + }, + { + "id": "minecraft:weathered_copper_grate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQBBAAACAQAbmFtZSAAbWluZWNyYWZ0OndlYXRoZXJlZF9jb3BwZXJfZ3JhdGUECQBuYW1lX2hhc2jB3o8enlv1RgMKAG5ldHdvcmtfaWRih2pOCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:oxidized_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRWAgAACAQAbmFtZRkAbWluZWNyYWZ0Om94aWRpemVkX2NvcHBlcgQJAG5hbWVfaGFzaMDtJqR0G5Y7AwoAbmV0d29ya19pZGjN8bUKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRWAgAACAQAbmFtZRkAbWluZWNyYWZ0Om94aWRpemVkX2NvcHBlcgQJAG5hbWVfaGFzaMDtJqR0G5Y7AwoAbmV0d29ya19pZGjN8bUKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" + }, + { + "id": "minecraft:oxidized_copper_door" + }, + { + "id": "minecraft:oxidized_copper_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQaBAAACAQAbmFtZSIAbWluZWNyYWZ0Om94aWRpemVkX2NvcHBlcl90cmFwZG9vcgQJAG5hbWVfaGFzaOJpG/XFexVwAwoAbmV0d29ya19pZPhi0J4KBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uAwAVAQA=" + }, + { + "id": "minecraft:oxidized_copper_grate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQCBAAACAQAbmFtZR8AbWluZWNyYWZ0Om94aWRpemVkX2NvcHBlcl9ncmF0ZQQJAG5hbWVfaGFzaBRfNhyndve7AwoAbmV0d29ya19pZKY2cnEKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:waxed_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRXAgAACAQAbmFtZRYAbWluZWNyYWZ0OndheGVkX2NvcHBlcgQJAG5hbWVfaGFzaPF+FG6Eh5fsAwoAbmV0d29ya19pZIjtz/0KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRXAgAACAQAbmFtZRYAbWluZWNyYWZ0OndheGVkX2NvcHBlcgQJAG5hbWVfaGFzaPF+FG6Eh5fsAwoAbmV0d29ya19pZIjtz/0KBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" + }, + { + "id": "minecraft:waxed_copper_door" + }, + { + "id": "minecraft:waxed_copper_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQbBAAACAQAbmFtZR8AbWluZWNyYWZ0OndheGVkX2NvcHBlcl90cmFwZG9vcgQJAG5hbWVfaGFzaO0JUKUHqNU6AwoAbmV0d29ya19pZJC3ZuMKBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uAwAVAQA=" + }, + { + "id": "minecraft:waxed_copper_grate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQDBAAACAQAbmFtZRwAbWluZWNyYWZ0OndheGVkX2NvcHBlcl9ncmF0ZQQJAG5hbWVfaGFzaDmC92M2RO+HAwoAbmV0d29ya19pZH4og2AKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:waxed_exposed_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRYAgAACAQAbmFtZR4AbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY29wcGVyBAkAbmFtZV9oYXNoig8IOc+SCikDCgBuZXR3b3JrX2lklz8yWQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRYAgAACAQAbmFtZR4AbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY29wcGVyBAkAbmFtZV9oYXNoig8IOc+SCikDCgBuZXR3b3JrX2lklz8yWQoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" + }, + { + "id": "minecraft:waxed_exposed_copper_door" + }, + { + "id": "minecraft:waxed_exposed_copper_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQcBAAACAQAbmFtZScAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY29wcGVyX3RyYXBkb29yBAkAbmFtZV9oYXNoBHHxCpkUzpgDCgBuZXR3b3JrX2lkw2XBGQoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAABCABvcGVuX2JpdAABDwB1cHNpZGVfZG93bl9iaXQAAAMHAHZlcnNpb24DABUBAA==" + }, + { + "id": "minecraft:waxed_exposed_copper_grate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQEBAAACAQAbmFtZSQAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY29wcGVyX2dyYXRlBAkAbmFtZV9oYXNoWmd6B+hWwiEDCgBuZXR3b3JrX2lk8d4ZQwoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:waxed_weathered_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRZAgAACAQAbmFtZSAAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jb3BwZXIECQBuYW1lX2hhc2gjtPq8MOdvKgMKAG5ldHdvcmtfaWSQ9Ln9CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRZAgAACAQAbmFtZSAAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jb3BwZXIECQBuYW1lX2hhc2gjtPq8MOdvKgMKAG5ldHdvcmtfaWSQ9Ln9CgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" + }, + { + "id": "minecraft:waxed_weathered_copper_door" + }, + { + "id": "minecraft:waxed_weathered_copper_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQdBAAACAQAbmFtZSkAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jb3BwZXJfdHJhcGRvb3IECQBuYW1lX2hhc2gH9Fi3JCF4egMKAG5ldHdvcmtfaWRkGU6TCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAEPAHVwc2lkZV9kb3duX2JpdAAAAwcAdmVyc2lvbgMAFQEA" + }, + { + "id": "minecraft:waxed_weathered_copper_grate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQFBAAACAQAbmFtZSYAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jb3BwZXJfZ3JhdGUECQBuYW1lX2hhc2hXfilVFDAiYQMKAG5ldHdvcmtfaWQqTGC1CgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:waxed_oxidized_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS9AgAACAQAbmFtZR8AbWluZWNyYWZ0OndheGVkX294aWRpemVkX2NvcHBlcgQJAG5hbWVfaGFzaMaORhsO+LzjAwoAbmV0d29ya19pZJhGfLEKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWS9AgAACAQAbmFtZR8AbWluZWNyYWZ0OndheGVkX294aWRpemVkX2NvcHBlcgQJAG5hbWVfaGFzaMaORhsO+LzjAwoAbmV0d29ya19pZJhGfLEKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" + }, + { + "id": "minecraft:waxed_oxidized_copper_door" + }, + { + "id": "minecraft:waxed_oxidized_copper_trapdoor", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQeBAAACAQAbmFtZSgAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2NvcHBlcl90cmFwZG9vcgQJAG5hbWVfaGFzaNA/q9qAy6Z9AwoAbmV0d29ya19pZDgExS8KBgBzdGF0ZXMDCQBkaXJlY3Rpb24AAAAAAQgAb3Blbl9iaXQAAQ8AdXBzaWRlX2Rvd25fYml0AAADBwB2ZXJzaW9uAwAVAQA=" + }, + { + "id": "minecraft:waxed_oxidized_copper_grate", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQGBAAACAQAbmFtZSUAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2NvcHBlcl9ncmF0ZQQJAG5hbWVfaGFzaEbeMT605GP4AwoAbmV0d29ya19pZOZjpkkKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:cut_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRaAgAACAQAbmFtZRQAbWluZWNyYWZ0OmN1dF9jb3BwZXIECQBuYW1lX2hhc2hAfN3NGax3eAMKAG5ldHdvcmtfaWTnFBtYCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRaAgAACAQAbmFtZRQAbWluZWNyYWZ0OmN1dF9jb3BwZXIECQBuYW1lX2hhc2hAfN3NGax3eAMKAG5ldHdvcmtfaWTnFBtYCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:exposed_cut_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRbAgAACAQAbmFtZRwAbWluZWNyYWZ0OmV4cG9zZWRfY3V0X2NvcHBlcgQJAG5hbWVfaGFzaA85G3yv/w6pAwoAbmV0d29ya19pZMQhr0QKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRbAgAACAQAbmFtZRwAbWluZWNyYWZ0OmV4cG9zZWRfY3V0X2NvcHBlcgQJAG5hbWVfaGFzaA85G3yv/w6pAwoAbmV0d29ya19pZMQhr0QKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:weathered_cut_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRcAgAACAQAbmFtZR4AbWluZWNyYWZ0OndlYXRoZXJlZF9jdXRfY29wcGVyBAkAbmFtZV9oYXNoVgRV0fBaz88DCgBuZXR3b3JrX2lk/0cYugoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRcAgAACAQAbmFtZR4AbWluZWNyYWZ0OndlYXRoZXJlZF9jdXRfY29wcGVyBAkAbmFtZV9oYXNoVgRV0fBaz88DCgBuZXR3b3JrX2lk/0cYugoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:oxidized_cut_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRdAgAACAQAbmFtZR0AbWluZWNyYWZ0Om94aWRpemVkX2N1dF9jb3BwZXIECQBuYW1lX2hhc2iP8WmFWOkriwMKAG5ldHdvcmtfaWQPdce7CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRdAgAACAQAbmFtZR0AbWluZWNyYWZ0Om94aWRpemVkX2N1dF9jb3BwZXIECQBuYW1lX2hhc2iP8WmFWOkriwMKAG5ldHdvcmtfaWQPdce7CgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:waxed_cut_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWReAgAACAQAbmFtZRoAbWluZWNyYWZ0OndheGVkX2N1dF9jb3BwZXIECQBuYW1lX2hhc2jumiwOZIqv2AMKAG5ldHdvcmtfaWQvuxx9CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWReAgAACAQAbmFtZRoAbWluZWNyYWZ0OndheGVkX2N1dF9jb3BwZXIECQBuYW1lX2hhc2jumiwOZIqv2AMKAG5ldHdvcmtfaWQvuxx9CgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:waxed_exposed_cut_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRfAgAACAQAbmFtZSIAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY3V0X2NvcHBlcgQJAG5hbWVfaGFzaPE/OfK6IoVMAwoAbmV0d29ya19pZHy5HkcKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRfAgAACAQAbmFtZSIAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY3V0X2NvcHBlcgQJAG5hbWVfaGFzaPE/OfK6IoVMAwoAbmV0d29ya19pZHy5HkcKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:waxed_weathered_cut_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRgAgAACAQAbmFtZSQAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jdXRfY29wcGVyBAkAbmFtZV9oYXNoCA1xDp11bnwDCgBuZXR3b3JrX2lkDyEDVQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRgAgAACAQAbmFtZSQAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jdXRfY29wcGVyBAkAbmFtZV9oYXNoCA1xDp11bnwDCgBuZXR3b3JrX2lkDyEDVQoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:waxed_oxidized_cut_copper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWS+AgAACAQAbmFtZSMAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2N1dF9jb3BwZXIECQBuYW1lX2hhc2i1pZAsZYHLDAMKAG5ldHdvcmtfaWQ/wSkCCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWS+AgAACAQAbmFtZSMAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2N1dF9jb3BwZXIECQBuYW1lX2hhc2i1pZAsZYHLDAMKAG5ldHdvcmtfaWQ/wSkCCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" + }, + { + "id": "minecraft:chiseled_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT3AwAACAQAbmFtZRkAbWluZWNyYWZ0OmNoaXNlbGVkX2NvcHBlcgQJAG5hbWVfaGFzaIsW5pmpJEuQAwoAbmV0d29ya19pZHetwrkKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" + }, + { + "id": "minecraft:exposed_chiseled_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT4AwAACAQAbmFtZSEAbWluZWNyYWZ0OmV4cG9zZWRfY2hpc2VsZWRfY29wcGVyBAkAbmFtZV9oYXNoOvrLJ0UowbgDCgBuZXR3b3JrX2lkZj7cPwoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" + }, + { + "id": "minecraft:weathered_chiseled_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT5AwAACAQAbmFtZSMAbWluZWNyYWZ0OndlYXRoZXJlZF9jaGlzZWxlZF9jb3BwZXIECQBuYW1lX2hhc2hh+42XlsWvGAMKAG5ldHdvcmtfaWS7Cy59CgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" + }, + { + "id": "minecraft:oxidized_chiseled_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT6AwAACAQAbmFtZSIAbWluZWNyYWZ0Om94aWRpemVkX2NoaXNlbGVkX2NvcHBlcgQJAG5hbWVfaGFzaLpTIsnfluiCAwoAbmV0d29ya19pZB9/jS8KBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" + }, + { + "id": "minecraft:waxed_chiseled_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT7AwAACAQAbmFtZR8AbWluZWNyYWZ0OndheGVkX2NoaXNlbGVkX2NvcHBlcgQJAG5hbWVfaGFzaFnXvXY5OinzAwoAbmV0d29ya19pZAcKtHsKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" + }, + { + "id": "minecraft:waxed_exposed_chiseled_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT8AwAACAQAbmFtZScAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY2hpc2VsZWRfY29wcGVyBAkAbmFtZV9oYXNoHJdq+Pph6hMDCgBuZXR3b3JrX2lkdge7IAoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" + }, + { + "id": "minecraft:waxed_oxidized_chiseled_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT9AwAACAQAbmFtZSgAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2NoaXNlbGVkX2NvcHBlcgQJAG5hbWVfaGFzaMj49OvlTpgCAwoAbmV0d29ya19pZN/r+roKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" + }, + { + "id": "minecraft:waxed_weathered_chiseled_copper", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT+AwAACAQAbmFtZSkAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jaGlzZWxlZF9jb3BwZXIECQBuYW1lX2hhc2hzuO+Sg9LYQwMKAG5ldHdvcmtfaWQ7AN7iCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" + }, + { + "id": "minecraft:copper_bulb", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQHBAAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcHBlcl9idWxiBAkAbmFtZV9oYXNo41TimHOsMWcDCgBuZXR3b3JrX2lkJnZvAgoGAHN0YXRlcwEDAGxpdAABCwBwb3dlcmVkX2JpdAAAAwcAdmVyc2lvbgMAFQEA" + }, + { + "id": "minecraft:exposed_copper_bulb", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQIBAAACAQAbmFtZR0AbWluZWNyYWZ0OmV4cG9zZWRfY29wcGVyX2J1bGIECQBuYW1lX2hhc2g++f1wYLLCrAMKAG5ldHdvcmtfaWRLdMmGCgYAc3RhdGVzAQMAbGl0AAELAHBvd2VyZWRfYml0AAADBwB2ZXJzaW9uAwAVAQA=" + }, + { + "id": "minecraft:weathered_copper_bulb", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQJBAAACAQAbmFtZR8AbWluZWNyYWZ0OndlYXRoZXJlZF9jb3BwZXJfYnVsYgQJAG5hbWVfaGFzaMEtsYfwRTXlAwoAbmV0d29ya19pZAp51LQKBgBzdGF0ZXMBAwBsaXQAAQsAcG93ZXJlZF9iaXQAAAMHAHZlcnNpb24DABUBAA==" + }, + { + "id": "minecraft:oxidized_copper_bulb", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQKBAAACAQAbmFtZR4AbWluZWNyYWZ0Om94aWRpemVkX2NvcHBlcl9idWxiBAkAbmFtZV9oYXNovnrBQZs8nDIDCgBuZXR3b3JrX2lkPsj0AAoGAHN0YXRlcwEDAGxpdAABCwBwb3dlcmVkX2JpdAAAAwcAdmVyc2lvbgMAFQEA" + }, + { + "id": "minecraft:waxed_copper_bulb", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQLBAAACAQAbmFtZRsAbWluZWNyYWZ0OndheGVkX2NvcHBlcl9idWxiBAkAbmFtZV9oYXNoGTg6TYllMiIDCgBuZXR3b3JrX2lk9m0WhgoGAHN0YXRlcwEDAGxpdAABCwBwb3dlcmVkX2JpdAAAAwcAdmVyc2lvbgMAFQEA" + }, + { + "id": "minecraft:waxed_exposed_copper_bulb", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQMBAAACAQAbmFtZSMAbWluZWNyYWZ0OndheGVkX2V4cG9zZWRfY29wcGVyX2J1bGIECQBuYW1lX2hhc2gI6xkPcvBDVwMKAG5ldHdvcmtfaWR7BRcACgYAc3RhdGVzAQMAbGl0AAELAHBvd2VyZWRfYml0AAADBwB2ZXJzaW9uAwAVAQA=" + }, + { + "id": "minecraft:waxed_weathered_copper_bulb", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQNBAAACAQAbmFtZSUAbWluZWNyYWZ0OndheGVkX3dlYXRoZXJlZF9jb3BwZXJfYnVsYgQJAG5hbWVfaGFzaMsUnmp3/VqVAwoAbmV0d29ya19pZEoworoKBgBzdGF0ZXMBAwBsaXQAAQsAcG93ZXJlZF9iaXQAAAMHAHZlcnNpb24DABUBAA==" + }, + { + "id": "minecraft:waxed_oxidized_copper_bulb", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQOBAAACAQAbmFtZSQAbWluZWNyYWZ0OndheGVkX294aWRpemVkX2NvcHBlcl9idWxiBAkAbmFtZV9oYXNoBFKxY3fjVq4DCgBuZXR3b3JrX2lkzrJ6aAoGAHN0YXRlcwEDAGxpdAABCwBwb3dlcmVkX2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:emerald_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAAAACAQAbmFtZRcAbWluZWNyYWZ0OmVtZXJhbGRfYmxvY2sECQBuYW1lX2hhc2hK6QunqJznNAMKAG5ldHdvcmtfaWRk5+otCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAAAACAQAbmFtZRcAbWluZWNyYWZ0OmVtZXJhbGRfYmxvY2sECQBuYW1lX2hhc2hK6QunqJznNAMKAG5ldHdvcmtfaWRk5+otCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:diamond_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ5AAAACAQAbmFtZRcAbWluZWNyYWZ0OmRpYW1vbmRfYmxvY2sECQBuYW1lX2hhc2iGKrxuvkytFQMKAG5ldHdvcmtfaWQQeQZXCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ5AAAACAQAbmFtZRcAbWluZWNyYWZ0OmRpYW1vbmRfYmxvY2sECQBuYW1lX2hhc2iGKrxuvkytFQMKAG5ldHdvcmtfaWQQeQZXCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:lapis_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQWAAAACAQAbmFtZRUAbWluZWNyYWZ0OmxhcGlzX2Jsb2NrBAkAbmFtZV9oYXNoDZ44xdb2zVoDCgBuZXR3b3JrX2lktVy0BAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQWAAAACAQAbmFtZRUAbWluZWNyYWZ0OmxhcGlzX2Jsb2NrBAkAbmFtZV9oYXNoDZ44xdb2zVoDCgBuZXR3b3JrX2lktVy0BAoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:raw_iron_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTCAgAACAQAbmFtZRgAbWluZWNyYWZ0OnJhd19pcm9uX2Jsb2NrBAkAbmFtZV9oYXNo9XyzNIQXxvwDCgBuZXR3b3JrX2lknms1QAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTCAgAACAQAbmFtZRgAbWluZWNyYWZ0OnJhd19pcm9uX2Jsb2NrBAkAbmFtZV9oYXNo9XyzNIQXxvwDCgBuZXR3b3JrX2lknms1QAoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:raw_copper_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTDAgAACAQAbmFtZRoAbWluZWNyYWZ0OnJhd19jb3BwZXJfYmxvY2sECQBuYW1lX2hhc2hw1KG0TNUGgwMKAG5ldHdvcmtfaWS1vGo/CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTDAgAACAQAbmFtZRoAbWluZWNyYWZ0OnJhd19jb3BwZXJfYmxvY2sECQBuYW1lX2hhc2hw1KG0TNUGgwMKAG5ldHdvcmtfaWS1vGo/CgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:raw_gold_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTEAgAACAQAbmFtZRgAbWluZWNyYWZ0OnJhd19nb2xkX2Jsb2NrBAkAbmFtZV9oYXNo6YuwuLwfOBwDCgBuZXR3b3JrX2lkLiQ5gQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTEAgAACAQAbmFtZRgAbWluZWNyYWZ0OnJhd19nb2xkX2Jsb2NrBAkAbmFtZV9oYXNo6YuwuLwfOBwDCgBuZXR3b3JrX2lkLiQ5gQoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:quartz_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAAAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZEupC1AKBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQcAZGVmYXVsdAgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAAAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZEupC1AKBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQcAZGVmYXVsdAgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:quartz_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAAAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZM97+l0KBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQUAbGluZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAAAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZM97+l0KBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQUAbGluZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:quartz_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAAAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZCbTfssKBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQgAY2hpc2VsZWQICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAAAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZCbTfssKBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQgAY2hpc2VsZWQICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:quartz_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAAAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZJss8V0KBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQYAc21vb3RoCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAAAACAQAbmFtZRYAbWluZWNyYWZ0OnF1YXJ0el9ibG9jawQJAG5hbWVfaGFzaCfpbqyIIvZCAwoAbmV0d29ya19pZJss8V0KBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQYAc21vb3RoCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:prismarine", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAAAACAQAbmFtZRQAbWluZWNyYWZ0OnByaXNtYXJpbmUECQBuYW1lX2hhc2jcnQCHi9CspQMKAG5ldHdvcmtfaWRFIsoGCgYAc3RhdGVzCBUAcHJpc21hcmluZV9ibG9ja190eXBlBwBkZWZhdWx0AAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAAAACAQAbmFtZRQAbWluZWNyYWZ0OnByaXNtYXJpbmUECQBuYW1lX2hhc2jcnQCHi9CspQMKAG5ldHdvcmtfaWRFIsoGCgYAc3RhdGVzCBUAcHJpc21hcmluZV9ibG9ja190eXBlBwBkZWZhdWx0AAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:prismarine", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAAAACAQAbmFtZRQAbWluZWNyYWZ0OnByaXNtYXJpbmUECQBuYW1lX2hhc2jcnQCHi9CspQMKAG5ldHdvcmtfaWTDNWOvCgYAc3RhdGVzCBUAcHJpc21hcmluZV9ibG9ja190eXBlBABkYXJrAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAAAACAQAbmFtZRQAbWluZWNyYWZ0OnByaXNtYXJpbmUECQBuYW1lX2hhc2jcnQCHi9CspQMKAG5ldHdvcmtfaWTDNWOvCgYAc3RhdGVzCBUAcHJpc21hcmluZV9ibG9ja190eXBlBABkYXJrAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:slime", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAAAACAQAbmFtZQ8AbWluZWNyYWZ0OnNsaW1lBAkAbmFtZV9oYXNoHJiEEJx+JlkDCgBuZXR3b3JrX2lkfgfVzAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAAAACAQAbmFtZQ8AbWluZWNyYWZ0OnNsaW1lBAkAbmFtZV9oYXNoHJiEEJx+JlkDCgBuZXR3b3JrX2lkfgfVzAoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:honey_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTbAQAACAQAbmFtZRUAbWluZWNyYWZ0OmhvbmV5X2Jsb2NrBAkAbmFtZV9oYXNo9zLYSUlelywDCgBuZXR3b3JrX2lko+dyWgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTbAQAACAQAbmFtZRUAbWluZWNyYWZ0OmhvbmV5X2Jsb2NrBAkAbmFtZV9oYXNo9zLYSUlelywDCgBuZXR3b3JrX2lko+dyWgoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:honeycomb_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTcAQAACAQAbmFtZRkAbWluZWNyYWZ0OmhvbmV5Y29tYl9ibG9jawQJAG5hbWVfaGFzaASIPuOCYd1oAwoAbmV0d29ya19pZKys4n4KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTcAQAACAQAbmFtZRkAbWluZWNyYWZ0OmhvbmV5Y29tYl9ibG9jawQJAG5hbWVfaGFzaASIPuOCYd1oAwoAbmV0d29ya19pZKys4n4KBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:hay_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSqAAAACAQAbmFtZRMAbWluZWNyYWZ0OmhheV9ibG9jawQJAG5hbWVfaGFzaIB2VxKxX8EpAwoAbmV0d29ya19pZKuQSloKBgBzdGF0ZXMDCgBkZXByZWNhdGVkAAAAAAgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSqAAAACAQAbmFtZRMAbWluZWNyYWZ0OmhheV9ibG9jawQJAG5hbWVfaGFzaIB2VxKxX8EpAwoAbmV0d29ya19pZKuQSloKBgBzdGF0ZXMDCgBkZXByZWNhdGVkAAAAAAgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:bone_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTYAAAACAQAbmFtZRQAbWluZWNyYWZ0OmJvbmVfYmxvY2sECQBuYW1lX2hhc2i4ZX576W9AWgMKAG5ldHdvcmtfaWTWGacQCgYAc3RhdGVzAwoAZGVwcmVjYXRlZAAAAAAICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTYAAAACAQAbmFtZRQAbWluZWNyYWZ0OmJvbmVfYmxvY2sECQBuYW1lX2hhc2i4ZX576W9AWgMKAG5ldHdvcmtfaWTWGacQCgYAc3RhdGVzAwoAZGVwcmVjYXRlZAAAAAAICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:nether_brick", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRwAAAACAQAbmFtZRYAbWluZWNyYWZ0Om5ldGhlcl9icmljawQJAG5hbWVfaGFzaMxcRiheU+nXAwoAbmV0d29ya19pZMkmzloKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRwAAAACAQAbmFtZRYAbWluZWNyYWZ0Om5ldGhlcl9icmljawQJAG5hbWVfaGFzaMxcRiheU+nXAwoAbmV0d29ya19pZMkmzloKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:red_nether_brick", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTXAAAACAQAbmFtZRoAbWluZWNyYWZ0OnJlZF9uZXRoZXJfYnJpY2sECQBuYW1lX2hhc2j8pRO4LfoECAMKAG5ldHdvcmtfaWRpdF0YCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTXAAAACAQAbmFtZRoAbWluZWNyYWZ0OnJlZF9uZXRoZXJfYnJpY2sECQBuYW1lX2hhc2j8pRO4LfoECAMKAG5ldHdvcmtfaWRpdF0YCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:netherite_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQNAgAACAQAbmFtZRkAbWluZWNyYWZ0Om5ldGhlcml0ZV9ibG9jawQJAG5hbWVfaGFzaMghh6Zib/ZKAwoAbmV0d29ya19pZIz0mq0KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQNAgAACAQAbmFtZRkAbWluZWNyYWZ0Om5ldGhlcml0ZV9ibG9jawQJAG5hbWVfaGFzaMghh6Zib/ZKAwoAbmV0d29ya19pZIz0mq0KBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:lodestone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTdAQAACAQAbmFtZRMAbWluZWNyYWZ0OmxvZGVzdG9uZQQJAG5hbWVfaGFzaJ2gmHOTlXv8AwoAbmV0d29ya19pZEfgB4wKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTdAQAACAQAbmFtZRMAbWluZWNyYWZ0OmxvZGVzdG9uZQQJAG5hbWVfaGFzaJ2gmHOTlXv8AwoAbmV0d29ya19pZEfgB4wKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:white_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQjAAAACAQAbmFtZRQAbWluZWNyYWZ0OndoaXRlX3dvb2wECQBuYW1lX2hhc2jRWB7vaIEDiQMKAG5ldHdvcmtfaWSO8paQCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQjAAAACAQAbmFtZRQAbWluZWNyYWZ0OndoaXRlX3dvb2wECQBuYW1lX2hhc2jRWB7vaIEDiQMKAG5ldHdvcmtfaWSO8paQCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:light_gray_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQnAwAACAQAbmFtZRkAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfd29vbAQJAG5hbWVfaGFzaOpdQ1a2v4b3AwoAbmV0d29ya19pZIqZCYEKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQnAwAACAQAbmFtZRkAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfd29vbAQJAG5hbWVfaGFzaOpdQ1a2v4b3AwoAbmV0d29ya19pZIqZCYEKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:gray_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQoAwAACAQAbmFtZRMAbWluZWNyYWZ0OmdyYXlfd29vbAQJAG5hbWVfaGFzaLsc1Lp1xdIOAwoAbmV0d29ya19pZFUs+HgKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQoAwAACAQAbmFtZRMAbWluZWNyYWZ0OmdyYXlfd29vbAQJAG5hbWVfaGFzaLsc1Lp1xdIOAwoAbmV0d29ya19pZFUs+HgKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:black_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQpAwAACAQAbmFtZRQAbWluZWNyYWZ0OmJsYWNrX3dvb2wECQBuYW1lX2hhc2hP2HC6o0X4HAMKAG5ldHdvcmtfaWRUbORcCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQpAwAACAQAbmFtZRQAbWluZWNyYWZ0OmJsYWNrX3dvb2wECQBuYW1lX2hhc2hP2HC6o0X4HAMKAG5ldHdvcmtfaWRUbORcCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:brown_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQqAwAACAQAbmFtZRQAbWluZWNyYWZ0OmJyb3duX3dvb2wECQBuYW1lX2hhc2ig5IW89PrREwMKAG5ldHdvcmtfaWRjT9j8CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQqAwAACAQAbmFtZRQAbWluZWNyYWZ0OmJyb3duX3dvb2wECQBuYW1lX2hhc2ig5IW89PrREwMKAG5ldHdvcmtfaWRjT9j8CgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:red_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQrAwAACAQAbmFtZRIAbWluZWNyYWZ0OnJlZF93b29sBAkAbmFtZV9oYXNoY4TBDq+mFgUDCgBuZXR3b3JrX2lktn9lcAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQrAwAACAQAbmFtZRIAbWluZWNyYWZ0OnJlZF93b29sBAkAbmFtZV9oYXNoY4TBDq+mFgUDCgBuZXR3b3JrX2lktn9lcAoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:orange_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAwAACAQAbmFtZRUAbWluZWNyYWZ0Om9yYW5nZV93b29sBAkAbmFtZV9oYXNoFstfrTZfSCgDCgBuZXR3b3JrX2lk+rqywwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAwAACAQAbmFtZRUAbWluZWNyYWZ0Om9yYW5nZV93b29sBAkAbmFtZV9oYXNoFstfrTZfSCgDCgBuZXR3b3JrX2lk+rqywwoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:yellow_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQtAwAACAQAbmFtZRUAbWluZWNyYWZ0OnllbGxvd193b29sBAkAbmFtZV9oYXNoTFyus2RHegcDCgBuZXR3b3JrX2lkkKBhXAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQtAwAACAQAbmFtZRUAbWluZWNyYWZ0OnllbGxvd193b29sBAkAbmFtZV9oYXNoTFyus2RHegcDCgBuZXR3b3JrX2lkkKBhXAoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:lime_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQuAwAACAQAbmFtZRMAbWluZWNyYWZ0OmxpbWVfd29vbAQJAG5hbWVfaGFzaNVnnzKiMxmeAwoAbmV0d29ya19pZG9b32kKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQuAwAACAQAbmFtZRMAbWluZWNyYWZ0OmxpbWVfd29vbAQJAG5hbWVfaGFzaNVnnzKiMxmeAwoAbmV0d29ya19pZG9b32kKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:green_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQvAwAACAQAbmFtZRQAbWluZWNyYWZ0OmdyZWVuX3dvb2wECQBuYW1lX2hhc2i3mElRYHIcSQMKAG5ldHdvcmtfaWSssprwCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQvAwAACAQAbmFtZRQAbWluZWNyYWZ0OmdyZWVuX3dvb2wECQBuYW1lX2hhc2i3mElRYHIcSQMKAG5ldHdvcmtfaWSssprwCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:cyan_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQwAwAACAQAbmFtZRMAbWluZWNyYWZ0OmN5YW5fd29vbAQJAG5hbWVfaGFzaBNDfvHn8dqFAwoAbmV0d29ya19pZK0hAbgKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQwAwAACAQAbmFtZRMAbWluZWNyYWZ0OmN5YW5fd29vbAQJAG5hbWVfaGFzaBNDfvHn8dqFAwoAbmV0d29ya19pZK0hAbgKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:light_blue_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQxAwAACAQAbmFtZRkAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfd29vbAQJAG5hbWVfaGFzaLWFAUfyxFPNAwoAbmV0d29ya19pZL2oEugKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQxAwAACAQAbmFtZRkAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfd29vbAQJAG5hbWVfaGFzaLWFAUfyxFPNAwoAbmV0d29ya19pZL2oEugKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:blue_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQyAwAACAQAbmFtZRMAbWluZWNyYWZ0OmJsdWVfd29vbAQJAG5hbWVfaGFzaLjHyxxbTWCLAwoAbmV0d29ya19pZPaLdFQKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQyAwAACAQAbmFtZRMAbWluZWNyYWZ0OmJsdWVfd29vbAQJAG5hbWVfaGFzaLjHyxxbTWCLAwoAbmV0d29ya19pZPaLdFQKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:purple_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQzAwAACAQAbmFtZRUAbWluZWNyYWZ0OnB1cnBsZV93b29sBAkAbmFtZV9oYXNojvFtqzjAf/4DCgBuZXR3b3JrX2lklqASNQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQzAwAACAQAbmFtZRUAbWluZWNyYWZ0OnB1cnBsZV93b29sBAkAbmFtZV9oYXNojvFtqzjAf/4DCgBuZXR3b3JrX2lklqASNQoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:magenta_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ0AwAACAQAbmFtZRYAbWluZWNyYWZ0Om1hZ2VudGFfd29vbAQJAG5hbWVfaGFzaGuOHvf+Pd4yAwoAbmV0d29ya19pZI4UoDQKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ0AwAACAQAbmFtZRYAbWluZWNyYWZ0Om1hZ2VudGFfd29vbAQJAG5hbWVfaGFzaGuOHvf+Pd4yAwoAbmV0d29ya19pZI4UoDQKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:pink_wool", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ1AwAACAQAbmFtZRMAbWluZWNyYWZ0OnBpbmtfd29vbAQJAG5hbWVfaGFzaPiVA2pFeoFLAwoAbmV0d29ya19pZOZRO6oKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ1AwAACAQAbmFtZRMAbWluZWNyYWZ0OnBpbmtfd29vbAQJAG5hbWVfaGFzaPiVA2pFeoFLAwoAbmV0d29ya19pZOZRO6oKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:white_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSrAAAACAQAbmFtZRYAbWluZWNyYWZ0OndoaXRlX2NhcnBldAQJAG5hbWVfaGFzaNeMHTI1fWPXAwoAbmV0d29ya19pZEahDFcKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSrAAAACAQAbmFtZRYAbWluZWNyYWZ0OndoaXRlX2NhcnBldAQJAG5hbWVfaGFzaNeMHTI1fWPXAwoAbmV0d29ya19pZEahDFcKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:light_gray_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRbAwAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY2FycGV0BAkAbmFtZV9oYXNoHPw6ArBAsP0DCgBuZXR3b3JrX2lkQoAeUAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRbAwAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY2FycGV0BAkAbmFtZV9oYXNoHPw6ArBAsP0DCgBuZXR3b3JrX2lkQoAeUAoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:gray_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRaAwAACAQAbmFtZRUAbWluZWNyYWZ0OmdyYXlfY2FycGV0BAkAbmFtZV9oYXNoZVR0OI+1VRADCgBuZXR3b3JrX2lkETF4WwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRaAwAACAQAbmFtZRUAbWluZWNyYWZ0OmdyYXlfY2FycGV0BAkAbmFtZV9oYXNoZVR0OI+1VRADCgBuZXR3b3JrX2lkETF4WwoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:black_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJsYWNrX2NhcnBldAQJAG5hbWVfaGFzaOk7LP9NptyhAwoAbmV0d29ya19pZFjmXtIKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRiAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJsYWNrX2NhcnBldAQJAG5hbWVfaGFzaOk7LP9NptyhAwoAbmV0d29ya19pZFjmXtIKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:brown_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRfAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJyb3duX2NhcnBldAQJAG5hbWVfaGFzaNaXFyOsAvIvAwoAbmV0d29ya19pZHPjFuoKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRfAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJyb3duX2NhcnBldAQJAG5hbWVfaGFzaNaXFyOsAvIvAwoAbmV0d29ya19pZHPjFuoKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:red_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAwAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9jYXJwZXQECQBuYW1lX2hhc2i9eSKBf6SO3wMKAG5ldHdvcmtfaWQuhI/KCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAwAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9jYXJwZXQECQBuYW1lX2hhc2i9eSKBf6SO3wMKAG5ldHdvcmtfaWQuhI/KCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:orange_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRUAwAACAQAbmFtZRcAbWluZWNyYWZ0Om9yYW5nZV9jYXJwZXQECQBuYW1lX2hhc2hIUkO4HlAdygMKAG5ldHdvcmtfaWSyKV9OCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRUAwAACAQAbmFtZRcAbWluZWNyYWZ0Om9yYW5nZV9jYXJwZXQECQBuYW1lX2hhc2hIUkO4HlAdygMKAG5ldHdvcmtfaWSyKV9OCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:yellow_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRXAwAACAQAbmFtZRcAbWluZWNyYWZ0OnllbGxvd19jYXJwZXQECQBuYW1lX2hhc2hSDKX3scCamwMKAG5ldHdvcmtfaWT8nq+ECgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRXAwAACAQAbmFtZRcAbWluZWNyYWZ0OnllbGxvd19jYXJwZXQECQBuYW1lX2hhc2hSDKX3scCamwMKAG5ldHdvcmtfaWT8nq+ECgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:lime_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRYAwAACAQAbmFtZRUAbWluZWNyYWZ0OmxpbWVfY2FycGV0BAkAbmFtZV9oYXNo+6KFOpzsib4DCgBuZXR3b3JrX2lkT+DS4woGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRYAwAACAQAbmFtZRUAbWluZWNyYWZ0OmxpbWVfY2FycGV0BAkAbmFtZV9oYXNo+6KFOpzsib4DCgBuZXR3b3JrX2lkT+DS4woGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:green_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRgAwAACAQAbmFtZRYAbWluZWNyYWZ0OmdyZWVuX2NhcnBldAQJAG5hbWVfaGFzaCHPMP9ltqFJAwoAbmV0d29ya19pZBgwAvAKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRgAwAACAQAbmFtZRYAbWluZWNyYWZ0OmdyZWVuX2NhcnBldAQJAG5hbWVfaGFzaCHPMP9ltqFJAwoAbmV0d29ya19pZBgwAvAKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:cyan_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRcAwAACAQAbmFtZRUAbWluZWNyYWZ0OmN5YW5fY2FycGV0BAkAbmFtZV9oYXNobXf62dQBJj8DCgBuZXR3b3JrX2lkKVppLgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRcAwAACAQAbmFtZRUAbWluZWNyYWZ0OmN5YW5fY2FycGV0BAkAbmFtZV9oYXNobXf62dQBJj8DCgBuZXR3b3JrX2lkKVppLgoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:light_blue_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRWAwAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY2FycGV0BAkAbmFtZV9oYXNo20l4oktdZ3sDCgBuZXR3b3JrX2lkjdeMiwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRWAwAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY2FycGV0BAkAbmFtZV9oYXNo20l4oktdZ3sDCgBuZXR3b3JrX2lkjdeMiwoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:blue_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWReAwAACAQAbmFtZRUAbWluZWNyYWZ0OmJsdWVfY2FycGV0BAkAbmFtZV9oYXNo3p3lsW0eQwsDCgBuZXR3b3JrX2lkAovdPQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWReAwAACAQAbmFtZRUAbWluZWNyYWZ0OmJsdWVfY2FycGV0BAkAbmFtZV9oYXNo3p3lsW0eQwsDCgBuZXR3b3JrX2lkAovdPQoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:purple_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRdAwAACAQAbmFtZRcAbWluZWNyYWZ0OnB1cnBsZV9jYXJwZXQECQBuYW1lX2hhc2jwIA9pW/qp7QMKAG5ldHdvcmtfaWTqJqhjCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRdAwAACAQAbmFtZRcAbWluZWNyYWZ0OnB1cnBsZV9jYXJwZXQECQBuYW1lX2hhc2jwIA9pW/qp7QMKAG5ldHdvcmtfaWTqJqhjCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:magenta_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRVAwAACAQAbmFtZRgAbWluZWNyYWZ0Om1hZ2VudGFfY2FycGV0BAkAbmFtZV9oYXNoFXT36YNNZhMDCgBuZXR3b3JrX2lk+tqsGAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRVAwAACAQAbmFtZRgAbWluZWNyYWZ0Om1hZ2VudGFfY2FycGV0BAkAbmFtZV9oYXNoFXT36YNNZhMDCgBuZXR3b3JrX2lk+tqsGAoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:pink_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRZAwAACAQAbmFtZRUAbWluZWNyYWZ0OnBpbmtfY2FycGV0BAkAbmFtZV9oYXNoHll72oqk+OoDCgBuZXR3b3JrX2lkrnBYDwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRZAwAACAQAbmFtZRUAbWluZWNyYWZ0OnBpbmtfY2FycGV0BAkAbmFtZV9oYXNoHll72oqk+OoDCgBuZXR3b3JrX2lkrnBYDwoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:white_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTtAAAACAQAbmFtZR8AbWluZWNyYWZ0OndoaXRlX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaFUk9iXVjwV8AwoAbmV0d29ya19pZJPZY8AKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTtAAAACAQAbmFtZR8AbWluZWNyYWZ0OndoaXRlX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaFUk9iXVjwV8AwoAbmV0d29ya19pZJPZY8AKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:light_gray_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTLAwAACAQAbmFtZSQAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNo7EUk30hmUtYDCgBuZXR3b3JrX2lkh8jVIwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTLAwAACAQAbmFtZSQAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNo7EUk30hmUtYDCgBuZXR3b3JrX2lkh8jVIwoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:gray_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTKAwAACAQAbmFtZR4AbWluZWNyYWZ0OmdyYXlfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoW77af6WihdwDCgBuZXR3b3JrX2lkSsqC1woGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTKAwAACAQAbmFtZR4AbWluZWNyYWZ0OmdyYXlfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoW77af6WihdwDCgBuZXR3b3JrX2lkSsqC1woGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:black_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTSAwAACAQAbmFtZR8AbWluZWNyYWZ0OmJsYWNrX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaAfWYp0xtgcfAwoAbmV0d29ya19pZMWTC8EKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTSAwAACAQAbmFtZR8AbWluZWNyYWZ0OmJsYWNrX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaAfWYp0xtgcfAwoAbmV0d29ya19pZMWTC8EKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:brown_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTPAwAACAQAbmFtZR8AbWluZWNyYWZ0OmJyb3duX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaB74EeiLO46XAwoAbmV0d29ya19pZEDHKqwKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTPAwAACAQAbmFtZR8AbWluZWNyYWZ0OmJyb3duX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaB74EeiLO46XAwoAbmV0d29ya19pZEDHKqwKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:red_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTRAwAACAQAbmFtZR0AbWluZWNyYWZ0OnJlZF9jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2gjFut6Z/VH1gMKAG5ldHdvcmtfaWSvcmwYCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTRAwAACAQAbmFtZR0AbWluZWNyYWZ0OnJlZF9jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2gjFut6Z/VH1gMKAG5ldHdvcmtfaWSvcmwYCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:orange_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTEAwAACAQAbmFtZSAAbWluZWNyYWZ0Om9yYW5nZV9jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2gADDj2IJiw+gMKAG5ldHdvcmtfaWTHph0FCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTEAwAACAQAbmFtZSAAbWluZWNyYWZ0Om9yYW5nZV9jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2gADDj2IJiw+gMKAG5ldHdvcmtfaWTHph0FCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:yellow_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTHAwAACAQAbmFtZSAAbWluZWNyYWZ0OnllbGxvd19jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2iy6qKNn3ob5wMKAG5ldHdvcmtfaWQZAI39CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTHAwAACAQAbmFtZSAAbWluZWNyYWZ0OnllbGxvd19jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2iy6qKNn3ob5wMKAG5ldHdvcmtfaWQZAI39CgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:lime_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTIAwAACAQAbmFtZR4AbWluZWNyYWZ0OmxpbWVfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNo4dYIPslbXPUDCgBuZXR3b3JrX2lk2O8X0AoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTIAwAACAQAbmFtZR4AbWluZWNyYWZ0OmxpbWVfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNo4dYIPslbXPUDCgBuZXR3b3JrX2lk2O8X0AoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:green_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTQAwAACAQAbmFtZR8AbWluZWNyYWZ0OmdyZWVuX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaM/c9x2aJh3HAwoAbmV0d29ya19pZA0VfBMKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTQAwAACAQAbmFtZR8AbWluZWNyYWZ0OmdyZWVuX2NvbmNyZXRlX3Bvd2RlcgQJAG5hbWVfaGFzaM/c9x2aJh3HAwoAbmV0d29ya19pZA0VfBMKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:cyan_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTMAwAACAQAbmFtZR4AbWluZWNyYWZ0OmN5YW5fY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNok+xKAe7XXjoDCgBuZXR3b3JrX2lkmkn6uwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTMAwAACAQAbmFtZR4AbWluZWNyYWZ0OmN5YW5fY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNok+xKAe7XXjoDCgBuZXR3b3JrX2lkmkn6uwoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:light_blue_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTGAwAACAQAbmFtZSQAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNogScpIQceyAEDCgBuZXR3b3JrX2lkOmVSbgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTGAwAACAQAbmFtZSQAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNogScpIQceyAEDCgBuZXR3b3JrX2lkOmVSbgoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:blue_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTOAwAACAQAbmFtZR4AbWluZWNyYWZ0OmJsdWVfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoFp7mmeL86r0DCgBuZXR3b3JrX2lkS3b3RQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTOAwAACAQAbmFtZR4AbWluZWNyYWZ0OmJsdWVfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoFp7mmeL86r0DCgBuZXR3b3JrX2lkS3b3RQoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:purple_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTNAwAACAQAbmFtZSAAbWluZWNyYWZ0OnB1cnBsZV9jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2iYcVU04hoStwMKAG5ldHdvcmtfaWQXimEjCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTNAwAACAQAbmFtZSAAbWluZWNyYWZ0OnB1cnBsZV9jb25jcmV0ZV9wb3dkZXIECQBuYW1lX2hhc2iYcVU04hoStwMKAG5ldHdvcmtfaWQXimEjCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:magenta_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTFAwAACAQAbmFtZSEAbWluZWNyYWZ0Om1hZ2VudGFfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoy/70q6VPsWgDCgBuZXR3b3JrX2lkf9mxQwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTFAwAACAQAbmFtZSEAbWluZWNyYWZ0Om1hZ2VudGFfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoy/70q6VPsWgDCgBuZXR3b3JrX2lkf9mxQwoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:pink_concrete_powder", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAwAACAQAbmFtZR4AbWluZWNyYWZ0OnBpbmtfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoVikSAf8DwV0DCgBuZXR3b3JrX2lku2MivwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAwAACAQAbmFtZR4AbWluZWNyYWZ0OnBpbmtfY29uY3JldGVfcG93ZGVyBAkAbmFtZV9oYXNoVikSAf8DwV0DCgBuZXR3b3JrX2lku2MivwoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:white_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTsAAAACAQAbmFtZRgAbWluZWNyYWZ0OndoaXRlX2NvbmNyZXRlBAkAbmFtZV9oYXNo6zAp7lsLlvkDCgBuZXR3b3JrX2lk3MAYQAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTsAAAACAQAbmFtZRgAbWluZWNyYWZ0OndoaXRlX2NvbmNyZXRlBAkAbmFtZV9oYXNo6zAp7lsLlvkDCgBuZXR3b3JrX2lk3MAYQAoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:light_gray_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR6AwAACAQAbmFtZR0AbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY29uY3JldGUECQBuYW1lX2hhc2hEtet5wuDIKAMKAG5ldHdvcmtfaWQISs02CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWR6AwAACAQAbmFtZR0AbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY29uY3JldGUECQBuYW1lX2hhc2hEtet5wuDIKAMKAG5ldHdvcmtfaWQISs02CgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:gray_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR5AwAACAQAbmFtZRcAbWluZWNyYWZ0OmdyYXlfY29uY3JldGUECQBuYW1lX2hhc2j92INnb0a83AMKAG5ldHdvcmtfaWQj8RHwCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWR5AwAACAQAbmFtZRcAbWluZWNyYWZ0OmdyYXlfY29uY3JldGUECQBuYW1lX2hhc2j92INnb0a83AMKAG5ldHdvcmtfaWQj8RHwCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:black_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSBAwAACAQAbmFtZRgAbWluZWNyYWZ0OmJsYWNrX2NvbmNyZXRlBAkAbmFtZV9oYXNo2X7NDIQmZ70DCgBuZXR3b3JrX2lk2uiVDQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSBAwAACAQAbmFtZRgAbWluZWNyYWZ0OmJsYWNrX2NvbmNyZXRlBAkAbmFtZV9oYXNo2X7NDIQmZ70DCgBuZXR3b3JrX2lk2uiVDQoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:brown_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR+AwAACAQAbmFtZRgAbWluZWNyYWZ0OmJyb3duX2NvbmNyZXRlBAkAbmFtZV9oYXNoeka02BwXf6oDCgBuZXR3b3JrX2lkYf+xDQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWR+AwAACAQAbmFtZRgAbWluZWNyYWZ0OmJyb3duX2NvbmNyZXRlBAkAbmFtZV9oYXNoeka02BwXf6oDCgBuZXR3b3JrX2lkYf+xDQoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:red_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSAAwAACAQAbmFtZRYAbWluZWNyYWZ0OnJlZF9jb25jcmV0ZQQJAG5hbWVfaGFzaPWmNowLGubqAwoAbmV0d29ya19pZKwyx58KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSAAwAACAQAbmFtZRYAbWluZWNyYWZ0OnJlZF9jb25jcmV0ZQQJAG5hbWVfaGFzaPWmNowLGubqAwoAbmV0d29ya19pZKwyx58KBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:orange_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRzAwAACAQAbmFtZRkAbWluZWNyYWZ0Om9yYW5nZV9jb25jcmV0ZQQJAG5hbWVfaGFzaAgE8XmaAi6+AwoAbmV0d29ya19pZMDQNz8KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRzAwAACAQAbmFtZRkAbWluZWNyYWZ0Om9yYW5nZV9jb25jcmV0ZQQJAG5hbWVfaGFzaAgE8XmaAi6+AwoAbmV0d29ya19pZMDQNz8KBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:yellow_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR2AwAACAQAbmFtZRkAbWluZWNyYWZ0OnllbGxvd19jb25jcmV0ZQQJAG5hbWVfaGFzaE6ONfJPBd0+AwoAbmV0d29ya19pZMarutwKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWR2AwAACAQAbmFtZRkAbWluZWNyYWZ0OnllbGxvd19jb25jcmV0ZQQJAG5hbWVfaGFzaE6ONfJPBd0+AwoAbmV0d29ya19pZMarutwKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:lime_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR3AwAACAQAbmFtZRcAbWluZWNyYWZ0OmxpbWVfY29uY3JldGUECQBuYW1lX2hhc2gnd8JW6wmJcAMKAG5ldHdvcmtfaWTd47aoCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWR3AwAACAQAbmFtZRcAbWluZWNyYWZ0OmxpbWVfY29uY3JldGUECQBuYW1lX2hhc2gnd8JW6wmJcAMKAG5ldHdvcmtfaWTd47aoCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:green_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR/AwAACAQAbmFtZRgAbWluZWNyYWZ0OmdyZWVuX2NvbmNyZXRlBAkAbmFtZV9oYXNokbFxRKchQZkDCgBuZXR3b3JrX2lkmhZWUgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWR/AwAACAQAbmFtZRgAbWluZWNyYWZ0OmdyZWVuX2NvbmNyZXRlBAkAbmFtZV9oYXNokbFxRKchQZkDCgBuZXR3b3JrX2lkmhZWUgoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:cyan_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR7AwAACAQAbmFtZRcAbWluZWNyYWZ0OmN5YW5fY29uY3JldGUECQBuYW1lX2hhc2hFRrWJ33qj1wMKAG5ldHdvcmtfaWQbi5b8CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWR7AwAACAQAbmFtZRcAbWluZWNyYWZ0OmN5YW5fY29uY3JldGUECQBuYW1lX2hhc2hFRrWJ33qj1wMKAG5ldHdvcmtfaWQbi5b8CgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:light_blue_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR1AwAACAQAbmFtZR0AbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY29uY3JldGUECQBuYW1lX2hhc2gHAe0kl0SE4AMKAG5ldHdvcmtfaWRL/GbSCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWR1AwAACAQAbmFtZR0AbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY29uY3JldGUECQBuYW1lX2hhc2gHAe0kl0SE4AMKAG5ldHdvcmtfaWRL/GbSCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:blue_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR9AwAACAQAbmFtZRcAbWluZWNyYWZ0OmJsdWVfY29uY3JldGUECQBuYW1lX2hhc2hiay301nnj1wMKAG5ldHdvcmtfaWRMvFXNCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWR9AwAACAQAbmFtZRcAbWluZWNyYWZ0OmJsdWVfY29uY3JldGUECQBuYW1lX2hhc2hiay301nnj1wMKAG5ldHdvcmtfaWRMvFXNCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:purple_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR8AwAACAQAbmFtZRkAbWluZWNyYWZ0OnB1cnBsZV9jb25jcmV0ZQQJAG5hbWVfaGFzaHBHflsPIwdXAwoAbmV0d29ya19pZCyKA5gKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWR8AwAACAQAbmFtZRkAbWluZWNyYWZ0OnB1cnBsZV9jb25jcmV0ZQQJAG5hbWVfaGFzaHBHflsPIwdXAwoAbmV0d29ya19pZCyKA5gKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:magenta_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR0AwAACAQAbmFtZRoAbWluZWNyYWZ0Om1hZ2VudGFfY29uY3JldGUECQBuYW1lX2hhc2gN7LuB/OvdZAMKAG5ldHdvcmtfaWTc6ZOdCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWR0AwAACAQAbmFtZRoAbWluZWNyYWZ0Om1hZ2VudGFfY29uY3JldGUECQBuYW1lX2hhc2gN7LuB/OvdZAMKAG5ldHdvcmtfaWTc6ZOdCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:pink_concrete", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR4AwAACAQAbmFtZRcAbWluZWNyYWZ0OnBpbmtfY29uY3JldGUECQBuYW1lX2hhc2ii2G5F0u3SOAMKAG5ldHdvcmtfaWSszGgrCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWR4AwAACAQAbmFtZRcAbWluZWNyYWZ0OnBpbmtfY29uY3JldGUECQBuYW1lX2hhc2ii2G5F0u3SOAMKAG5ldHdvcmtfaWSszGgrCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:clay", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRSAAAACAQAbmFtZQ4AbWluZWNyYWZ0OmNsYXkECQBuYW1lX2hhc2j/S6sKXRcpzwMKAG5ldHdvcmtfaWRmsb8nCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRSAAAACAQAbmFtZQ4AbWluZWNyYWZ0OmNsYXkECQBuYW1lX2hhc2j/S6sKXRcpzwMKAG5ldHdvcmtfaWRmsb8nCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:hardened_clay", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSsAAAACAQAbmFtZRcAbWluZWNyYWZ0OmhhcmRlbmVkX2NsYXkECQBuYW1lX2hhc2jrnRwCJ0krJAMKAG5ldHdvcmtfaWRBCOrrCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSsAAAACAQAbmFtZRcAbWluZWNyYWZ0OmhhcmRlbmVkX2NsYXkECQBuYW1lX2hhc2jrnRwCJ0krJAMKAG5ldHdvcmtfaWRBCOrrCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:white_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSfAAAACAQAbmFtZRoAbWluZWNyYWZ0OndoaXRlX3RlcnJhY290dGEECQBuYW1lX2hhc2j3RSdgmnAIewMKAG5ldHdvcmtfaWSimKw+CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSfAAAACAQAbmFtZRoAbWluZWNyYWZ0OndoaXRlX3RlcnJhY290dGEECQBuYW1lX2hhc2j3RSdgmnAIewMKAG5ldHdvcmtfaWSimKw+CgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:light_gray_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTaAwAACAQAbmFtZR8AbWluZWNyYWZ0OmxpZ2h0X2dyYXlfdGVycmFjb3R0YQQJAG5hbWVfaGFzaAz1Ri3wIxomAwoAbmV0d29ya19pZH5qgOcKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTaAwAACAQAbmFtZR8AbWluZWNyYWZ0OmxpZ2h0X2dyYXlfdGVycmFjb3R0YQQJAG5hbWVfaGFzaAz1Ri3wIxomAwoAbmV0d29ya19pZH5qgOcKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:gray_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTZAwAACAQAbmFtZRkAbWluZWNyYWZ0OmdyYXlfdGVycmFjb3R0YQQJAG5hbWVfaGFzaAXdSLAaNZ9vAwoAbmV0d29ya19pZM1QDV0KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTZAwAACAQAbmFtZRkAbWluZWNyYWZ0OmdyYXlfdGVycmFjb3R0YQQJAG5hbWVfaGFzaAXdSLAaNZ9vAwoAbmV0d29ya19pZM1QDV0KBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:black_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWThAwAACAQAbmFtZRoAbWluZWNyYWZ0OmJsYWNrX3RlcnJhY290dGEECQBuYW1lX2hhc2jxssdv5vlbpgMKAG5ldHdvcmtfaWRE3Ru/CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWThAwAACAQAbmFtZRoAbWluZWNyYWZ0OmJsYWNrX3RlcnJhY290dGEECQBuYW1lX2hhc2jxssdv5vlbpgMKAG5ldHdvcmtfaWRE3Ru/CgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:brown_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTeAwAACAQAbmFtZRoAbWluZWNyYWZ0OmJyb3duX3RlcnJhY290dGEECQBuYW1lX2hhc2gG4kPenmOF9gMKAG5ldHdvcmtfaWQ/i0iNCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTeAwAACAQAbmFtZRoAbWluZWNyYWZ0OmJyb3duX3RlcnJhY290dGEECQBuYW1lX2hhc2gG4kPenmOF9gMKAG5ldHdvcmtfaWQ/i0iNCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:red_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTgAwAACAQAbmFtZRgAbWluZWNyYWZ0OnJlZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNo7fX56HXFejEDCgBuZXR3b3JrX2lk8tTF8QoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTgAwAACAQAbmFtZRgAbWluZWNyYWZ0OnJlZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNo7fX56HXFejEDCgBuZXR3b3JrX2lk8tTF8QoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:orange_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAwAACAQAbmFtZRsAbWluZWNyYWZ0Om9yYW5nZV90ZXJyYWNvdHRhBAkAbmFtZV9oYXNo0Hjmql3sruMDCgBuZXR3b3JrX2lklmqmkAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAwAACAQAbmFtZRsAbWluZWNyYWZ0Om9yYW5nZV90ZXJyYWNvdHRhBAkAbmFtZV9oYXNo0Hjmql3sruMDCgBuZXR3b3JrX2lklmqmkAoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:yellow_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTWAwAACAQAbmFtZRsAbWluZWNyYWZ0OnllbGxvd190ZXJyYWNvdHRhBAkAbmFtZV9oYXNoqkyKKrmA3VcDCgBuZXR3b3JrX2lkaM/orAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTWAwAACAQAbmFtZRsAbWluZWNyYWZ0OnllbGxvd190ZXJyYWNvdHRhBAkAbmFtZV9oYXNoqkyKKrmA3VcDCgBuZXR3b3JrX2lkaM/orAoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:lime_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTXAwAACAQAbmFtZRkAbWluZWNyYWZ0OmxpbWVfdGVycmFjb3R0YQQJAG5hbWVfaGFzaANjADFOF9v7AwoAbmV0d29ya19pZJt0XsgKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTXAwAACAQAbmFtZRkAbWluZWNyYWZ0OmxpbWVfdGVycmFjb3R0YQQJAG5hbWVfaGFzaANjADFOF9v7AwoAbmV0d29ya19pZJt0XsgKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:green_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTfAwAACAQAbmFtZRoAbWluZWNyYWZ0OmdyZWVuX3RlcnJhY290dGEECQBuYW1lX2hhc2j5Ybq36yYwRQMKAG5ldHdvcmtfaWQ8kGdHCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTfAwAACAQAbmFtZRoAbWluZWNyYWZ0OmdyZWVuX3RlcnJhY290dGEECQBuYW1lX2hhc2j5Ybq36yYwRQMKAG5ldHdvcmtfaWQ8kGdHCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:cyan_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTbAwAACAQAbmFtZRkAbWluZWNyYWZ0OmN5YW5fdGVycmFjb3R0YQQJAG5hbWVfaGFzaN09COzMuHwAAwoAbmV0d29ya19pZIWPCzoKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTbAwAACAQAbmFtZRkAbWluZWNyYWZ0OmN5YW5fdGVycmFjb3R0YQQJAG5hbWVfaGFzaN09COzMuHwAAwoAbmV0d29ya19pZIWPCzoKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:light_blue_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTVAwAACAQAbmFtZR8AbWluZWNyYWZ0OmxpZ2h0X2JsdWVfdGVycmFjb3R0YQQJAG5hbWVfaGFzaOMytez7cOZiAwoAbmV0d29ya19pZFHK1UsKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTVAwAACAQAbmFtZR8AbWluZWNyYWZ0OmxpZ2h0X2JsdWVfdGVycmFjb3R0YQQJAG5hbWVfaGFzaOMytez7cOZiAwoAbmV0d29ya19pZFHK1UsKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:blue_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTdAwAACAQAbmFtZRkAbWluZWNyYWZ0OmJsdWVfdGVycmFjb3R0YQQJAG5hbWVfaGFzaF6inyTK5RpAAwoAbmV0d29ya19pZF5mVZIKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTdAwAACAQAbmFtZRkAbWluZWNyYWZ0OmJsdWVfdGVycmFjb3R0YQQJAG5hbWVfaGFzaF6inyTK5RpAAwoAbmV0d29ya19pZF5mVZIKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:purple_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTcAwAACAQAbmFtZRsAbWluZWNyYWZ0OnB1cnBsZV90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoKF7YG61yTbEDCgBuZXR3b3JrX2lkhtRDlwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTcAwAACAQAbmFtZRsAbWluZWNyYWZ0OnB1cnBsZV90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoKF7YG61yTbEDCgBuZXR3b3JrX2lkhtRDlwoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:magenta_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTUAwAACAQAbmFtZRwAbWluZWNyYWZ0Om1hZ2VudGFfdGVycmFjb3R0YQQJAG5hbWVfaGFzaLWvtpAVtztyAwoAbmV0d29ya19pZN5SoakKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTUAwAACAQAbmFtZRwAbWluZWNyYWZ0Om1hZ2VudGFfdGVycmFjb3R0YQQJAG5hbWVfaGFzaLWvtpAVtztyAwoAbmV0d29ya19pZN5SoakKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:pink_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTYAwAACAQAbmFtZRkAbWluZWNyYWZ0OnBpbmtfdGVycmFjb3R0YQQJAG5hbWVfaGFzaJ7mzvyzSQZTAwoAbmV0d29ya19pZDJWe4YKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTYAwAACAQAbmFtZRkAbWluZWNyYWZ0OnBpbmtfdGVycmFjb3R0YQQJAG5hbWVfaGFzaJ7mzvyzSQZTAwoAbmV0d29ya19pZDJWe4YKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:white_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTcAAAACAQAbmFtZSEAbWluZWNyYWZ0OndoaXRlX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoiVzCdoHAJo0DCgBuZXR3b3JrX2lkIlj9AAoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTcAAAACAQAbmFtZSEAbWluZWNyYWZ0OndoaXRlX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoiVzCdoHAJo0DCgBuZXR3b3JrX2lkIlj9AAoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:silver_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTkAAAACAQAbmFtZSIAbWluZWNyYWZ0OnNpbHZlcl9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaAVsA0CnhzA4AwoAbmV0d29ya19pZPnxtJEKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTkAAAACAQAbmFtZSIAbWluZWNyYWZ0OnNpbHZlcl9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaAVsA0CnhzA4AwoAbmV0d29ya19pZPnxtJEKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:gray_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTjAAAACAQAbmFtZSAAbWluZWNyYWZ0OmdyYXlfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2jvLZt9u/lF/AMKAG5ldHdvcmtfaWQVU8eFCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTjAAAACAQAbmFtZSAAbWluZWNyYWZ0OmdyYXlfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2jvLZt9u/lF/AMKAG5ldHdvcmtfaWQVU8eFCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:black_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTrAAAACAQAbmFtZSEAbWluZWNyYWZ0OmJsYWNrX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoe8I4xAXbO5UDCgBuZXR3b3JrX2lk2Icb9AoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTrAAAACAQAbmFtZSEAbWluZWNyYWZ0OmJsYWNrX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoe8I4xAXbO5UDCgBuZXR3b3JrX2lk2Icb9AoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:brown_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWToAAAACAQAbmFtZSEAbWluZWNyYWZ0OmJyb3duX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoSiNZOobbpjoDCgBuZXR3b3JrX2lkJy0jwgoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWToAAAACAQAbmFtZSEAbWluZWNyYWZ0OmJyb3duX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNoSiNZOobbpjoDCgBuZXR3b3JrX2lkJy0jwgoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:red_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTqAAAACAQAbmFtZR8AbWluZWNyYWZ0OnJlZF9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaBdWFGLmCLFVAwoAbmV0d29ya19pZMYBJSEKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTqAAAACAQAbmFtZR8AbWluZWNyYWZ0OnJlZF9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaBdWFGLmCLFVAwoAbmV0d29ya19pZMYBJSEKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:orange_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTdAAAACAQAbmFtZSIAbWluZWNyYWZ0Om9yYW5nZV9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaMyJMrnPr7szAwoAbmV0d29ya19pZN6+7TUKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTdAAAACAQAbmFtZSIAbWluZWNyYWZ0Om9yYW5nZV9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaMyJMrnPr7szAwoAbmV0d29ya19pZN6+7TUKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:yellow_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTgAAAACAQAbmFtZSIAbWluZWNyYWZ0OnllbGxvd19nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaN6NaIhf6m0uAwoAbmV0d29ya19pZKRHXeoKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTgAAAACAQAbmFtZSIAbWluZWNyYWZ0OnllbGxvd19nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaN6NaIhf6m0uAwoAbmV0d29ya19pZKRHXeoKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:lime_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWThAAAACAQAbmFtZSAAbWluZWNyYWZ0OmxpbWVfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2iF3E68/rB2EAMKAG5ldHdvcmtfaWSP7qQWCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWThAAAACAQAbmFtZSAAbWluZWNyYWZ0OmxpbWVfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2iF3E68/rB2EAMKAG5ldHdvcmtfaWSP7qQWCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:green_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTpAAAACAQAbmFtZSEAbWluZWNyYWZ0OmdyZWVuX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNow5mo8aQDFboDCgBuZXR3b3JrX2lkoF11kgoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTpAAAACAQAbmFtZSEAbWluZWNyYWZ0OmdyZWVuX2dsYXplZF90ZXJyYWNvdHRhBAkAbmFtZV9oYXNow5mo8aQDFboDCgBuZXR3b3JrX2lkoF11kgoGAHN0YXRlcwMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:cyan_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTlAAAACAQAbmFtZSAAbWluZWNyYWZ0OmN5YW5fZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2gnNB+cCFRJhwMKAG5ldHdvcmtfaWT9buMtCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTlAAAACAQAbmFtZSAAbWluZWNyYWZ0OmN5YW5fZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2gnNB+cCFRJhwMKAG5ldHdvcmtfaWT9buMtCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:light_blue_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTfAAAACAQAbmFtZSYAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2gladnCDBKCigMKAG5ldHdvcmtfaWS5CszFCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTfAAAACAQAbmFtZSYAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2gladnCDBKCigMKAG5ldHdvcmtfaWS5CszFCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:blue_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTnAAAACAQAbmFtZSAAbWluZWNyYWZ0OmJsdWVfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2giOZK+2nB1igMKAG5ldHdvcmtfaWR+e22CCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTnAAAACAQAbmFtZSAAbWluZWNyYWZ0OmJsdWVfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2giOZK+2nB1igMKAG5ldHdvcmtfaWR+e22CCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:purple_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTbAAAACAQAbmFtZSIAbWluZWNyYWZ0OnB1cnBsZV9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaIQU03txeAfHAwoAbmV0d29ya19pZLKbSE4KBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTbAAAACAQAbmFtZSIAbWluZWNyYWZ0OnB1cnBsZV9nbGF6ZWRfdGVycmFjb3R0YQQJAG5hbWVfaGFzaIQU03txeAfHAwoAbmV0d29ya19pZLKbSE4KBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:magenta_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTeAAAACAQAbmFtZSMAbWluZWNyYWZ0Om1hZ2VudGFfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2i/SNqDJbfjMgMKAG5ldHdvcmtfaWQKf9UvCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTeAAAACAQAbmFtZSMAbWluZWNyYWZ0Om1hZ2VudGFfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2i/SNqDJbfjMgMKAG5ldHdvcmtfaWQKf9UvCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:pink_glazed_terracotta", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTiAAAACAQAbmFtZSAAbWluZWNyYWZ0OnBpbmtfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2hik8DVt4g+twMKAG5ldHdvcmtfaWTKzav2CgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTiAAAACAQAbmFtZSAAbWluZWNyYWZ0OnBpbmtfZ2xhemVkX3RlcnJhY290dGEECQBuYW1lX2hhc2hik8DVt4g+twMKAG5ldHdvcmtfaWTKzav2CgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:purpur_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAAAACAQAbmFtZRYAbWluZWNyYWZ0OnB1cnB1cl9ibG9jawQJAG5hbWVfaGFzaAgLwnUZGlzsAwoAbmV0d29ya19pZLD8ox4KBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQcAZGVmYXVsdAgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAAAACAQAbmFtZRYAbWluZWNyYWZ0OnB1cnB1cl9ibG9jawQJAG5hbWVfaGFzaAgLwnUZGlzsAwoAbmV0d29ya19pZLD8ox4KBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQcAZGVmYXVsdAgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:purpur_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAAAACAQAbmFtZRYAbWluZWNyYWZ0OnB1cnB1cl9ibG9jawQJAG5hbWVfaGFzaAgLwnUZGlzsAwoAbmV0d29ya19pZPSAFFsKBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQUAbGluZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAAAACAQAbmFtZRYAbWluZWNyYWZ0OnB1cnB1cl9ibG9jawQJAG5hbWVfaGFzaAgLwnUZGlzsAwoAbmV0d29ya19pZPSAFFsKBgBzdGF0ZXMICwBjaGlzZWxfdHlwZQUAbGluZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:packed_mud", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTcAgAACAQAbmFtZRQAbWluZWNyYWZ0OnBhY2tlZF9tdWQECQBuYW1lX2hhc2gHOMa121h4FgMKAG5ldHdvcmtfaWTUb6LyCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTcAgAACAQAbmFtZRQAbWluZWNyYWZ0OnBhY2tlZF9tdWQECQBuYW1lX2hhc2gHOMa121h4FgMKAG5ldHdvcmtfaWTUb6LyCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:mud_bricks", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTaAgAACAQAbmFtZRQAbWluZWNyYWZ0Om11ZF9icmlja3MECQBuYW1lX2hhc2iDL/SVl/PewQMKAG5ldHdvcmtfaWSkBjaDCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTaAgAACAQAbmFtZRQAbWluZWNyYWZ0Om11ZF9icmlja3MECQBuYW1lX2hhc2iDL/SVl/PewQMKAG5ldHdvcmtfaWSkBjaDCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:nether_wart_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTWAAAACAQAbmFtZRsAbWluZWNyYWZ0Om5ldGhlcl93YXJ0X2Jsb2NrBAkAbmFtZV9oYXNo9XGS4GNnlV4DCgBuZXR3b3JrX2lkh3apIgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTWAAAACAQAbmFtZRsAbWluZWNyYWZ0Om5ldGhlcl93YXJ0X2Jsb2NrBAkAbmFtZV9oYXNo9XGS4GNnlV4DCgBuZXR3b3JrX2lkh3apIgoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:warped_wart_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTiAQAACAQAbmFtZRsAbWluZWNyYWZ0OndhcnBlZF93YXJ0X2Jsb2NrBAkAbmFtZV9oYXNo9IqDS9yUPJoDCgBuZXR3b3JrX2lkMpKAbAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTiAQAACAQAbmFtZRsAbWluZWNyYWZ0OndhcnBlZF93YXJ0X2Jsb2NrBAkAbmFtZV9oYXNo9IqDS9yUPJoDCgBuZXR3b3JrX2lkMpKAbAoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:shroomlight", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTlAQAACAQAbmFtZRUAbWluZWNyYWZ0OnNocm9vbWxpZ2h0BAkAbmFtZV9oYXNoZHCHcHX/HYADCgBuZXR3b3JrX2lkLG2JiwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTlAQAACAQAbmFtZRUAbWluZWNyYWZ0OnNocm9vbWxpZ2h0BAkAbmFtZV9oYXNoZHCHcHX/HYADCgBuZXR3b3JrX2lkLG2JiwoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:crimson_nylium", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTnAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fbnlsaXVtBAkAbmFtZV9oYXNoOr6DJYW2bFYDCgBuZXR3b3JrX2lkuWpRDgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTnAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fbnlsaXVtBAkAbmFtZV9oYXNoOr6DJYW2bFYDCgBuZXR3b3JrX2lkuWpRDgoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:warped_nylium", - "block_state_b64": "CgAAAwgAYmxvY2tfaWToAQAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9ueWxpdW0ECQBuYW1lX2hhc2g0Zf89cfr3rwMKAG5ldHdvcmtfaWSu/kekCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWToAQAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9ueWxpdW0ECQBuYW1lX2hhc2g0Zf89cfr3rwMKAG5ldHdvcmtfaWSu/kekCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:netherrack", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRXAAAACAQAbmFtZRQAbWluZWNyYWZ0Om5ldGhlcnJhY2sECQBuYW1lX2hhc2i/r5ZyRsvPyQMKAG5ldHdvcmtfaWTAiTOACgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRXAAAACAQAbmFtZRQAbWluZWNyYWZ0Om5ldGhlcnJhY2sECQBuYW1lX2hhc2i/r5ZyRsvPyQMKAG5ldHdvcmtfaWTAiTOACgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:basalt", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTpAQAACAQAbmFtZRAAbWluZWNyYWZ0OmJhc2FsdAQJAG5hbWVfaGFzaH+UQO2yWodiAwoAbmV0d29ya19pZBPNSV4KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTpAQAACAQAbmFtZRAAbWluZWNyYWZ0OmJhc2FsdAQJAG5hbWVfaGFzaH+UQO2yWodiAwoAbmV0d29ya19pZBPNSV4KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:polished_basalt", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTqAQAACAQAbmFtZRkAbWluZWNyYWZ0OnBvbGlzaGVkX2Jhc2FsdAQJAG5hbWVfaGFzaMS+L0gMnRcBAwoAbmV0d29ya19pZF+/mHwKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTqAQAACAQAbmFtZRkAbWluZWNyYWZ0OnBvbGlzaGVkX2Jhc2FsdAQJAG5hbWVfaGFzaMS+L0gMnRcBAwoAbmV0d29ya19pZF+/mHwKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:smooth_basalt", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR4AgAACAQAbmFtZRcAbWluZWNyYWZ0OnNtb290aF9iYXNhbHQECQBuYW1lX2hhc2jKPUdz89kuNAMKAG5ldHdvcmtfaWTkb/oVCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWR4AgAACAQAbmFtZRcAbWluZWNyYWZ0OnNtb290aF9iYXNhbHQECQBuYW1lX2hhc2jKPUdz89kuNAMKAG5ldHdvcmtfaWTkb/oVCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:soul_soil", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTrAQAACAQAbmFtZRMAbWluZWNyYWZ0OnNvdWxfc29pbAQJAG5hbWVfaGFzaC1/87ccutuTAwoAbmV0d29ya19pZKc63SMKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTrAQAACAQAbmFtZRMAbWluZWNyYWZ0OnNvdWxfc29pbAQJAG5hbWVfaGFzaC1/87ccutuTAwoAbmV0d29ya19pZKc63SMKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:dirt", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAAAACAQAbmFtZQ4AbWluZWNyYWZ0OmRpcnQECQBuYW1lX2hhc2hXp6jnXAe+kQMKAG5ldHdvcmtfaWQmkQtoCgYAc3RhdGVzCAkAZGlydF90eXBlBgBub3JtYWwAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAAAACAQAbmFtZQ4AbWluZWNyYWZ0OmRpcnQECQBuYW1lX2hhc2hXp6jnXAe+kQMKAG5ldHdvcmtfaWQmkQtoCgYAc3RhdGVzCAkAZGlydF90eXBlBgBub3JtYWwAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:dirt", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAAAACAQAbmFtZQ4AbWluZWNyYWZ0OmRpcnQECQBuYW1lX2hhc2hXp6jnXAe+kQMKAG5ldHdvcmtfaWQId9pLCgYAc3RhdGVzCAkAZGlydF90eXBlBgBjb2Fyc2UAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAAAACAQAbmFtZQ4AbWluZWNyYWZ0OmRpcnQECQBuYW1lX2hhc2hXp6jnXAe+kQMKAG5ldHdvcmtfaWQId9pLCgYAc3RhdGVzCAkAZGlydF90eXBlBgBjb2Fyc2UAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:farmland", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ8AAAACAQAbmFtZRIAbWluZWNyYWZ0OmZhcm1sYW5kBAkAbmFtZV9oYXNoxyQ5ag7LolADCgBuZXR3b3JrX2lkX618FQoGAHN0YXRlcwMSAG1vaXN0dXJpemVkX2Ftb3VudAAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ8AAAACAQAbmFtZRIAbWluZWNyYWZ0OmZhcm1sYW5kBAkAbmFtZV9oYXNoxyQ5ag7LolADCgBuZXR3b3JrX2lkX618FQoGAHN0YXRlcwMSAG1vaXN0dXJpemVkX2Ftb3VudAAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:grass_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQCAAAACAQAbmFtZRUAbWluZWNyYWZ0OmdyYXNzX2Jsb2NrBAkAbmFtZV9oYXNojPyGp3/CSZwDCgBuZXR3b3JrX2lktCgx3goGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQCAAAACAQAbmFtZRUAbWluZWNyYWZ0OmdyYXNzX2Jsb2NrBAkAbmFtZV9oYXNojPyGp3/CSZwDCgBuZXR3b3JrX2lktCgx3goGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:grass_path", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTGAAAACAQAbmFtZRQAbWluZWNyYWZ0OmdyYXNzX3BhdGgECQBuYW1lX2hhc2i0/KZV8Qsy+gMKAG5ldHdvcmtfaWT7CcdzCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTGAAAACAQAbmFtZRQAbWluZWNyYWZ0OmdyYXNzX3BhdGgECQBuYW1lX2hhc2i0/KZV8Qsy+gMKAG5ldHdvcmtfaWT7CcdzCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:podzol", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTzAAAACAQAbmFtZRAAbWluZWNyYWZ0OnBvZHpvbAQJAG5hbWVfaGFzaBzqokRjH4Z1AwoAbmV0d29ya19pZPPS/GUKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTzAAAACAQAbmFtZRAAbWluZWNyYWZ0OnBvZHpvbAQJAG5hbWVfaGFzaBzqokRjH4Z1AwoAbmV0d29ya19pZPPS/GUKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:mycelium", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRuAAAACAQAbmFtZRIAbWluZWNyYWZ0Om15Y2VsaXVtBAkAbmFtZV9oYXNojTN09cKickIDCgBuZXR3b3JrX2lkLNPxXQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRuAAAACAQAbmFtZRIAbWluZWNyYWZ0Om15Y2VsaXVtBAkAbmFtZV9oYXNojTN09cKickIDCgBuZXR3b3JrX2lkLNPxXQoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:mud", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTYAgAACAQAbmFtZQ0AbWluZWNyYWZ0Om11ZAQJAG5hbWVfaGFzaPb/3P+uLy+9AwoAbmV0d29ya19pZPIUlUkKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTYAgAACAQAbmFtZQ0AbWluZWNyYWZ0Om11ZAQJAG5hbWVfaGFzaPb/3P+uLy+9AwoAbmV0d29ya19pZPIUlUkKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:stone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQBAAAACAQAbmFtZQ8AbWluZWNyYWZ0OnN0b25lBAkAbmFtZV9oYXNoE3mqhJxzJycDCgBuZXR3b3JrX2lkIQ4xgAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQBAAAACAQAbmFtZQ8AbWluZWNyYWZ0OnN0b25lBAkAbmFtZV9oYXNoE3mqhJxzJycDCgBuZXR3b3JrX2lkIQ4xgAoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:iron_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQPAAAACAQAbmFtZRIAbWluZWNyYWZ0Omlyb25fb3JlBAkAbmFtZV9oYXNoS7BYtLnfx3gDCgBuZXR3b3JrX2lk3loneQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQPAAAACAQAbmFtZRIAbWluZWNyYWZ0Omlyb25fb3JlBAkAbmFtZV9oYXNoS7BYtLnfx3gDCgBuZXR3b3JrX2lk3loneQoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:gold_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQOAAAACAQAbmFtZRIAbWluZWNyYWZ0OmdvbGRfb3JlBAkAbmFtZV9oYXNoC5Y+DUGXLC4DCgBuZXR3b3JrX2lkNhvMfwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQOAAAACAQAbmFtZRIAbWluZWNyYWZ0OmdvbGRfb3JlBAkAbmFtZV9oYXNoC5Y+DUGXLC4DCgBuZXR3b3JrX2lkNhvMfwoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:diamond_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ4AAAACAQAbmFtZRUAbWluZWNyYWZ0OmRpYW1vbmRfb3JlBAkAbmFtZV9oYXNokUOJ2wZZrGQDCgBuZXR3b3JrX2lk/dChVAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ4AAAACAQAbmFtZRUAbWluZWNyYWZ0OmRpYW1vbmRfb3JlBAkAbmFtZV9oYXNokUOJ2wZZrGQDCgBuZXR3b3JrX2lk/dChVAoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:lapis_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQVAAAACAQAbmFtZRMAbWluZWNyYWZ0OmxhcGlzX29yZQQJAG5hbWVfaGFzaMrmrUrSzb7qAwoAbmV0d29ya19pZMg+qK4KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQVAAAACAQAbmFtZRMAbWluZWNyYWZ0OmxhcGlzX29yZQQJAG5hbWVfaGFzaMrmrUrSzb7qAwoAbmV0d29ya19pZMg+qK4KBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:redstone_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRJAAAACAQAbmFtZRYAbWluZWNyYWZ0OnJlZHN0b25lX29yZQQJAG5hbWVfaGFzaFHVnp8Wc4JbAwoAbmV0d29ya19pZKDYvQoKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRJAAAACAQAbmFtZRYAbWluZWNyYWZ0OnJlZHN0b25lX29yZQQJAG5hbWVfaGFzaFHVnp8Wc4JbAwoAbmV0d29ya19pZKDYvQoKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:coal_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQQAAAACAQAbmFtZRIAbWluZWNyYWZ0OmNvYWxfb3JlBAkAbmFtZV9oYXNo1OjA+Iuy51oDCgBuZXR3b3JrX2lk+R/aKAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQQAAAACAQAbmFtZRIAbWluZWNyYWZ0OmNvYWxfb3JlBAkAbmFtZV9oYXNo1OjA+Iuy51oDCgBuZXR3b3JrX2lk+R/aKAoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:copper_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ2AgAACAQAbmFtZRQAbWluZWNyYWZ0OmNvcHBlcl9vcmUECQBuYW1lX2hhc2iSZduSntOzOwMKAG5ldHdvcmtfaWQtIuCnCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ2AgAACAQAbmFtZRQAbWluZWNyYWZ0OmNvcHBlcl9vcmUECQBuYW1lX2hhc2iSZduSntOzOwMKAG5ldHdvcmtfaWQtIuCnCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:emerald_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSBAAAACAQAbmFtZRUAbWluZWNyYWZ0OmVtZXJhbGRfb3JlBAkAbmFtZV9oYXNoJTovr+VgINsDCgBuZXR3b3JrX2lknbkqCgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSBAAAACAQAbmFtZRUAbWluZWNyYWZ0OmVtZXJhbGRfb3JlBAkAbmFtZV9oYXNoJTovr+VgINsDCgBuZXR3b3JrX2lknbkqCgoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:quartz_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSZAAAACAQAbmFtZRQAbWluZWNyYWZ0OnF1YXJ0el9vcmUECQBuYW1lX2hhc2g0yNHLMK9TaQMKAG5ldHdvcmtfaWSzN7nzCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSZAAAACAQAbmFtZRQAbWluZWNyYWZ0OnF1YXJ0el9vcmUECQBuYW1lX2hhc2g0yNHLMK9TaQMKAG5ldHdvcmtfaWSzN7nzCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:nether_gold_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQfAgAACAQAbmFtZRkAbWluZWNyYWZ0Om5ldGhlcl9nb2xkX29yZQQJAG5hbWVfaGFzaEJZ7segIBgBAwoAbmV0d29ya19pZNI9pDgKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQfAgAACAQAbmFtZRkAbWluZWNyYWZ0Om5ldGhlcl9nb2xkX29yZQQJAG5hbWVfaGFzaEJZ7segIBgBAwoAbmV0d29ya19pZNI9pDgKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:ancient_debris", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQOAgAACAQAbmFtZRgAbWluZWNyYWZ0OmFuY2llbnRfZGVicmlzBAkAbmFtZV9oYXNoNrbxMc9AwKcDCgBuZXR3b3JrX2lkrSNjEAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQOAgAACAQAbmFtZRgAbWluZWNyYWZ0OmFuY2llbnRfZGVicmlzBAkAbmFtZV9oYXNoNrbxMc9AwKcDCgBuZXR3b3JrX2lkrSNjEAoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:deepslate_iron_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSQAgAACAQAbmFtZRwAbWluZWNyYWZ0OmRlZXBzbGF0ZV9pcm9uX29yZQQJAG5hbWVfaGFzaB/fDL9pgvXXAwoAbmV0d29ya19pZFA0bz4KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSQAgAACAQAbmFtZRwAbWluZWNyYWZ0OmRlZXBzbGF0ZV9pcm9uX29yZQQJAG5hbWVfaGFzaB/fDL9pgvXXAwoAbmV0d29ya19pZFA0bz4KBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:deepslate_gold_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAgAACAQAbmFtZRwAbWluZWNyYWZ0OmRlZXBzbGF0ZV9nb2xkX29yZQQJAG5hbWVfaGFzaF9G7WYhKFinAwoAbmV0d29ya19pZHQTfBUKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAgAACAQAbmFtZRwAbWluZWNyYWZ0OmRlZXBzbGF0ZV9nb2xkX29yZQQJAG5hbWVfaGFzaF9G7WYhKFinAwoAbmV0d29ya19pZHQTfBUKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:deepslate_diamond_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSUAgAACAQAbmFtZR8AbWluZWNyYWZ0OmRlZXBzbGF0ZV9kaWFtb25kX29yZQQJAG5hbWVfaGFzaEUH5USh+iD3AwoAbmV0d29ya19pZHP6VzAKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSUAgAACAQAbmFtZR8AbWluZWNyYWZ0OmRlZXBzbGF0ZV9kaWFtb25kX29yZQQJAG5hbWVfaGFzaEUH5USh+iD3AwoAbmV0d29ya19pZHP6VzAKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:deepslate_lapis_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSPAgAACAQAbmFtZR0AbWluZWNyYWZ0OmRlZXBzbGF0ZV9sYXBpc19vcmUECQBuYW1lX2hhc2j+yFxU/KZs1gMKAG5ldHdvcmtfaWRKINzICgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSPAgAACAQAbmFtZR0AbWluZWNyYWZ0OmRlZXBzbGF0ZV9sYXBpc19vcmUECQBuYW1lX2hhc2j+yFxU/KZs1gMKAG5ldHdvcmtfaWRKINzICgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:deepslate_redstone_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSSAgAACAQAbmFtZSAAbWluZWNyYWZ0OmRlZXBzbGF0ZV9yZWRzdG9uZV9vcmUECQBuYW1lX2hhc2iVgM3wWWD6ugMKAG5ldHdvcmtfaWReBdYRCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSSAgAACAQAbmFtZSAAbWluZWNyYWZ0OmRlZXBzbGF0ZV9yZWRzdG9uZV9vcmUECQBuYW1lX2hhc2iVgM3wWWD6ugMKAG5ldHdvcmtfaWReBdYRCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:deepslate_emerald_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSWAgAACAQAbmFtZR8AbWluZWNyYWZ0OmRlZXBzbGF0ZV9lbWVyYWxkX29yZQQJAG5hbWVfaGFzaNlfo5HTwS6wAwoAbmV0d29ya19pZNeie6sKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSWAgAACAQAbmFtZR8AbWluZWNyYWZ0OmRlZXBzbGF0ZV9lbWVyYWxkX29yZQQJAG5hbWVfaGFzaNlfo5HTwS6wAwoAbmV0d29ya19pZNeie6sKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:deepslate_coal_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSVAgAACAQAbmFtZRwAbWluZWNyYWZ0OmRlZXBzbGF0ZV9jb2FsX29yZQQJAG5hbWVfaGFzaIjikmcbRrPPAwoAbmV0d29ya19pZD9TiygKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSVAgAACAQAbmFtZRwAbWluZWNyYWZ0OmRlZXBzbGF0ZV9jb2FsX29yZQQJAG5hbWVfaGFzaIjikmcbRrPPAwoAbmV0d29ya19pZD9TiygKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:deepslate_copper_ore", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSXAgAACAQAbmFtZR4AbWluZWNyYWZ0OmRlZXBzbGF0ZV9jb3BwZXJfb3JlBAkAbmFtZV9oYXNottjV4Ev5LAQDCgBuZXR3b3JrX2lkP23rgQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSXAgAACAQAbmFtZR4AbWluZWNyYWZ0OmRlZXBzbGF0ZV9jb3BwZXJfb3JlBAkAbmFtZV9oYXNottjV4Ev5LAQDCgBuZXR3b3JrX2lkP23rgQoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:gravel", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQNAAAACAQAbmFtZRAAbWluZWNyYWZ0OmdyYXZlbAQJAG5hbWVfaGFzaOFxz8XJd2r/AwoAbmV0d29ya19pZBpfI1sKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQNAAAACAQAbmFtZRAAbWluZWNyYWZ0OmdyYXZlbAQJAG5hbWVfaGFzaOFxz8XJd2r/AwoAbmV0d29ya19pZBpfI1sKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:granite", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRNAwAACAQAbmFtZREAbWluZWNyYWZ0OmdyYW5pdGUECQBuYW1lX2hhc2iq+Dur2pw4AwMKAG5ldHdvcmtfaWT2NMfJCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRNAwAACAQAbmFtZREAbWluZWNyYWZ0OmdyYW5pdGUECQBuYW1lX2hhc2iq+Dur2pw4AwMKAG5ldHdvcmtfaWT2NMfJCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:diorite", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRPAwAACAQAbmFtZREAbWluZWNyYWZ0OmRpb3JpdGUECQBuYW1lX2hhc2iaFsq2iinZBQMKAG5ldHdvcmtfaWQqGE6XCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRPAwAACAQAbmFtZREAbWluZWNyYWZ0OmRpb3JpdGUECQBuYW1lX2hhc2iaFsq2iinZBQMKAG5ldHdvcmtfaWQqGE6XCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:andesite", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRRAwAACAQAbmFtZRIAbWluZWNyYWZ0OmFuZGVzaXRlBAkAbmFtZV9oYXNosaLIEnQQoSYDCgBuZXR3b3JrX2lkEApRZAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRRAwAACAQAbmFtZRIAbWluZWNyYWZ0OmFuZGVzaXRlBAkAbmFtZV9oYXNosaLIEnQQoSYDCgBuZXR3b3JrX2lkEApRZAoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:blackstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQQAgAACAQAbmFtZRQAbWluZWNyYWZ0OmJsYWNrc3RvbmUECQBuYW1lX2hhc2iMFYziD80D6QMKAG5ldHdvcmtfaWSrUryHCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQQAgAACAQAbmFtZRQAbWluZWNyYWZ0OmJsYWNrc3RvbmUECQBuYW1lX2hhc2iMFYziD80D6QMKAG5ldHdvcmtfaWSrUryHCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:deepslate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR5AgAACAQAbmFtZRMAbWluZWNyYWZ0OmRlZXBzbGF0ZQQJAG5hbWVfaGFzaKX5pAblxz8TAwoAbmV0d29ya19pZOJoQjsKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWR5AgAACAQAbmFtZRMAbWluZWNyYWZ0OmRlZXBzbGF0ZQQJAG5hbWVfaGFzaKX5pAblxz8TAwoAbmV0d29ya19pZOJoQjsKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:polished_granite", - "block_state_b64": "CgAAAwgAYmxvY2tfaWROAwAACAQAbmFtZRoAbWluZWNyYWZ0OnBvbGlzaGVkX2dyYW5pdGUECQBuYW1lX2hhc2iLiEfys8pFIAMKAG5ldHdvcmtfaWTCxxcHCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWROAwAACAQAbmFtZRoAbWluZWNyYWZ0OnBvbGlzaGVkX2dyYW5pdGUECQBuYW1lX2hhc2iLiEfys8pFIAMKAG5ldHdvcmtfaWTCxxcHCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:polished_diorite", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRQAwAACAQAbmFtZRoAbWluZWNyYWZ0OnBvbGlzaGVkX2Rpb3JpdGUECQBuYW1lX2hhc2hTxY4fKmNmlAMKAG5ldHdvcmtfaWTmtjdRCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRQAwAACAQAbmFtZRoAbWluZWNyYWZ0OnBvbGlzaGVkX2Rpb3JpdGUECQBuYW1lX2hhc2hTxY4fKmNmlAMKAG5ldHdvcmtfaWTmtjdRCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:polished_andesite", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRSAwAACAQAbmFtZRsAbWluZWNyYWZ0OnBvbGlzaGVkX2FuZGVzaXRlBAkAbmFtZV9oYXNovl28uFk4HuQDCgBuZXR3b3JrX2lklFjuCwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRSAwAACAQAbmFtZRsAbWluZWNyYWZ0OnBvbGlzaGVkX2FuZGVzaXRlBAkAbmFtZV9oYXNovl28uFk4HuQDCgBuZXR3b3JrX2lklFjuCwoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:polished_blackstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQiAgAACAQAbmFtZR0AbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmUECQBuYW1lX2hhc2jT9fHCl6vWQQMKAG5ldHdvcmtfaWR/Ho6oCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQiAgAACAQAbmFtZR0AbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmUECQBuYW1lX2hhc2jT9fHCl6vWQQMKAG5ldHdvcmtfaWR/Ho6oCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:polished_deepslate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR+AgAACAQAbmFtZRwAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZQQJAG5hbWVfaGFzaHC1edoaWF3uAwoAbmV0d29ya19pZCPeQsEKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWR+AgAACAQAbmFtZRwAbWluZWNyYWZ0OnBvbGlzaGVkX2RlZXBzbGF0ZQQJAG5hbWVfaGFzaHC1edoaWF3uAwoAbmV0d29ya19pZCPeQsEKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:sand", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQMAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnNhbmQECQBuYW1lX2hhc2i6lthXXbAyWAMKAG5ldHdvcmtfaWTekU/mCgYAc3RhdGVzCAkAc2FuZF90eXBlBgBub3JtYWwAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQMAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnNhbmQECQBuYW1lX2hhc2i6lthXXbAyWAMKAG5ldHdvcmtfaWTekU/mCgYAc3RhdGVzCAkAc2FuZF90eXBlBgBub3JtYWwAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:sand", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQMAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnNhbmQECQBuYW1lX2hhc2i6lthXXbAyWAMKAG5ldHdvcmtfaWSTgcqmCgYAc3RhdGVzCAkAc2FuZF90eXBlAwByZWQAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQMAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnNhbmQECQBuYW1lX2hhc2i6lthXXbAyWAMKAG5ldHdvcmtfaWSTgcqmCgYAc3RhdGVzCAkAc2FuZF90eXBlAwByZWQAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:cactus", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRRAAAACAQAbmFtZRAAbWluZWNyYWZ0OmNhY3R1cwQJAG5hbWVfaGFzaCG9zL0N4wvGAwoAbmV0d29ya19pZDeCERAKBgBzdGF0ZXMDAwBhZ2UAAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRRAAAACAQAbmFtZRAAbWluZWNyYWZ0OmNhY3R1cwQJAG5hbWVfaGFzaCG9zL0N4wvGAwoAbmV0d29ya19pZDeCERAKBgBzdGF0ZXMDAwBhZ2UAAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:oak_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQRAAAACAQAbmFtZREAbWluZWNyYWZ0Om9ha19sb2cECQBuYW1lX2hhc2ho6TS+K7PZFQMKAG5ldHdvcmtfaWQjfjoxCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQRAAAACAQAbmFtZREAbWluZWNyYWZ0Om9ha19sb2cECQBuYW1lX2hhc2ho6TS+K7PZFQMKAG5ldHdvcmtfaWQjfjoxCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:stripped_oak_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQJAQAACAQAbmFtZRoAbWluZWNyYWZ0OnN0cmlwcGVkX29ha19sb2cECQBuYW1lX2hhc2h8dqh+OOHU4wMKAG5ldHdvcmtfaWSYKjdrCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQJAQAACAQAbmFtZRoAbWluZWNyYWZ0OnN0cmlwcGVkX29ha19sb2cECQBuYW1lX2hhc2h8dqh+OOHU4wMKAG5ldHdvcmtfaWSYKjdrCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:spruce_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ4AwAACAQAbmFtZRQAbWluZWNyYWZ0OnNwcnVjZV9sb2cECQBuYW1lX2hhc2hZ03qaLoF3WgMKAG5ldHdvcmtfaWRlFD8eCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ4AwAACAQAbmFtZRQAbWluZWNyYWZ0OnNwcnVjZV9sb2cECQBuYW1lX2hhc2hZ03qaLoF3WgMKAG5ldHdvcmtfaWRlFD8eCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:stripped_spruce_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQEAQAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX3NwcnVjZV9sb2cECQBuYW1lX2hhc2iNrhKjS5IyrgMKAG5ldHdvcmtfaWRQcEC3CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQEAQAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX3NwcnVjZV9sb2cECQBuYW1lX2hhc2iNrhKjS5IyrgMKAG5ldHdvcmtfaWRQcEC3CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:birch_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ5AwAACAQAbmFtZRMAbWluZWNyYWZ0OmJpcmNoX2xvZwQJAG5hbWVfaGFzaBUzT3NxsZAnAwoAbmV0d29ya19pZBKN3VQKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ5AwAACAQAbmFtZRMAbWluZWNyYWZ0OmJpcmNoX2xvZwQJAG5hbWVfaGFzaBUzT3NxsZAnAwoAbmV0d29ya19pZBKN3VQKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:stripped_birch_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQFAQAACAQAbmFtZRwAbWluZWNyYWZ0OnN0cmlwcGVkX2JpcmNoX2xvZwQJAG5hbWVfaGFzaCFKS4AeuSidAwoAbmV0d29ya19pZN0IONIKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQFAQAACAQAbmFtZRwAbWluZWNyYWZ0OnN0cmlwcGVkX2JpcmNoX2xvZwQJAG5hbWVfaGFzaCFKS4AeuSidAwoAbmV0d29ya19pZN0IONIKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:jungle_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ6AwAACAQAbmFtZRQAbWluZWNyYWZ0Omp1bmdsZV9sb2cECQBuYW1lX2hhc2gkwW0KNulqDgMKAG5ldHdvcmtfaWQaziU/CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ6AwAACAQAbmFtZRQAbWluZWNyYWZ0Omp1bmdsZV9sb2cECQBuYW1lX2hhc2gkwW0KNulqDgMKAG5ldHdvcmtfaWQaziU/CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:stripped_jungle_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAQAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2p1bmdsZV9sb2cECQBuYW1lX2hhc2hAwMsgOk02JAMKAG5ldHdvcmtfaWQvls0eCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAQAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2p1bmdsZV9sb2cECQBuYW1lX2hhc2hAwMsgOk02JAMKAG5ldHdvcmtfaWQvls0eCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:acacia_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSiAAAACAQAbmFtZRQAbWluZWNyYWZ0OmFjYWNpYV9sb2cECQBuYW1lX2hhc2iV48VpYhjoYQMKAG5ldHdvcmtfaWRxEqe0CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSiAAAACAQAbmFtZRQAbWluZWNyYWZ0OmFjYWNpYV9sb2cECQBuYW1lX2hhc2iV48VpYhjoYQMKAG5ldHdvcmtfaWRxEqe0CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:stripped_acacia_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQHAQAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2FjYWNpYV9sb2cECQBuYW1lX2hhc2hJb0lQqnEqlgMKAG5ldHdvcmtfaWRg3IdRCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQHAQAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2FjYWNpYV9sb2cECQBuYW1lX2hhc2hJb0lQqnEqlgMKAG5ldHdvcmtfaWRg3IdRCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:dark_oak_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ7AwAACAQAbmFtZRYAbWluZWNyYWZ0OmRhcmtfb2FrX2xvZwQJAG5hbWVfaGFzaIWfVRd0XUo3AwoAbmV0d29ya19pZPMM7LYKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ7AwAACAQAbmFtZRYAbWluZWNyYWZ0OmRhcmtfb2FrX2xvZwQJAG5hbWVfaGFzaIWfVRd0XUo3AwoAbmV0d29ya19pZPMM7LYKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:stripped_dark_oak_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQIAQAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX2Rhcmtfb2FrX2xvZwQJAG5hbWVfaGFzaPFTdxRdPwkOAwoAbmV0d29ya19pZDIzenIKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQIAQAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX2Rhcmtfb2FrX2xvZwQJAG5hbWVfaGFzaPFTdxRdPwkOAwoAbmV0d29ya19pZDIzenIKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:mangrove_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTjAgAACAQAbmFtZRYAbWluZWNyYWZ0Om1hbmdyb3ZlX2xvZwQJAG5hbWVfaGFzaHZe6DzPZBobAwoAbmV0d29ya19pZG6DuYkKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTjAgAACAQAbmFtZRYAbWluZWNyYWZ0Om1hbmdyb3ZlX2xvZwQJAG5hbWVfaGFzaHZe6DzPZBobAwoAbmV0d29ya19pZG6DuYkKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:stripped_mangrove_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTkAgAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX21hbmdyb3ZlX2xvZwQJAG5hbWVfaGFzaLqIBo4hwA//AwoAbmV0d29ya19pZPtRn7UKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTkAgAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX21hbmdyb3ZlX2xvZwQJAG5hbWVfaGFzaLqIBo4hwA//AwoAbmV0d29ya19pZPtRn7UKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:cherry_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQXAwAACAQAbmFtZRQAbWluZWNyYWZ0OmNoZXJyeV9sb2cECQBuYW1lX2hhc2hwFlaioppB1wMKAG5ldHdvcmtfaWS2sdXECgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQXAwAACAQAbmFtZRQAbWluZWNyYWZ0OmNoZXJyeV9sb2cECQBuYW1lX2hhc2hwFlaioppB1wMKAG5ldHdvcmtfaWS2sdXECgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:stripped_cherry_log", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQWAwAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2NoZXJyeV9sb2cECQBuYW1lX2hhc2i85H6G+WhXaAMKAG5ldHdvcmtfaWRjzoglCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQWAwAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2NoZXJyeV9sb2cECQBuYW1lX2hhc2i85H6G+WhXaAMKAG5ldHdvcmtfaWRjzoglCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:crimson_stem", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTgAQAACAQAbmFtZRYAbWluZWNyYWZ0OmNyaW1zb25fc3RlbQQJAG5hbWVfaGFzaM0FzfL0UTKZAwoAbmV0d29ya19pZKvzID0KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTgAQAACAQAbmFtZRYAbWluZWNyYWZ0OmNyaW1zb25fc3RlbQQJAG5hbWVfaGFzaM0FzfL0UTKZAwoAbmV0d29ya19pZKvzID0KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:stripped_crimson_stem", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTvAQAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX2NyaW1zb25fc3RlbQQJAG5hbWVfaGFzaDlA6nood57EAwoAbmV0d29ya19pZHrIqjIKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTvAQAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX2NyaW1zb25fc3RlbQQJAG5hbWVfaGFzaDlA6nood57EAwoAbmV0d29ya19pZHrIqjIKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:warped_stem", - "block_state_b64": "CgAAAwgAYmxvY2tfaWThAQAACAQAbmFtZRUAbWluZWNyYWZ0OndhcnBlZF9zdGVtBAkAbmFtZV9oYXNon7cKfPZxdrUDCgBuZXR3b3JrX2lkerWyMwoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWThAQAACAQAbmFtZRUAbWluZWNyYWZ0OndhcnBlZF9zdGVtBAkAbmFtZV9oYXNon7cKfPZxdrUDCgBuZXR3b3JrX2lkerWyMwoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:stripped_warped_stem", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTwAQAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX3dhcnBlZF9zdGVtBAkAbmFtZV9oYXNoEw+y0dDPSd8DCgBuZXR3b3JrX2lkIQ9vBAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTwAQAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX3dhcnBlZF9zdGVtBAkAbmFtZV9oYXNoEw+y0dDPSd8DCgBuZXR3b3JrX2lkIQ9vBAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:oak_wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAQAACAQAbmFtZRIAbWluZWNyYWZ0Om9ha193b29kBAkAbmFtZV9oYXNoqQIkuVPyJX0DCgBuZXR3b3JrX2lku2G1YAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAQAACAQAbmFtZRIAbWluZWNyYWZ0Om9ha193b29kBAkAbmFtZV9oYXNoqQIkuVPyJX0DCgBuZXR3b3JrX2lku2G1YAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:spruce_wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQtBAAACAQAbmFtZRUAbWluZWNyYWZ0OnNwcnVjZV93b29kBAkAbmFtZV9oYXNoTrIJ5TAQ+OgDCgBuZXR3b3JrX2lkaXLxCwoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQtBAAACAQAbmFtZRUAbWluZWNyYWZ0OnNwcnVjZV93b29kBAkAbmFtZV9oYXNoTrIJ5TAQ+OgDCgBuZXR3b3JrX2lkaXLxCwoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:birch_wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQuBAAACAQAbmFtZRQAbWluZWNyYWZ0OmJpcmNoX3dvb2QECQBuYW1lX2hhc2iqVjG4xt0cKQMKAG5ldHdvcmtfaWS06c5VCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQuBAAACAQAbmFtZRQAbWluZWNyYWZ0OmJpcmNoX3dvb2QECQBuYW1lX2hhc2iqVjG4xt0cKQMKAG5ldHdvcmtfaWS06c5VCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:jungle_wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQvBAAACAQAbmFtZRUAbWluZWNyYWZ0Omp1bmdsZV93b29kBAkAbmFtZV9oYXNo9bYW29ORWCoDCgBuZXR3b3JrX2lkyFyKLQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQvBAAACAQAbmFtZRUAbWluZWNyYWZ0Omp1bmdsZV93b29kBAkAbmFtZV9oYXNo9bYW29ORWCoDCgBuZXR3b3JrX2lkyFyKLQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:acacia_wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQwBAAACAQAbmFtZRUAbWluZWNyYWZ0OmFjYWNpYV93b29kBAkAbmFtZV9oYXNoKkDfgzlJUcIDCgBuZXR3b3JrX2lkuTWlcgoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQwBAAACAQAbmFtZRUAbWluZWNyYWZ0OmFjYWNpYV93b29kBAkAbmFtZV9oYXNoKkDfgzlJUcIDCgBuZXR3b3JrX2lkuTWlcgoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:dark_oak_wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQxBAAACAQAbmFtZRcAbWluZWNyYWZ0OmRhcmtfb2FrX3dvb2QECQBuYW1lX2hhc2jaKv4ORLadAAMKAG5ldHdvcmtfaWSDrNQ8CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQxBAAACAQAbmFtZRcAbWluZWNyYWZ0OmRhcmtfb2FrX3dvb2QECQBuYW1lX2hhc2jaKv4ORLadAAMKAG5ldHdvcmtfaWSDrNQ8CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:stripped_oak_wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQyBAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0cmlwcGVkX29ha193b29kBAkAbmFtZV9oYXNovW6KCv+VZnsDCgBuZXR3b3JrX2lkkhWGegoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQyBAAACAQAbmFtZRsAbWluZWNyYWZ0OnN0cmlwcGVkX29ha193b29kBAkAbmFtZV9oYXNovW6KCv+VZnsDCgBuZXR3b3JrX2lkkhWGegoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:stripped_spruce_wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQzBAAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX3NwcnVjZV93b29kBAkAbmFtZV9oYXNoMnuUk4Xo6icDCgBuZXR3b3JrX2lkes2ydAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQzBAAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX3NwcnVjZV93b29kBAkAbmFtZV9oYXNoMnuUk4Xo6icDCgBuZXR3b3JrX2lkes2ydAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:stripped_birch_wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ0BAAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2JpcmNoX3dvb2QECQBuYW1lX2hhc2hm88R604TKbAMKAG5ldHdvcmtfaWRleEMJCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ0BAAACAQAbmFtZR0AbWluZWNyYWZ0OnN0cmlwcGVkX2JpcmNoX3dvb2QECQBuYW1lX2hhc2hm88R604TKbAMKAG5ldHdvcmtfaWRleEMJCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:stripped_jungle_wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ1BAAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX2p1bmdsZV93b29kBAkAbmFtZV9oYXNoUVs6KsZQRBoDCgBuZXR3b3JrX2lk92k8HQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ1BAAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX2p1bmdsZV93b29kBAkAbmFtZV9oYXNoUVs6KsZQRBoDCgBuZXR3b3JrX2lk92k8HQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:stripped_acacia_wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ2BAAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX2FjYWNpYV93b29kBAkAbmFtZV9oYXNo/kOPN2bCJhUDCgBuZXR3b3JrX2lktl6LwQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ2BAAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX2FjYWNpYV93b29kBAkAbmFtZV9oYXNo/kOPN2bCJhUDCgBuZXR3b3JrX2lktl6LwQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:stripped_dark_oak_wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ3BAAACAQAbmFtZSAAbWluZWNyYWZ0OnN0cmlwcGVkX2Rhcmtfb2FrX3dvb2QECQBuYW1lX2hhc2h2jFDfKVFgfAMKAG5ldHdvcmtfaWTgZQ5VCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ3BAAACAQAbmFtZSAAbWluZWNyYWZ0OnN0cmlwcGVkX2Rhcmtfb2FrX3dvb2QECQBuYW1lX2hhc2h2jFDfKVFgfAMKAG5ldHdvcmtfaWTgZQ5VCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:mangrove_wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTwAgAACAQAbmFtZRcAbWluZWNyYWZ0Om1hbmdyb3ZlX3dvb2QECQBuYW1lX2hhc2iXVxG0JG2fVAMKAG5ldHdvcmtfaWTok1JCCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTwAgAACAQAbmFtZRcAbWluZWNyYWZ0Om1hbmdyb3ZlX3dvb2QECQBuYW1lX2hhc2iXVxG0JG2fVAMKAG5ldHdvcmtfaWTok1JCCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkBDABzdHJpcHBlZF9iaXQAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:stripped_mangrove_wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTxAgAACAQAbmFtZSAAbWluZWNyYWZ0OnN0cmlwcGVkX21hbmdyb3ZlX3dvb2QECQBuYW1lX2hhc2h7CkbaBF7/WAMKAG5ldHdvcmtfaWQLAX88CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTxAgAACAQAbmFtZSAAbWluZWNyYWZ0OnN0cmlwcGVkX21hbmdyb3ZlX3dvb2QECQBuYW1lX2hhc2h7CkbaBF7/WAMKAG5ldHdvcmtfaWQLAX88CgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:cherry_wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQhAwAACAQAbmFtZRUAbWluZWNyYWZ0OmNoZXJyeV93b29kBAkAbmFtZV9oYXNoAW8srlmpBM8DCgBuZXR3b3JrX2lkEALMfAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AQwAc3RyaXBwZWRfYml0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQhAwAACAQAbmFtZRUAbWluZWNyYWZ0OmNoZXJyeV93b29kBAkAbmFtZV9oYXNoAW8srlmpBM8DCgBuZXR3b3JrX2lkEALMfAoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AQwAc3RyaXBwZWRfYml0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:stripped_cherry_wood", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQgAwAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX2NoZXJyeV93b29kBAkAbmFtZV9oYXNo/e7KXv+CB38DCgBuZXR3b3JrX2lkg5aVtQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQgAwAACAQAbmFtZR4AbWluZWNyYWZ0OnN0cmlwcGVkX2NoZXJyeV93b29kBAkAbmFtZV9oYXNo/e7KXv+CB38DCgBuZXR3b3JrX2lkg5aVtQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:crimson_hyphae", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQqAgAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25faHlwaGFlBAkAbmFtZV9oYXNouRmKmfSqEWADCgBuZXR3b3JrX2lk+Tm5rQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQqAgAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25faHlwaGFlBAkAbmFtZV9oYXNouRmKmfSqEWADCgBuZXR3b3JrX2lk+Tm5rQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:stripped_crimson_hyphae", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQrAgAACAQAbmFtZSEAbWluZWNyYWZ0OnN0cmlwcGVkX2NyaW1zb25faHlwaGFlBAkAbmFtZV9oYXNoFffwmABq4LUDCgBuZXR3b3JrX2lkZAlUbgoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQrAgAACAQAbmFtZSEAbWluZWNyYWZ0OnN0cmlwcGVkX2NyaW1zb25faHlwaGFlBAkAbmFtZV9oYXNoFffwmABq4LUDCgBuZXR3b3JrX2lkZAlUbgoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:warped_hyphae", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQpAgAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9oeXBoYWUECQBuYW1lX2hhc2hn8plQUr6pmQMKAG5ldHdvcmtfaWRU2AIBCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQpAgAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9oeXBoYWUECQBuYW1lX2hhc2hn8plQUr6pmQMKAG5ldHdvcmtfaWRU2AIBCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:stripped_warped_hyphae", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAgAACAQAbmFtZSAAbWluZWNyYWZ0OnN0cmlwcGVkX3dhcnBlZF9oeXBoYWUECQBuYW1lX2hhc2irKq+HYPSgjQMKAG5ldHdvcmtfaWSbrOPDCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQsAgAACAQAbmFtZSAAbWluZWNyYWZ0OnN0cmlwcGVkX3dhcnBlZF9oeXBoYWUECQBuYW1lX2hhc2irKq+HYPSgjQMKAG5ldHdvcmtfaWSbrOPDCgYAc3RhdGVzCAsAcGlsbGFyX2F4aXMBAHkAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:bamboo_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQOAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJhbWJvb19ibG9jawQJAG5hbWVfaGFzaAbDeur6stIBAwoAbmV0d29ya19pZCJAwn0KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQOAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJhbWJvb19ibG9jawQJAG5hbWVfaGFzaAbDeur6stIBAwoAbmV0d29ya19pZCJAwn0KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:stripped_bamboo_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQPAwAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX2JhbWJvb19ibG9jawQJAG5hbWVfaGFzaJpwytpZOZM9AwoAbmV0d29ya19pZKuRbNEKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQPAwAACAQAbmFtZR8AbWluZWNyYWZ0OnN0cmlwcGVkX2JhbWJvb19ibG9jawQJAG5hbWVfaGFzaJpwytpZOZM9AwoAbmV0d29ya19pZKuRbNEKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:oak_leaves", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQSAAAACAQAbmFtZRQAbWluZWNyYWZ0Om9ha19sZWF2ZXMECQBuYW1lX2hhc2h6O4xGqA2oKgMKAG5ldHdvcmtfaWT98c59CgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQSAAAACAQAbmFtZRQAbWluZWNyYWZ0Om9ha19sZWF2ZXMECQBuYW1lX2hhc2h6O4xGqA2oKgMKAG5ldHdvcmtfaWT98c59CgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:spruce_leaves", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQfBAAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9sZWF2ZXMECQBuYW1lX2hhc2i9x1CtNAuqZwMKAG5ldHdvcmtfaWSzF7pTCgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQfBAAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9sZWF2ZXMECQBuYW1lX2hhc2i9x1CtNAuqZwMKAG5ldHdvcmtfaWSzF7pTCgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:birch_leaves", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQgBAAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX2xlYXZlcwQJAG5hbWVfaGFzaBlAGHaoaLZSAwoAbmV0d29ya19pZOjtvWcKBgBzdGF0ZXMBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQgBAAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX2xlYXZlcwQJAG5hbWVfaGFzaBlAGHaoaLZSAwoAbmV0d29ya19pZOjtvWcKBgBzdGF0ZXMBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:jungle_leaves", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQhBAAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9sZWF2ZXMECQBuYW1lX2hhc2iW1uAH07zGhgMKAG5ldHdvcmtfaWSA5KX0CgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQhBAAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9sZWF2ZXMECQBuYW1lX2hhc2iW1uAH07zGhgMKAG5ldHdvcmtfaWSA5KX0CgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:acacia_leaves", - "block_state_b64": "CgAAAwgAYmxvY2tfaWShAAAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9sZWF2ZXMECQBuYW1lX2hhc2iZJf8dAgDRNQMKAG5ldHdvcmtfaWQ/G7VuCgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAAAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9sZWF2ZXMECQBuYW1lX2hhc2iZJf8dAgDRNQMKAG5ldHdvcmtfaWQ/G7VuCgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:dark_oak_leaves", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQiBAAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX2xlYXZlcwQJAG5hbWVfaGFzaCk7rDipWFSjAwoAbmV0d29ya19pZJ2AkbYKBgBzdGF0ZXMBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQiBAAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX2xlYXZlcwQJAG5hbWVfaGFzaCk7rDipWFSjAwoAbmV0d29ya19pZJ2AkbYKBgBzdGF0ZXMBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:mangrove_leaves", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTXAgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX2xlYXZlcwQJAG5hbWVfaGFzaKyI/dWvhEG8AwoAbmV0d29ya19pZPQxCZ8KBgBzdGF0ZXMBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTXAgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX2xlYXZlcwQJAG5hbWVfaGFzaKyI/dWvhEG8AwoAbmV0d29ya19pZPQxCZ8KBgBzdGF0ZXMBDgBwZXJzaXN0ZW50X2JpdAABCgB1cGRhdGVfYml0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:cherry_leaves", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQjAwAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9sZWF2ZXMECQBuYW1lX2hhc2giTs9ChhYBlQMKAG5ldHdvcmtfaWR8bPpwCgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQjAwAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9sZWF2ZXMECQBuYW1lX2hhc2giTs9ChhYBlQMKAG5ldHdvcmtfaWR8bPpwCgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:azalea_leaves", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRDAgAACAQAbmFtZRcAbWluZWNyYWZ0OmF6YWxlYV9sZWF2ZXMECQBuYW1lX2hhc2iXFhD57wFS7AMKAG5ldHdvcmtfaWTNB/9ECgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRDAgAACAQAbmFtZRcAbWluZWNyYWZ0OmF6YWxlYV9sZWF2ZXMECQBuYW1lX2hhc2iXFhD57wFS7AMKAG5ldHdvcmtfaWTNB/9ECgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:azalea_leaves_flowered", - "block_state_b64": "CgAAAwgAYmxvY2tfaWREAgAACAQAbmFtZSAAbWluZWNyYWZ0OmF6YWxlYV9sZWF2ZXNfZmxvd2VyZWQECQBuYW1lX2hhc2gs8jxlS/pMrwMKAG5ldHdvcmtfaWQ7W4PyCgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWREAgAACAQAbmFtZSAAbWluZWNyYWZ0OmF6YWxlYV9sZWF2ZXNfZmxvd2VyZWQECQBuYW1lX2hhc2gs8jxlS/pMrwMKAG5ldHdvcmtfaWQ7W4PyCgYAc3RhdGVzAQ4AcGVyc2lzdGVudF9iaXQAAQoAdXBkYXRlX2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { - "id": "minecraft:sapling", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAAAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWQmoOEvCgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUDAG9hawADBwB2ZXJzaW9uBEYUAQA=" + "id": "minecraft:oak_sapling", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAAAACAQAbmFtZRUAbWluZWNyYWZ0Om9ha19zYXBsaW5nBAkAbmFtZV9oYXNoogXcT9QfjiUDCgBuZXR3b3JrX2lkG22C+AoGAHN0YXRlcwEHAGFnZV9iaXQAAAMHAHZlcnNpb24DABUBAA==" }, { - "id": "minecraft:sapling", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAAAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWQO8pAmCgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUGAHNwcnVjZQADBwB2ZXJzaW9uBEYUAQA=" + "id": "minecraft:spruce_sapling", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ4BAAACAQAbmFtZRgAbWluZWNyYWZ0OnNwcnVjZV9zYXBsaW5nBAkAbmFtZV9oYXNoe8hz4uYP0FcDCgBuZXR3b3JrX2lkUQmhaQoGAHN0YXRlcwEHAGFnZV9iaXQAAAMHAHZlcnNpb24DABUBAA==" }, { - "id": "minecraft:sapling", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAAAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWQDHhokCgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUFAGJpcmNoAAMHAHZlcnNpb24ERhQBAA==" + "id": "minecraft:birch_sapling", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ5BAAACAQAbmFtZRcAbWluZWNyYWZ0OmJpcmNoX3NhcGxpbmcECQBuYW1lX2hhc2h348iJQ/tK4wMKAG5ldHdvcmtfaWQ2Uh53CgYAc3RhdGVzAQcAYWdlX2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { - "id": "minecraft:sapling", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAAAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWTdQrcyCgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUGAGp1bmdsZQADBwB2ZXJzaW9uBEYUAQA=" + "id": "minecraft:jungle_sapling", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ6BAAACAQAbmFtZRgAbWluZWNyYWZ0Omp1bmdsZV9zYXBsaW5nBAkAbmFtZV9oYXNo7tyTOdSrxaADCgBuZXR3b3JrX2lkXmBAdAoGAHN0YXRlcwEHAGFnZV9iaXQAAAMHAHZlcnNpb24DABUBAA==" }, { - "id": "minecraft:sapling", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAAAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWRCDffNCgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUGAGFjYWNpYQADBwB2ZXJzaW9uBEYUAQA=" + "id": "minecraft:acacia_sapling", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ7BAAACAQAbmFtZRgAbWluZWNyYWZ0OmFjYWNpYV9zYXBsaW5nBAkAbmFtZV9oYXNo99sg15uoX7ADCgBuZXR3b3JrX2lkPXX1KgoGAHN0YXRlcwEHAGFnZV9iaXQAAAMHAHZlcnNpb24DABUBAA==" }, { - "id": "minecraft:sapling", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAAAACAQAbmFtZREAbWluZWNyYWZ0OnNhcGxpbmcECQBuYW1lX2hhc2goZxi1oICLKwMKAG5ldHdvcmtfaWR0BRzPCgYAc3RhdGVzAQcAYWdlX2JpdAAIDABzYXBsaW5nX3R5cGUIAGRhcmtfb2FrAAMHAHZlcnNpb24ERhQBAA==" + "id": "minecraft:dark_oak_sapling", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ8BAAACAQAbmFtZRoAbWluZWNyYWZ0OmRhcmtfb2FrX3NhcGxpbmcECQBuYW1lX2hhc2jnVzFplW7cHgMKAG5ldHdvcmtfaWTD4giHCgYAc3RhdGVzAQcAYWdlX2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:mangrove_propagule", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTZAgAACAQAbmFtZRwAbWluZWNyYWZ0Om1hbmdyb3ZlX3Byb3BhZ3VsZQQJAG5hbWVfaGFzaJGeox6hkfLFAwoAbmV0d29ya19pZAIpvpYKBgBzdGF0ZXMBBwBoYW5naW5nAAMPAHByb3BhZ3VsZV9zdGFnZQAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTZAgAACAQAbmFtZRwAbWluZWNyYWZ0Om1hbmdyb3ZlX3Byb3BhZ3VsZQQJAG5hbWVfaGFzaJGeox6hkfLFAwoAbmV0d29ya19pZAIpvpYKBgBzdGF0ZXMBBwBoYW5naW5nAAMPAHByb3BhZ3VsZV9zdGFnZQAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:cherry_sapling", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQiAwAACAQAbmFtZRgAbWluZWNyYWZ0OmNoZXJyeV9zYXBsaW5nBAkAbmFtZV9oYXNoGrPpNMf1LtcDCgBuZXR3b3JrX2lkypakXQoGAHN0YXRlcwEHAGFnZV9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQiAwAACAQAbmFtZRgAbWluZWNyYWZ0OmNoZXJyeV9zYXBsaW5nBAkAbmFtZV9oYXNoGrPpNMf1LtcDCgBuZXR3b3JrX2lkypakXQoGAHN0YXRlcwEHAGFnZV9iaXQAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:bee_nest", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTZAQAACAQAbmFtZRIAbWluZWNyYWZ0OmJlZV9uZXN0BAkAbmFtZV9oYXNo2R2WBxUHEZIDCgBuZXR3b3JrX2lkiXWLEAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAADCwBob25leV9sZXZlbAAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTZAQAACAQAbmFtZRIAbWluZWNyYWZ0OmJlZV9uZXN0BAkAbmFtZV9oYXNo2R2WBxUHEZIDCgBuZXR3b3JrX2lkiXWLEAoGAHN0YXRlcwMJAGRpcmVjdGlvbgAAAAADCwBob25leV9sZXZlbAAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:wheat_seeds" @@ -2095,7 +2247,7 @@ }, { "id": "minecraft:melon_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRnAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1lbG9uX2Jsb2NrBAkAbmFtZV9oYXNoXxSm0iYpAx8DCgBuZXR3b3JrX2lkC9rqygoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRnAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1lbG9uX2Jsb2NrBAkAbmFtZV9oYXNoXxSm0iYpAx8DCgBuZXR3b3JrX2lkC9rqygoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:melon_slice" @@ -2111,205 +2263,205 @@ }, { "id": "minecraft:pumpkin", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRWAAAACAQAbmFtZREAbWluZWNyYWZ0OnB1bXBraW4ECQBuYW1lX2hhc2gc8A3jaSzWbgMKAG5ldHdvcmtfaWRFGA+xCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRWAAAACAQAbmFtZREAbWluZWNyYWZ0OnB1bXBraW4ECQBuYW1lX2hhc2gc8A3jaSzWbgMKAG5ldHdvcmtfaWRFGA+xCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:carved_pumpkin", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSaAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNhcnZlZF9wdW1wa2luBAkAbmFtZV9oYXNoPu1T0MJuG90DCgBuZXR3b3JrX2lkXNNn5QoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSaAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNhcnZlZF9wdW1wa2luBAkAbmFtZV9oYXNoPu1T0MJuG90DCgBuZXR3b3JrX2lkXNNn5QoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:lit_pumpkin", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRbAAAACAQAbmFtZRUAbWluZWNyYWZ0OmxpdF9wdW1wa2luBAkAbmFtZV9oYXNo7gWtEm2uPL0DCgBuZXR3b3JrX2lki8sU4AoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRbAAAACAQAbmFtZRUAbWluZWNyYWZ0OmxpdF9wdW1wa2luBAkAbmFtZV9oYXNo7gWtEm2uPL0DCgBuZXR3b3JrX2lki8sU4AoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:honeycomb" }, { - "id": "minecraft:tallgrass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQfAAAACAQAbmFtZRMAbWluZWNyYWZ0OnRhbGxncmFzcwQJAG5hbWVfaGFzaC3PXpAXXYswAwoAbmV0d29ya19pZOh33DMKBgBzdGF0ZXMIDwB0YWxsX2dyYXNzX3R5cGUEAGZlcm4AAwcAdmVyc2lvbgRGFAEA" + "id": "minecraft:fern", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRPBAAACAQAbmFtZQ4AbWluZWNyYWZ0OmZlcm4ECQBuYW1lX2hhc2iHbj3yXFn4owMKAG5ldHdvcmtfaWQKC6u7CgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { - "id": "minecraft:double_plant", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZMx1sfgKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQQAZmVybgEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "id": "minecraft:large_fern", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRgBAAACAQAbmFtZRQAbWluZWNyYWZ0OmxhcmdlX2Zlcm4ECQBuYW1lX2hhc2gnE9sd0LzHtQMKAG5ldHdvcmtfaWTS9hG4CgYAc3RhdGVzAQ8AdXBwZXJfYmxvY2tfYml0AAADBwB2ZXJzaW9uAwAVAQA=" }, { - "id": "minecraft:tallgrass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQfAAAACAQAbmFtZRMAbWluZWNyYWZ0OnRhbGxncmFzcwQJAG5hbWVfaGFzaC3PXpAXXYswAwoAbmV0d29ya19pZErptfIKBgBzdGF0ZXMIDwB0YWxsX2dyYXNzX3R5cGUEAHRhbGwAAwcAdmVyc2lvbgRGFAEA" + "id": "minecraft:short_grass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQfAAAACAQAbmFtZRUAbWluZWNyYWZ0OnNob3J0X2dyYXNzBAkAbmFtZV9oYXNobWQghLH0bLcDCgBuZXR3b3JrX2lkJWOOqAoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { - "id": "minecraft:double_plant", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZAbadmIKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQUAZ3Jhc3MBDwB1cHBlcl9ibG9ja19iaXQAAAMHAHZlcnNpb24ERhQBAA==" + "id": "minecraft:tall_grass", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRfBAAACAQAbmFtZRQAbWluZWNyYWZ0OnRhbGxfZ3Jhc3MECQBuYW1lX2hhc2ii5MyZJpv4sgMKAG5ldHdvcmtfaWRRfeH4CgYAc3RhdGVzAQ8AdXBwZXJfYmxvY2tfYml0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:nether_sprouts" }, { "id": "minecraft:fire_coral", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRGAwAACAQAbmFtZRQAbWluZWNyYWZ0OmZpcmVfY29yYWwECQBuYW1lX2hhc2hOHyyECVQVJwMKAG5ldHdvcmtfaWS9vF0UCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRGAwAACAQAbmFtZRQAbWluZWNyYWZ0OmZpcmVfY29yYWwECQBuYW1lX2hhc2hOHyyECVQVJwMKAG5ldHdvcmtfaWS9vF0UCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:brain_coral", - "block_state_b64": "CgAAAwgAYmxvY2tfaWREAwAACAQAbmFtZRUAbWluZWNyYWZ0OmJyYWluX2NvcmFsBAkAbmFtZV9oYXNoRiWlLCwA2ycDCgBuZXR3b3JrX2lkrjAuhgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWREAwAACAQAbmFtZRUAbWluZWNyYWZ0OmJyYWluX2NvcmFsBAkAbmFtZV9oYXNoRiWlLCwA2ycDCgBuZXR3b3JrX2lkrjAuhgoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:bubble_coral", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRFAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJ1YmJsZV9jb3JhbAQJAG5hbWVfaGFzaJz6rWnl+v2qAwoAbmV0d29ya19pZImIWy0KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRFAwAACAQAbmFtZRYAbWluZWNyYWZ0OmJ1YmJsZV9jb3JhbAQJAG5hbWVfaGFzaJz6rWnl+v2qAwoAbmV0d29ya19pZImIWy0KBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:tube_coral", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSCAQAACAQAbmFtZRQAbWluZWNyYWZ0OnR1YmVfY29yYWwECQBuYW1lX2hhc2iYa8oO/tgk7wMKAG5ldHdvcmtfaWRTfND5CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSCAQAACAQAbmFtZRQAbWluZWNyYWZ0OnR1YmVfY29yYWwECQBuYW1lX2hhc2iYa8oO/tgk7wMKAG5ldHdvcmtfaWRTfND5CgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:horn_coral", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRHAwAACAQAbmFtZRQAbWluZWNyYWZ0Omhvcm5fY29yYWwECQBuYW1lX2hhc2iZnRHjZbnLPgMKAG5ldHdvcmtfaWR+GGp8CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRHAwAACAQAbmFtZRQAbWluZWNyYWZ0Omhvcm5fY29yYWwECQBuYW1lX2hhc2iZnRHjZbnLPgMKAG5ldHdvcmtfaWR+GGp8CgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:dead_fire_coral", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRLAwAACAQAbmFtZRkAbWluZWNyYWZ0OmRlYWRfZmlyZV9jb3JhbAQJAG5hbWVfaGFzaEPU6tFy/latAwoAbmV0d29ya19pZNMa7V4KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRLAwAACAQAbmFtZRkAbWluZWNyYWZ0OmRlYWRfZmlyZV9jb3JhbAQJAG5hbWVfaGFzaEPU6tFy/latAwoAbmV0d29ya19pZNMa7V4KBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:dead_brain_coral", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRJAwAACAQAbmFtZRoAbWluZWNyYWZ0OmRlYWRfYnJhaW5fY29yYWwECQBuYW1lX2hhc2j5L6QJCISvzwMKAG5ldHdvcmtfaWQkKzeiCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRJAwAACAQAbmFtZRoAbWluZWNyYWZ0OmRlYWRfYnJhaW5fY29yYWwECQBuYW1lX2hhc2j5L6QJCISvzwMKAG5ldHdvcmtfaWQkKzeiCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:dead_bubble_coral", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRKAwAACAQAbmFtZRsAbWluZWNyYWZ0OmRlYWRfYnViYmxlX2NvcmFsBAkAbmFtZV9oYXNoSTOZ/8wpeNYDCgBuZXR3b3JrX2lka6w9DAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRKAwAACAQAbmFtZRsAbWluZWNyYWZ0OmRlYWRfYnViYmxlX2NvcmFsBAkAbmFtZV9oYXNoSTOZ/8wpeNYDCgBuZXR3b3JrX2lka6w9DAoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:dead_tube_coral", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRIAwAACAQAbmFtZRkAbWluZWNyYWZ0OmRlYWRfdHViZV9jb3JhbAQJAG5hbWVfaGFzaJGjNWhlaIJeAwoAbmV0d29ya19pZO3Z0ygKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRIAwAACAQAbmFtZRkAbWluZWNyYWZ0OmRlYWRfdHViZV9jb3JhbAQJAG5hbWVfaGFzaJGjNWhlaIJeAwoAbmV0d29ya19pZO3Z0ygKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:dead_horn_coral", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRMAwAACAQAbmFtZRkAbWluZWNyYWZ0OmRlYWRfaG9ybl9jb3JhbAQJAG5hbWVfaGFzaJBkz3qt+g2cAwoAbmV0d29ya19pZBAN+eYKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRMAwAACAQAbmFtZRkAbWluZWNyYWZ0OmRlYWRfaG9ybl9jb3JhbAQJAG5hbWVfaGFzaJBkz3qt+g2cAwoAbmV0d29ya19pZBAN+eYKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { - "id": "minecraft:coral_fan", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAQAACAQAbmFtZRMAbWluZWNyYWZ0OmNvcmFsX2ZhbgQJAG5hbWVfaGFzaAFROjbTm8JzAwoAbmV0d29ya19pZOg7iS4KBgBzdGF0ZXMICwBjb3JhbF9jb2xvcgMAcmVkAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "id": "minecraft:fire_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRJBAAACAQAbmFtZRgAbWluZWNyYWZ0OmZpcmVfY29yYWxfZmFuBAkAbmFtZV9oYXNosOTxYYxsDLgDCgBuZXR3b3JrX2lkFKxbEgoGAHN0YXRlcwMTAGNvcmFsX2Zhbl9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { - "id": "minecraft:coral_fan", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAQAACAQAbmFtZRMAbWluZWNyYWZ0OmNvcmFsX2ZhbgQJAG5hbWVfaGFzaAFROjbTm8JzAwoAbmV0d29ya19pZIDj8HMKBgBzdGF0ZXMICwBjb3JhbF9jb2xvcgQAcGluawMTAGNvcmFsX2Zhbl9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "id": "minecraft:brain_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRHBAAACAQAbmFtZRkAbWluZWNyYWZ0OmJyYWluX2NvcmFsX2ZhbgQJAG5hbWVfaGFzaAi5uHizSNcqAwoAbmV0d29ya19pZFtLjNwKBgBzdGF0ZXMDEwBjb3JhbF9mYW5fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { - "id": "minecraft:coral_fan", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAQAACAQAbmFtZRMAbWluZWNyYWZ0OmNvcmFsX2ZhbgQJAG5hbWVfaGFzaAFROjbTm8JzAwoAbmV0d29ya19pZLCJP0kKBgBzdGF0ZXMICwBjb3JhbF9jb2xvcgYAcHVycGxlAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "id": "minecraft:bubble_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRIBAAACAQAbmFtZRoAbWluZWNyYWZ0OmJ1YmJsZV9jb3JhbF9mYW4ECQBuYW1lX2hhc2hy/rX2on17DgMKAG5ldHdvcmtfaWQof60VCgYAc3RhdGVzAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { - "id": "minecraft:coral_fan", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAQAACAQAbmFtZRMAbWluZWNyYWZ0OmNvcmFsX2ZhbgQJAG5hbWVfaGFzaAFROjbTm8JzAwoAbmV0d29ya19pZFz2ly4KBgBzdGF0ZXMICwBjb3JhbF9jb2xvcgQAYmx1ZQMTAGNvcmFsX2Zhbl9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "id": "minecraft:tube_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAQAACAQAbmFtZRgAbWluZWNyYWZ0OnR1YmVfY29yYWxfZmFuBAkAbmFtZV9oYXNo9pbJbo+PphIDCgBuZXR3b3JrX2lkenDTYgoGAHN0YXRlcwMTAGNvcmFsX2Zhbl9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { - "id": "minecraft:coral_fan", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSEAQAACAQAbmFtZRMAbWluZWNyYWZ0OmNvcmFsX2ZhbgQJAG5hbWVfaGFzaAFROjbTm8JzAwoAbmV0d29ya19pZE4TgnYKBgBzdGF0ZXMICwBjb3JhbF9jb2xvcgYAeWVsbG93AxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "id": "minecraft:horn_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRKBAAACAQAbmFtZRgAbWluZWNyYWZ0Omhvcm5fY29yYWxfZmFuBAkAbmFtZV9oYXNoA+ri6NPDkbUDCgBuZXR3b3JrX2lkezoHNwoGAHN0YXRlcwMTAGNvcmFsX2Zhbl9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { - "id": "minecraft:coral_fan_dead", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNvcmFsX2Zhbl9kZWFkBAkAbmFtZV9oYXNo3kgokLV4uQIDCgBuZXR3b3JrX2lkdhLQzwoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yAwByZWQDEwBjb3JhbF9mYW5fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "id": "minecraft:dead_fire_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRNBAAACAQAbmFtZR0AbWluZWNyYWZ0OmRlYWRfZmlyZV9jb3JhbF9mYW4ECQBuYW1lX2hhc2hpQO02NDxPvwMKAG5ldHdvcmtfaWTaOJgLCgYAc3RhdGVzAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { - "id": "minecraft:coral_fan_dead", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNvcmFsX2Zhbl9kZWFkBAkAbmFtZV9oYXNo3kgokLV4uQIDCgBuZXR3b3JrX2lkSi6srQoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABwaW5rAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "id": "minecraft:dead_brain_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRLBAAACAQAbmFtZR4AbWluZWNyYWZ0OmRlYWRfYnJhaW5fY29yYWxfZmFuBAkAbmFtZV9oYXNoI9/+Z4YqMhIDCgBuZXR3b3JrX2lkqYXxYgoGAHN0YXRlcwMTAGNvcmFsX2Zhbl9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { - "id": "minecraft:coral_fan_dead", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNvcmFsX2Zhbl9kZWFkBAkAbmFtZV9oYXNo3kgokLV4uQIDCgBuZXR3b3JrX2lkGiGSzAoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgBwdXJwbGUDEwBjb3JhbF9mYW5fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "id": "minecraft:dead_bubble_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRMBAAACAQAbmFtZR8AbWluZWNyYWZ0OmRlYWRfYnViYmxlX2NvcmFsX2ZhbgQJAG5hbWVfaGFzaBNECtIM6VIOAwoAbmV0d29ya19pZLrNtBEKBgBzdGF0ZXMDEwBjb3JhbF9mYW5fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { - "id": "minecraft:coral_fan_dead", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNvcmFsX2Zhbl9kZWFkBAkAbmFtZV9oYXNo3kgokLV4uQIDCgBuZXR3b3JrX2lkmvZKOgoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABibHVlAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "id": "minecraft:dead_tube_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAQAACAQAbmFtZR0AbWluZWNyYWZ0OmRlYWRfdHViZV9jb3JhbF9mYW4ECQBuYW1lX2hhc2hbBBM9jFKWvQMKAG5ldHdvcmtfaWSkJKUWCgYAc3RhdGVzAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { - "id": "minecraft:coral_fan_dead", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSFAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNvcmFsX2Zhbl9kZWFkBAkAbmFtZV9oYXNo3kgokLV4uQIDCgBuZXR3b3JrX2lknLw+4QoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgB5ZWxsb3cDEwBjb3JhbF9mYW5fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "id": "minecraft:dead_horn_coral_fan", + "block_state_b64": "CgAAAwgAYmxvY2tfaWROBAAACAQAbmFtZR0AbWluZWNyYWZ0OmRlYWRfaG9ybl9jb3JhbF9mYW4ECQBuYW1lX2hhc2hObElFrHfPygMKAG5ldHdvcmtfaWQ1ZxvmCgYAc3RhdGVzAxMAY29yYWxfZmFuX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:crimson_roots", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTeAQAACAQAbmFtZRcAbWluZWNyYWZ0OmNyaW1zb25fcm9vdHMECQBuYW1lX2hhc2j1fWgQLViv5QMKAG5ldHdvcmtfaWRLh5DXCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTeAQAACAQAbmFtZRcAbWluZWNyYWZ0OmNyaW1zb25fcm9vdHMECQBuYW1lX2hhc2j1fWgQLViv5QMKAG5ldHdvcmtfaWRLh5DXCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:warped_roots", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTfAQAACAQAbmFtZRYAbWluZWNyYWZ0OndhcnBlZF9yb290cwQJAG5hbWVfaGFzaBc3WvbJOLlkAwoAbmV0d29ya19pZNLgDnAKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTfAQAACAQAbmFtZRYAbWluZWNyYWZ0OndhcnBlZF9yb290cwQJAG5hbWVfaGFzaBc3WvbJOLlkAwoAbmV0d29ya19pZNLgDnAKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:yellow_flower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQlAAAACAQAbmFtZRcAbWluZWNyYWZ0OnllbGxvd19mbG93ZXIECQBuYW1lX2hhc2jWbU1pF0OUGAMKAG5ldHdvcmtfaWQgO3hpCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQlAAAACAQAbmFtZRcAbWluZWNyYWZ0OnllbGxvd19mbG93ZXIECQBuYW1lX2hhc2jWbU1pF0OUGAMKAG5ldHdvcmtfaWQgO3hpCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { - "id": "minecraft:red_flower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWSqsqQGCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUFAHBvcHB5AAMHAHZlcnNpb24ERhQBAA==" + "id": "minecraft:poppy", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZQ8AbWluZWNyYWZ0OnBvcHB5BAkAbmFtZV9oYXNocMF8pITMbkcDCgBuZXR3b3JrX2lk8im6ywoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { - "id": "minecraft:red_flower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWTqDajjCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUGAG9yY2hpZAADBwB2ZXJzaW9uBEYUAQA=" + "id": "minecraft:blue_orchid", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ9BAAACAQAbmFtZRUAbWluZWNyYWZ0OmJsdWVfb3JjaGlkBAkAbmFtZV9oYXNoBjz2MsgB21EDCgBuZXR3b3JrX2lk/iLsSwoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { - "id": "minecraft:red_flower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWT5CjveCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUGAGFsbGl1bQADBwB2ZXJzaW9uBEYUAQA=" + "id": "minecraft:allium", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ+BAAACAQAbmFtZRAAbWluZWNyYWZ0OmFsbGl1bQQJAG5hbWVfaGFzaDCGQBHNDTkcAwoAbmV0d29ya19pZD9Dgr0KBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { - "id": "minecraft:red_flower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWTORIBJCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUJAGhvdXN0b25pYQADBwB2ZXJzaW9uBEYUAQA=" + "id": "minecraft:azure_bluet", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ/BAAACAQAbmFtZRUAbWluZWNyYWZ0OmF6dXJlX2JsdWV0BAkAbmFtZV9oYXNo9N5egqMT2QcDCgBuZXR3b3JrX2lkwIgDnwoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { - "id": "minecraft:red_flower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWTuNhmYCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUJAHR1bGlwX3JlZAADBwB2ZXJzaW9uBEYUAQA=" + "id": "minecraft:red_tulip", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRABAAACAQAbmFtZRMAbWluZWNyYWZ0OnJlZF90dWxpcAQJAG5hbWVfaGFzaAjMi9Rd+6rhAwoAbmV0d29ya19pZAZCnt8KBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { - "id": "minecraft:red_flower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWT0O4nfCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUMAHR1bGlwX29yYW5nZQADBwB2ZXJzaW9uBEYUAQA=" + "id": "minecraft:orange_tulip", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRBBAAACAQAbmFtZRYAbWluZWNyYWZ0Om9yYW5nZV90dWxpcAQJAG5hbWVfaGFzaP+NjxMBZ8vAAwoAbmV0d29ya19pZPYatsMKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { - "id": "minecraft:red_flower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWTqkthyCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGULAHR1bGlwX3doaXRlAAMHAHZlcnNpb24ERhQBAA==" + "id": "minecraft:white_tulip", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRCBAAACAQAbmFtZRUAbWluZWNyYWZ0OndoaXRlX3R1bGlwBAkAbmFtZV9oYXNo5vbU4VRPh3ADCgBuZXR3b3JrX2lkok+4rQoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { - "id": "minecraft:red_flower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWRMbBA7CgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUKAHR1bGlwX3BpbmsAAwcAdmVyc2lvbgRGFAEA" + "id": "minecraft:pink_tulip", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRDBAAACAQAbmFtZRQAbWluZWNyYWZ0OnBpbmtfdHVsaXAECQBuYW1lX2hhc2hxDHZa6OaNXAMKAG5ldHdvcmtfaWTiOT+VCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { - "id": "minecraft:red_flower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWRexMAuCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUFAG94ZXllAAMHAHZlcnNpb24ERhQBAA==" + "id": "minecraft:oxeye_daisy", + "block_state_b64": "CgAAAwgAYmxvY2tfaWREBAAACAQAbmFtZRUAbWluZWNyYWZ0Om94ZXllX2RhaXN5BAkAbmFtZV9oYXNoXwxsqNQTN9gDCgBuZXR3b3JrX2lkw7R7dwoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { - "id": "minecraft:red_flower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWQgs7BECgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUKAGNvcm5mbG93ZXIAAwcAdmVyc2lvbgRGFAEA" + "id": "minecraft:cornflower", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRFBAAACAQAbmFtZRQAbWluZWNyYWZ0OmNvcm5mbG93ZXIECQBuYW1lX2hhc2gnhyC3EeqHgAMKAG5ldHdvcmtfaWR4VrvACgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { - "id": "minecraft:red_flower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAAAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9mbG93ZXIECQBuYW1lX2hhc2ixeWoRT8FNPwMKAG5ldHdvcmtfaWRvDuNbCgYAc3RhdGVzCAsAZmxvd2VyX3R5cGUSAGxpbHlfb2ZfdGhlX3ZhbGxleQADBwB2ZXJzaW9uBEYUAQA=" + "id": "minecraft:lily_of_the_valley", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRGBAAACAQAbmFtZRwAbWluZWNyYWZ0OmxpbHlfb2ZfdGhlX3ZhbGxleQQJAG5hbWVfaGFzaI64TJSf9mgQAwoAbmV0d29ya19pZFE9+nwKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { - "id": "minecraft:double_plant", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZOemRt4KBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQkAc3VuZmxvd2VyAQ8AdXBwZXJfYmxvY2tfYml0AAADBwB2ZXJzaW9uBEYUAQA=" + "id": "minecraft:sunflower", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRMAbWluZWNyYWZ0OnN1bmZsb3dlcgQJAG5hbWVfaGFzaAMxYQLoqlZ0AwoAbmV0d29ya19pZA10iSoKBgBzdGF0ZXMBDwB1cHBlcl9ibG9ja19iaXQAAAMHAHZlcnNpb24DABUBAA==" }, { - "id": "minecraft:double_plant", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZOFugoEKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQcAc3lyaW5nYQEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "id": "minecraft:lilac", + "block_state_b64": "CgAAAwgAYmxvY2tfaWReBAAACAQAbmFtZQ8AbWluZWNyYWZ0OmxpbGFjBAkAbmFtZV9oYXNoD3nrQJuo7NkDCgBuZXR3b3JrX2lk5W+uFAoGAHN0YXRlcwEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { - "id": "minecraft:double_plant", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZN4O+/gKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQQAcm9zZQEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "id": "minecraft:rose_bush", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhBAAACAQAbmFtZRMAbWluZWNyYWZ0OnJvc2VfYnVzaAQJAG5hbWVfaGFzaLoiFk8LVpGKAwoAbmV0d29ya19pZMZPv48KBgBzdGF0ZXMBDwB1cHBlcl9ibG9ja19iaXQAAAMHAHZlcnNpb24DABUBAA==" }, { - "id": "minecraft:double_plant", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSvAAAACAQAbmFtZRYAbWluZWNyYWZ0OmRvdWJsZV9wbGFudAQJAG5hbWVfaGFzaHVcUQvyXwGKAwoAbmV0d29ya19pZI3w4GMKBgBzdGF0ZXMIEQBkb3VibGVfcGxhbnRfdHlwZQcAcGFlb25pYQEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "id": "minecraft:peony", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRiBAAACAQAbmFtZQ8AbWluZWNyYWZ0OnBlb255BAkAbmFtZV9oYXNoR4dYc4QquPADCgBuZXR3b3JrX2lkrTe7RwoGAHN0YXRlcwEPAHVwcGVyX2Jsb2NrX2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:pitcher_plant", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAwAACAQAbmFtZRcAbWluZWNyYWZ0OnBpdGNoZXJfcGxhbnQECQBuYW1lX2hhc2hRJHzsbDH+SQMKAG5ldHdvcmtfaWRnY76VCgYAc3RhdGVzAQ8AdXBwZXJfYmxvY2tfYml0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAwAACAQAbmFtZRcAbWluZWNyYWZ0OnBpdGNoZXJfcGxhbnQECQBuYW1lX2hhc2hRJHzsbDH+SQMKAG5ldHdvcmtfaWRnY76VCgYAc3RhdGVzAQ8AdXBwZXJfYmxvY2tfYml0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:pink_petals", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQkAwAACAQAbmFtZRUAbWluZWNyYWZ0OnBpbmtfcGV0YWxzBAkAbmFtZV9oYXNo6DQwN9SwV3QDCgBuZXR3b3JrX2lkNWneGgoGAHN0YXRlcwMGAGdyb3d0aAAAAAAIHABtaW5lY3JhZnQ6Y2FyZGluYWxfZGlyZWN0aW9uBQBzb3V0aAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQkAwAACAQAbmFtZRUAbWluZWNyYWZ0OnBpbmtfcGV0YWxzBAkAbmFtZV9oYXNo6DQwN9SwV3QDCgBuZXR3b3JrX2lkNWneGgoGAHN0YXRlcwMGAGdyb3d0aAAAAAAIHABtaW5lY3JhZnQ6Y2FyZGluYWxfZGlyZWN0aW9uBQBzb3V0aAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:wither_rose", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTXAQAACAQAbmFtZRUAbWluZWNyYWZ0OndpdGhlcl9yb3NlBAkAbmFtZV9oYXNoaSKxl3I516gDCgBuZXR3b3JrX2lkATXLPwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTXAQAACAQAbmFtZRUAbWluZWNyYWZ0OndpdGhlcl9yb3NlBAkAbmFtZV9oYXNoaSKxl3I516gDCgBuZXR3b3JrX2lkATXLPwoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:torchflower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ3AwAACAQAbmFtZRUAbWluZWNyYWZ0OnRvcmNoZmxvd2VyBAkAbmFtZV9oYXNoL+mHtElwbqQDCgBuZXR3b3JrX2lkI34O+AoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ3AwAACAQAbmFtZRUAbWluZWNyYWZ0OnRvcmNoZmxvd2VyBAkAbmFtZV9oYXNoL+mHtElwbqQDCgBuZXR3b3JrX2lkI34O+AoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:white_dye" @@ -2376,142 +2528,194 @@ }, { "id": "minecraft:vine", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRqAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnZpbmUECQBuYW1lX2hhc2j0Sj8/XeXOLAMKAG5ldHdvcmtfaWSUkDtbCgYAc3RhdGVzAxMAdmluZV9kaXJlY3Rpb25fYml0cwAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRqAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnZpbmUECQBuYW1lX2hhc2j0Sj8/XeXOLAMKAG5ldHdvcmtfaWSUkDtbCgYAc3RhdGVzAxMAdmluZV9kaXJlY3Rpb25fYml0cwAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:weeping_vines", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTmAQAACAQAbmFtZRcAbWluZWNyYWZ0OndlZXBpbmdfdmluZXMECQBuYW1lX2hhc2jrLgLHkQygiwMKAG5ldHdvcmtfaWQ8NHSJCgYAc3RhdGVzAxEAd2VlcGluZ192aW5lc19hZ2UAAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTmAQAACAQAbmFtZRcAbWluZWNyYWZ0OndlZXBpbmdfdmluZXMECQBuYW1lX2hhc2jrLgLHkQygiwMKAG5ldHdvcmtfaWQ8NHSJCgYAc3RhdGVzAxEAd2VlcGluZ192aW5lc19hZ2UAAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:twisting_vines", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQeAgAACAQAbmFtZRgAbWluZWNyYWZ0OnR3aXN0aW5nX3ZpbmVzBAkAbmFtZV9oYXNoDYR5QgVUQJADCgBuZXR3b3JrX2lk5kYVIQoGAHN0YXRlcwMSAHR3aXN0aW5nX3ZpbmVzX2FnZQAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQeAgAACAQAbmFtZRgAbWluZWNyYWZ0OnR3aXN0aW5nX3ZpbmVzBAkAbmFtZV9oYXNoDYR5QgVUQJADCgBuZXR3b3JrX2lk5kYVIQoGAHN0YXRlcwMSAHR3aXN0aW5nX3ZpbmVzX2FnZQAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:waterlily", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRvAAAACAQAbmFtZRMAbWluZWNyYWZ0OndhdGVybGlseQQJAG5hbWVfaGFzaEHgC4c1SXg0AwoAbmV0d29ya19pZOOerp8KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRvAAAACAQAbmFtZRMAbWluZWNyYWZ0OndhdGVybGlseQQJAG5hbWVfaGFzaEHgC4c1SXg0AwoAbmV0d29ya19pZOOerp8KBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:seagrass", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSBAQAACAQAbmFtZRIAbWluZWNyYWZ0OnNlYWdyYXNzBAkAbmFtZV9oYXNoHSBFtoHdWxIDCgBuZXR3b3JrX2lkd3lhEAoGAHN0YXRlcwgOAHNlYV9ncmFzc190eXBlBwBkZWZhdWx0AAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSBAQAACAQAbmFtZRIAbWluZWNyYWZ0OnNlYWdyYXNzBAkAbmFtZV9oYXNoHSBFtoHdWxIDCgBuZXR3b3JrX2lkd3lhEAoGAHN0YXRlcwgOAHNlYV9ncmFzc190eXBlBwBkZWZhdWx0AAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:kelp" }, { "id": "minecraft:deadbush", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQgAAAACAQAbmFtZRIAbWluZWNyYWZ0OmRlYWRidXNoBAkAbmFtZV9oYXNoPFODe4IScnYDCgBuZXR3b3JrX2lkVfnl+goGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQgAAAACAQAbmFtZRIAbWluZWNyYWZ0OmRlYWRidXNoBAkAbmFtZV9oYXNoPFODe4IScnYDCgBuZXR3b3JrX2lkVfnl+goGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:bamboo", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSiAQAACAQAbmFtZRAAbWluZWNyYWZ0OmJhbWJvbwQJAG5hbWVfaGFzaBgpGmyzhedCAwoAbmV0d29ya19pZIZv1nYKBgBzdGF0ZXMBBwBhZ2VfYml0AAgQAGJhbWJvb19sZWFmX3NpemUJAG5vX2xlYXZlcwgWAGJhbWJvb19zdGFsa190aGlja25lc3MEAHRoaW4AAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSiAQAACAQAbmFtZRAAbWluZWNyYWZ0OmJhbWJvbwQJAG5hbWVfaGFzaBgpGmyzhedCAwoAbmV0d29ya19pZIZv1nYKBgBzdGF0ZXMBBwBhZ2VfYml0AAgQAGJhbWJvb19sZWFmX3NpemUJAG5vX2xlYXZlcwgWAGJhbWJvb19zdGFsa190aGlja25lc3MEAHRoaW4AAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:snow", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRQAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnNub3cECQBuYW1lX2hhc2gVHr5XXdETWAMKAG5ldHdvcmtfaWQ0zCeHCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRQAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnNub3cECQBuYW1lX2hhc2gVHr5XXdETWAMKAG5ldHdvcmtfaWQ0zCeHCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:ice", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRPAAAACAQAbmFtZQ0AbWluZWNyYWZ0OmljZQQJAG5hbWVfaGFzaNF26f+uUT29AwoAbmV0d29ya19pZOUMaQYKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRPAAAACAQAbmFtZQ0AbWluZWNyYWZ0OmljZQQJAG5hbWVfaGFzaNF26f+uUT29AwoAbmV0d29ya19pZOUMaQYKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:packed_ice", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSuAAAACAQAbmFtZRQAbWluZWNyYWZ0OnBhY2tlZF9pY2UECQBuYW1lX2hhc2hk4bu123ZrFgMKAG5ldHdvcmtfaWTr/ooaCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSuAAAACAQAbmFtZRQAbWluZWNyYWZ0OnBhY2tlZF9pY2UECQBuYW1lX2hhc2hk4bu123ZrFgMKAG5ldHdvcmtfaWTr/ooaCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:blue_ice", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQKAQAACAQAbmFtZRIAbWluZWNyYWZ0OmJsdWVfaWNlBAkAbmFtZV9oYXNo+EKxYgFhKcgDCgBuZXR3b3JrX2lkxfsA8goGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQKAQAACAQAbmFtZRIAbWluZWNyYWZ0OmJsdWVfaWNlBAkAbmFtZV9oYXNo+EKxYgFhKcgDCgBuZXR3b3JrX2lkxfsA8goGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:snow_layer", - "block_state_b64": "CgAAAwgAYmxvY2tfaWROAAAACAQAbmFtZRQAbWluZWNyYWZ0OnNub3dfbGF5ZXIECQBuYW1lX2hhc2hXka6atMYUCQMKAG5ldHdvcmtfaWRCrIPcCgYAc3RhdGVzAQsAY292ZXJlZF9iaXQAAwYAaGVpZ2h0AAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWROAAAACAQAbmFtZRQAbWluZWNyYWZ0OnNub3dfbGF5ZXIECQBuYW1lX2hhc2hXka6atMYUCQMKAG5ldHdvcmtfaWRCrIPcCgYAc3RhdGVzAQsAY292ZXJlZF9iaXQAAwYAaGVpZ2h0AAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:pointed_dripstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQzAgAACAQAbmFtZRsAbWluZWNyYWZ0OnBvaW50ZWRfZHJpcHN0b25lBAkAbmFtZV9oYXNoJMISzmHQgt8DCgBuZXR3b3JrX2lkbWrtYgoGAHN0YXRlcwgTAGRyaXBzdG9uZV90aGlja25lc3MDAHRpcAEHAGhhbmdpbmcBAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQzAgAACAQAbmFtZRsAbWluZWNyYWZ0OnBvaW50ZWRfZHJpcHN0b25lBAkAbmFtZV9oYXNoJMISzmHQgt8DCgBuZXR3b3JrX2lkbWrtYgoGAHN0YXRlcwgTAGRyaXBzdG9uZV90aGlja25lc3MDAHRpcAEHAGhhbmdpbmcBAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:dripstone_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ8AgAACAQAbmFtZRkAbWluZWNyYWZ0OmRyaXBzdG9uZV9ibG9jawQJAG5hbWVfaGFzaIIXnEqY77YsAwoAbmV0d29ya19pZMZi2kwKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ8AgAACAQAbmFtZRkAbWluZWNyYWZ0OmRyaXBzdG9uZV9ibG9jawQJAG5hbWVfaGFzaIIXnEqY77YsAwoAbmV0d29ya19pZMZi2kwKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:moss_carpet", - "block_state_b64": "CgAAAwgAYmxvY2tfaWROAgAACAQAbmFtZRUAbWluZWNyYWZ0Om1vc3NfY2FycGV0BAkAbmFtZV9oYXNo/NEDxRPTshYDCgBuZXR3b3JrX2lkaGG3QwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWROAgAACAQAbmFtZRUAbWluZWNyYWZ0Om1vc3NfY2FycGV0BAkAbmFtZV9oYXNo/NEDxRPTshYDCgBuZXR3b3JrX2lkaGG3QwoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:moss_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ/AgAACAQAbmFtZRQAbWluZWNyYWZ0Om1vc3NfYmxvY2sECQBuYW1lX2hhc2iovcsPUYX2tgMKAG5ldHdvcmtfaWT3JSbfCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ/AgAACAQAbmFtZRQAbWluZWNyYWZ0Om1vc3NfYmxvY2sECQBuYW1lX2hhc2iovcsPUYX2tgMKAG5ldHdvcmtfaWT3JSbfCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:dirt_with_roots", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ9AgAACAQAbmFtZRkAbWluZWNyYWZ0OmRpcnRfd2l0aF9yb290cwQJAG5hbWVfaGFzaLCNDYPviDCIAwoAbmV0d29ya19pZNCkwzoKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ9AgAACAQAbmFtZRkAbWluZWNyYWZ0OmRpcnRfd2l0aF9yb290cwQJAG5hbWVfaGFzaLCNDYPviDCIAwoAbmV0d29ya19pZNCkwzoKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:hanging_roots", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ+AgAACAQAbmFtZRcAbWluZWNyYWZ0Omhhbmdpbmdfcm9vdHMECQBuYW1lX2hhc2jaXn+Y5UZpDAMKAG5ldHdvcmtfaWRU4c2vCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ+AgAACAQAbmFtZRcAbWluZWNyYWZ0Omhhbmdpbmdfcm9vdHMECQBuYW1lX2hhc2jaXn+Y5UZpDAMKAG5ldHdvcmtfaWRU4c2vCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:mangrove_roots", - "block_state_b64": "CgAAAwgAYmxvY2tfaWThAgAACAQAbmFtZRgAbWluZWNyYWZ0Om1hbmdyb3ZlX3Jvb3RzBAkAbmFtZV9oYXNoa786PzQGZ6kDCgBuZXR3b3JrX2lklA0AHgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWThAgAACAQAbmFtZRgAbWluZWNyYWZ0Om1hbmdyb3ZlX3Jvb3RzBAkAbmFtZV9oYXNoa786PzQGZ6kDCgBuZXR3b3JrX2lklA0AHgoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:muddy_mangrove_roots", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTiAgAACAQAbmFtZR4AbWluZWNyYWZ0Om11ZGR5X21hbmdyb3ZlX3Jvb3RzBAkAbmFtZV9oYXNo9YApdHpo1RkDCgBuZXR3b3JrX2lkH0Oc4woGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTiAgAACAQAbmFtZR4AbWluZWNyYWZ0Om11ZGR5X21hbmdyb3ZlX3Jvb3RzBAkAbmFtZV9oYXNo9YApdHpo1RkDCgBuZXR3b3JrX2lkH0Oc4woGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:big_dripleaf", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRCAgAACAQAbmFtZRYAbWluZWNyYWZ0OmJpZ19kcmlwbGVhZgQJAG5hbWVfaGFzaGBEhXjo6qSdAwoAbmV0d29ya19pZMETsb8KBgBzdGF0ZXMBEQBiaWdfZHJpcGxlYWZfaGVhZAEIEQBiaWdfZHJpcGxlYWZfdGlsdAQAbm9uZQgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRCAgAACAQAbmFtZRYAbWluZWNyYWZ0OmJpZ19kcmlwbGVhZgQJAG5hbWVfaGFzaGBEhXjo6qSdAwoAbmV0d29ya19pZMETsb8KBgBzdGF0ZXMBEQBiaWdfZHJpcGxlYWZfaGVhZAEIEQBiaWdfZHJpcGxlYWZfdGlsdAQAbm9uZQgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:small_dripleaf_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRPAgAACAQAbmFtZR4AbWluZWNyYWZ0OnNtYWxsX2RyaXBsZWFmX2Jsb2NrBAkAbmFtZV9oYXNojxRAgXP9uWADCgBuZXR3b3JrX2lkozbVPwoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24EAGVhc3QBDwB1cHBlcl9ibG9ja19iaXQBAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRPAgAACAQAbmFtZR4AbWluZWNyYWZ0OnNtYWxsX2RyaXBsZWFmX2Jsb2NrBAkAbmFtZV9oYXNojxRAgXP9uWADCgBuZXR3b3JrX2lkozbVPwoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24EAGVhc3QBDwB1cHBlcl9ibG9ja19iaXQBAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:spore_blossom", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRAAgAACAQAbmFtZRcAbWluZWNyYWZ0OnNwb3JlX2Jsb3Nzb20ECQBuYW1lX2hhc2il3U72Gbco2gMKAG5ldHdvcmtfaWSbbbgcCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRAAgAACAQAbmFtZRcAbWluZWNyYWZ0OnNwb3JlX2Jsb3Nzb20ECQBuYW1lX2hhc2il3U72Gbco2gMKAG5ldHdvcmtfaWSbbbgcCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:azalea", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRQAgAACAQAbmFtZRAAbWluZWNyYWZ0OmF6YWxlYQQJAG5hbWVfaGFzaNyUl+BW9JrBAwoAbmV0d29ya19pZO/XZtQKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRQAgAACAQAbmFtZRAAbWluZWNyYWZ0OmF6YWxlYQQJAG5hbWVfaGFzaNyUl+BW9JrBAwoAbmV0d29ya19pZO/XZtQKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:flowering_azalea", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRRAgAACAQAbmFtZRoAbWluZWNyYWZ0OmZsb3dlcmluZ19hemFsZWEECQBuYW1lX2hhc2ie9r33wz8kiwMKAG5ldHdvcmtfaWQ3ij0VCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRRAgAACAQAbmFtZRoAbWluZWNyYWZ0OmZsb3dlcmluZ19hemFsZWEECQBuYW1lX2hhc2ie9r33wz8kiwMKAG5ldHdvcmtfaWQ3ij0VCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:glow_lichen", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSaAgAACAQAbmFtZRUAbWluZWNyYWZ0Omdsb3dfbGljaGVuBAkAbmFtZV9oYXNobyPUrIYlo44DCgBuZXR3b3JrX2lkCh8lSAoGAHN0YXRlcwMZAG11bHRpX2ZhY2VfZGlyZWN0aW9uX2JpdHM/AAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSaAgAACAQAbmFtZRUAbWluZWNyYWZ0Omdsb3dfbGljaGVuBAkAbmFtZV9oYXNobyPUrIYlo44DCgBuZXR3b3JrX2lkCh8lSAoGAHN0YXRlcwMZAG11bHRpX2ZhY2VfZGlyZWN0aW9uX2JpdHM/AAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:amethyst_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRGAgAACAQAbmFtZRgAbWluZWNyYWZ0OmFtZXRoeXN0X2Jsb2NrBAkAbmFtZV9oYXNob+JK1iiAthcDCgBuZXR3b3JrX2lk8HtpzgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRGAgAACAQAbmFtZRgAbWluZWNyYWZ0OmFtZXRoeXN0X2Jsb2NrBAkAbmFtZV9oYXNob+JK1iiAthcDCgBuZXR3b3JrX2lk8HtpzgoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:budding_amethyst", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRHAgAACAQAbmFtZRoAbWluZWNyYWZ0OmJ1ZGRpbmdfYW1ldGh5c3QECQBuYW1lX2hhc2gJvAwfI14fxgMKAG5ldHdvcmtfaWTQYqfACgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRHAgAACAQAbmFtZRoAbWluZWNyYWZ0OmJ1ZGRpbmdfYW1ldGh5c3QECQBuYW1lX2hhc2gJvAwfI14fxgMKAG5ldHdvcmtfaWTQYqfACgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:amethyst_cluster", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRIAgAACAQAbmFtZRoAbWluZWNyYWZ0OmFtZXRoeXN0X2NsdXN0ZXIECQBuYW1lX2hhc2jK82S88Jgm8wMKAG5ldHdvcmtfaWSCPMPGCgYAc3RhdGVzCBQAbWluZWNyYWZ0OmJsb2NrX2ZhY2UCAHVwAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRIAgAACAQAbmFtZRoAbWluZWNyYWZ0OmFtZXRoeXN0X2NsdXN0ZXIECQBuYW1lX2hhc2jK82S88Jgm8wMKAG5ldHdvcmtfaWSCPMPGCgYAc3RhdGVzCBQAbWluZWNyYWZ0OmJsb2NrX2ZhY2UCAHVwAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:large_amethyst_bud", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRJAgAACAQAbmFtZRwAbWluZWNyYWZ0OmxhcmdlX2FtZXRoeXN0X2J1ZAQJAG5hbWVfaGFzaAHhdpWD+sd5AwoAbmV0d29ya19pZKkQxOcKBgBzdGF0ZXMIFABtaW5lY3JhZnQ6YmxvY2tfZmFjZQIAdXAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRJAgAACAQAbmFtZRwAbWluZWNyYWZ0OmxhcmdlX2FtZXRoeXN0X2J1ZAQJAG5hbWVfaGFzaAHhdpWD+sd5AwoAbmV0d29ya19pZKkQxOcKBgBzdGF0ZXMIFABtaW5lY3JhZnQ6YmxvY2tfZmFjZQIAdXAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:medium_amethyst_bud", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRKAgAACAQAbmFtZR0AbWluZWNyYWZ0Om1lZGl1bV9hbWV0aHlzdF9idWQECQBuYW1lX2hhc2g5lBGtC0DzZQMKAG5ldHdvcmtfaWSYiP4gCgYAc3RhdGVzCBQAbWluZWNyYWZ0OmJsb2NrX2ZhY2UCAHVwAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRKAgAACAQAbmFtZR0AbWluZWNyYWZ0Om1lZGl1bV9hbWV0aHlzdF9idWQECQBuYW1lX2hhc2g5lBGtC0DzZQMKAG5ldHdvcmtfaWSYiP4gCgYAc3RhdGVzCBQAbWluZWNyYWZ0OmJsb2NrX2ZhY2UCAHVwAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:small_amethyst_bud", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRLAgAACAQAbmFtZRwAbWluZWNyYWZ0OnNtYWxsX2FtZXRoeXN0X2J1ZAQJAG5hbWVfaGFzaEnb4+q9PO4YAwoAbmV0d29ya19pZGWzxrQKBgBzdGF0ZXMIFABtaW5lY3JhZnQ6YmxvY2tfZmFjZQIAdXAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRLAgAACAQAbmFtZRwAbWluZWNyYWZ0OnNtYWxsX2FtZXRoeXN0X2J1ZAQJAG5hbWVfaGFzaEnb4+q9PO4YAwoAbmV0d29ya19pZGWzxrQKBgBzdGF0ZXMIFABtaW5lY3JhZnQ6YmxvY2tfZmFjZQIAdXAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:tuff", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRMAgAACAQAbmFtZQ4AbWluZWNyYWZ0OnR1ZmYECQBuYW1lX2hhc2h1Rwc1XYsBGwMKAG5ldHdvcmtfaWRwQGn0CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRMAgAACAQAbmFtZQ4AbWluZWNyYWZ0OnR1ZmYECQBuYW1lX2hhc2h1Rwc1XYsBGwMKAG5ldHdvcmtfaWRwQGn0CgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" + }, + { + "id": "minecraft:tuff_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTpAwAACAQAbmFtZRUAbWluZWNyYWZ0OnR1ZmZfc3RhaXJzBAkAbmFtZV9oYXNoKjyNUBjcfZsDCgBuZXR3b3JrX2lk+LsycgoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" + }, + { + "id": "minecraft:tuff_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTnAwAACAQAbmFtZRMAbWluZWNyYWZ0OnR1ZmZfc2xhYgQJAG5hbWVfaGFzaIhCGdlIsnMUAwoAbmV0d29ya19pZN1dUL4KBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DABUBAA==" + }, + { + "id": "minecraft:tuff_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTqAwAACAQAbmFtZRMAbWluZWNyYWZ0OnR1ZmZfd2FsbAQJAG5hbWVfaGFzaMyeeu1IRf03AwoAbmV0d29ya19pZDkIrosKBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uAwAVAQA=" + }, + { + "id": "minecraft:chiseled_tuff", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTwAwAACAQAbmFtZRcAbWluZWNyYWZ0OmNoaXNlbGVkX3R1ZmYECQBuYW1lX2hhc2iVliOT8OTQ9AMKAG5ldHdvcmtfaWTLNKOiCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" + }, + { + "id": "minecraft:polished_tuff", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTrAwAACAQAbmFtZRcAbWluZWNyYWZ0OnBvbGlzaGVkX3R1ZmYECQBuYW1lX2hhc2hyaLe/KEVZ0gMKAG5ldHdvcmtfaWTcX3NrCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" + }, + { + "id": "minecraft:polished_tuff_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTuAwAACAQAbmFtZR4AbWluZWNyYWZ0OnBvbGlzaGVkX3R1ZmZfc3RhaXJzBAkAbmFtZV9oYXNo8yuah8QI1dcDCgBuZXR3b3JrX2lkjLoU4AoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" + }, + { + "id": "minecraft:polished_tuff_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTsAwAACAQAbmFtZRwAbWluZWNyYWZ0OnBvbGlzaGVkX3R1ZmZfc2xhYgQJAG5hbWVfaGFzaLXdb48YvAsHAwoAbmV0d29ya19pZAnJ7W0KBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DABUBAA==" + }, + { + "id": "minecraft:polished_tuff_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTvAwAACAQAbmFtZRwAbWluZWNyYWZ0OnBvbGlzaGVkX3R1ZmZfd2FsbAQJAG5hbWVfaGFzaJVZj6QYWXUrAwoAbmV0d29ya19pZLU7dooKBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uAwAVAQA=" + }, + { + "id": "minecraft:tuff_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTxAwAACAQAbmFtZRUAbWluZWNyYWZ0OnR1ZmZfYnJpY2tzBAkAbmFtZV9oYXNo/hbQ+mXSK7wDCgBuZXR3b3JrX2lk6gmIwQoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" + }, + { + "id": "minecraft:tuff_brick_stairs", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT0AwAACAQAbmFtZRsAbWluZWNyYWZ0OnR1ZmZfYnJpY2tfc3RhaXJzBAkAbmFtZV9oYXNoWJpkAurUfKwDCgBuZXR3b3JrX2lkUMcjiwoGAHN0YXRlcwEPAHVwc2lkZV9kb3duX2JpdAADEAB3ZWlyZG9fZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" + }, + { + "id": "minecraft:tuff_brick_slab", + "block_state_b64": "CgAAAwgAYmxvY2tfaWTyAwAACAQAbmFtZRkAbWluZWNyYWZ0OnR1ZmZfYnJpY2tfc2xhYgQJAG5hbWVfaGFzaLqPMjVCv5dIAwoAbmV0d29ya19pZOmeRhcKBgBzdGF0ZXMIFwBtaW5lY3JhZnQ6dmVydGljYWxfaGFsZgYAYm90dG9tAAMHAHZlcnNpb24DABUBAA==" + }, + { + "id": "minecraft:tuff_brick_wall", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT1AwAACAQAbmFtZRkAbWluZWNyYWZ0OnR1ZmZfYnJpY2tfd2FsbAQJAG5hbWVfaGFzaIL0IyNCOsonAwoAbmV0d29ya19pZJW4T5UKBgBzdGF0ZXMIGQB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9lYXN0BABub25lCBoAd2FsbF9jb25uZWN0aW9uX3R5cGVfbm9ydGgEAG5vbmUIGgB3YWxsX2Nvbm5lY3Rpb25fdHlwZV9zb3V0aAQAbm9uZQgZAHdhbGxfY29ubmVjdGlvbl90eXBlX3dlc3QEAG5vbmUBDQB3YWxsX3Bvc3RfYml0AAADBwB2ZXJzaW9uAwAVAQA=" + }, + { + "id": "minecraft:chiseled_tuff_bricks", + "block_state_b64": "CgAAAwgAYmxvY2tfaWT2AwAACAQAbmFtZR4AbWluZWNyYWZ0OmNoaXNlbGVkX3R1ZmZfYnJpY2tzBAkAbmFtZV9oYXNo3oQw6gmxYuADCgBuZXR3b3JrX2lkm3D8AgoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:calcite", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRFAgAACAQAbmFtZREAbWluZWNyYWZ0OmNhbGNpdGUECQBuYW1lX2hhc2ixKLu8ZIdzDQMKAG5ldHdvcmtfaWQlSbJDCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRFAgAACAQAbmFtZREAbWluZWNyYWZ0OmNhbGNpdGUECQBuYW1lX2hhc2ixKLu8ZIdzDQMKAG5ldHdvcmtfaWQlSbJDCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:chicken" @@ -2542,35 +2746,35 @@ }, { "id": "minecraft:brown_mushroom", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQnAAAACAQAbmFtZRgAbWluZWNyYWZ0OmJyb3duX211c2hyb29tBAkAbmFtZV9oYXNonYw/FO78WDoDCgBuZXR3b3JrX2lkLh1OXAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQnAAAACAQAbmFtZRgAbWluZWNyYWZ0OmJyb3duX211c2hyb29tBAkAbmFtZV9oYXNonYw/FO78WDoDCgBuZXR3b3JrX2lkLh1OXAoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:red_mushroom", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQoAAAACAQAbmFtZRYAbWluZWNyYWZ0OnJlZF9tdXNocm9vbQQJAG5hbWVfaGFzaPpzJua7669xAwoAbmV0d29ya19pZCvWPYkKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQoAAAACAQAbmFtZRYAbWluZWNyYWZ0OnJlZF9tdXNocm9vbQQJAG5hbWVfaGFzaPpzJua7669xAwoAbmV0d29ya19pZCvWPYkKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:crimson_fungus", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTjAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fZnVuZ3VzBAkAbmFtZV9oYXNolIcCUuFM2u0DCgBuZXR3b3JrX2lkD2NN0QoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTjAQAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fZnVuZ3VzBAkAbmFtZV9oYXNolIcCUuFM2u0DCgBuZXR3b3JrX2lkD2NN0QoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:warped_fungus", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTkAQAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9mdW5ndXMECQBuYW1lX2hhc2gq8bSnRVTAFgMKAG5ldHdvcmtfaWTkwS+rCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTkAQAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9mdW5ndXMECQBuYW1lX2hhc2gq8bSnRVTAFgMKAG5ldHdvcmtfaWTkwS+rCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:brown_mushroom_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAAAACAQAbmFtZR4AbWluZWNyYWZ0OmJyb3duX211c2hyb29tX2Jsb2NrBAkAbmFtZV9oYXNoIyjnbI6xy9sDCgBuZXR3b3JrX2lkdOMhDAoGAHN0YXRlcwMSAGh1Z2VfbXVzaHJvb21fYml0cw4AAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAAAACAQAbmFtZR4AbWluZWNyYWZ0OmJyb3duX211c2hyb29tX2Jsb2NrBAkAbmFtZV9oYXNoIyjnbI6xy9sDCgBuZXR3b3JrX2lkdOMhDAoGAHN0YXRlcwMSAGh1Z2VfbXVzaHJvb21fYml0cw4AAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:red_mushroom_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRkAAAACAQAbmFtZRwAbWluZWNyYWZ0OnJlZF9tdXNocm9vbV9ibG9jawQJAG5hbWVfaGFzaJTTyJbth9M9AwoAbmV0d29ya19pZM+AyboKBgBzdGF0ZXMDEgBodWdlX211c2hyb29tX2JpdHMOAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRkAAAACAQAbmFtZRwAbWluZWNyYWZ0OnJlZF9tdXNocm9vbV9ibG9jawQJAG5hbWVfaGFzaJTTyJbth9M9AwoAbmV0d29ya19pZM+AyboKBgBzdGF0ZXMDEgBodWdlX211c2hyb29tX2JpdHMOAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:brown_mushroom_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAAAACAQAbmFtZR4AbWluZWNyYWZ0OmJyb3duX211c2hyb29tX2Jsb2NrBAkAbmFtZV9oYXNoIyjnbI6xy9sDCgBuZXR3b3JrX2lkbdt3CAoGAHN0YXRlcwMSAGh1Z2VfbXVzaHJvb21fYml0cw8AAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAAAACAQAbmFtZR4AbWluZWNyYWZ0OmJyb3duX211c2hyb29tX2Jsb2NrBAkAbmFtZV9oYXNoIyjnbI6xy9sDCgBuZXR3b3JrX2lkbdt3CAoGAHN0YXRlcwMSAGh1Z2VfbXVzaHJvb21fYml0cw8AAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:brown_mushroom_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAAAACAQAbmFtZR4AbWluZWNyYWZ0OmJyb3duX211c2hyb29tX2Jsb2NrBAkAbmFtZV9oYXNoIyjnbI6xy9sDCgBuZXR3b3JrX2lkSrMl9goGAHN0YXRlcwMSAGh1Z2VfbXVzaHJvb21fYml0cwAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRjAAAACAQAbmFtZR4AbWluZWNyYWZ0OmJyb3duX211c2hyb29tX2Jsb2NrBAkAbmFtZV9oYXNoIyjnbI6xy9sDCgBuZXR3b3JrX2lkSrMl9goGAHN0YXRlcwMSAGh1Z2VfbXVzaHJvb21fYml0cwAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:egg" @@ -2589,74 +2793,82 @@ }, { "id": "minecraft:web", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQeAAAACAQAbmFtZQ0AbWluZWNyYWZ0OndlYgQJAG5hbWVfaGFzaA4GKQCvG4i9AwoAbmV0d29ya19pZApt+jgKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQeAAAACAQAbmFtZQ0AbWluZWNyYWZ0OndlYgQJAG5hbWVfaGFzaA4GKQCvG4i9AwoAbmV0d29ya19pZApt+jgKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:spider_eye" }, { "id": "minecraft:mob_spawner", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ0AAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vYl9zcGF3bmVyBAkAbmFtZV9oYXNoNwGrCV/Fkh8DCgBuZXR3b3JrX2lkM1wTmgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ0AAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vYl9zcGF3bmVyBAkAbmFtZV9oYXNoNwGrCV/Fkh8DCgBuZXR3b3JrX2lkM1wTmgoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" + }, + { + "id": "minecraft:trial_spawner", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ6AgAACAQAbmFtZRcAbWluZWNyYWZ0OnRyaWFsX3NwYXduZXIECQBuYW1lX2hhc2iNLRPB4ACz+QMKAG5ldHdvcmtfaWTWFYHGCgYAc3RhdGVzAQcAb21pbm91cwADEwB0cmlhbF9zcGF3bmVyX3N0YXRlAAAAAAADBwB2ZXJzaW9uAwAVAQA=" + }, + { + "id": "minecraft:vault", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ5AgAACAQAbmFtZQ8AbWluZWNyYWZ0OnZhdWx0BAkAbmFtZV9oYXNoCAp9n3IAyqcDCgBuZXR3b3JrX2lk6/P+vwoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAQcAb21pbm91cwAICwB2YXVsdF9zdGF0ZQgAaW5hY3RpdmUAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:end_portal_frame", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR4AAAACAQAbmFtZRoAbWluZWNyYWZ0OmVuZF9wb3J0YWxfZnJhbWUECQBuYW1lX2hhc2gqofyUIjGOpQMKAG5ldHdvcmtfaWRbGHf8CgYAc3RhdGVzARIAZW5kX3BvcnRhbF9leWVfYml0AAgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWR4AAAACAQAbmFtZRoAbWluZWNyYWZ0OmVuZF9wb3J0YWxfZnJhbWUECQBuYW1lX2hhc2gqofyUIjGOpQMKAG5ldHdvcmtfaWRbGHf8CgYAc3RhdGVzARIAZW5kX3BvcnRhbF9leWVfYml0AAgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:monster_egg", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkqXH7RgoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGUFAHN0b25lAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkqXH7RgoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGUFAHN0b25lAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:monster_egg", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkeIBb6QoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGULAGNvYmJsZXN0b25lAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkeIBb6QoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGULAGNvYmJsZXN0b25lAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:monster_egg", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkDZ2cFQoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGULAHN0b25lX2JyaWNrAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkDZ2cFQoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGULAHN0b25lX2JyaWNrAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:monster_egg", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkOR/cTAoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGURAG1vc3N5X3N0b25lX2JyaWNrAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkOR/cTAoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGURAG1vc3N5X3N0b25lX2JyaWNrAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:monster_egg", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkqdwlHAoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGUTAGNyYWNrZWRfc3RvbmVfYnJpY2sAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkqdwlHAoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGUTAGNyYWNrZWRfc3RvbmVfYnJpY2sAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:monster_egg", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkFqqPggoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGUUAGNoaXNlbGVkX3N0b25lX2JyaWNrAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRhAAAACAQAbmFtZRUAbWluZWNyYWZ0Om1vbnN0ZXJfZWdnBAkAbmFtZV9oYXNoFMxMALksxVEDCgBuZXR3b3JrX2lkFqqPggoGAHN0YXRlcwgWAG1vbnN0ZXJfZWdnX3N0b25lX3R5cGUUAGNoaXNlbGVkX3N0b25lX2JyaWNrAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:infested_deepslate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTFAgAACAQAbmFtZRwAbWluZWNyYWZ0OmluZmVzdGVkX2RlZXBzbGF0ZQQJAG5hbWVfaGFzaICF2VYccxF1AwoAbmV0d29ya19pZDa/624KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTFAgAACAQAbmFtZRwAbWluZWNyYWZ0OmluZmVzdGVkX2RlZXBzbGF0ZQQJAG5hbWVfaGFzaICF2VYccxF1AwoAbmV0d29ya19pZDa/624KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:dragon_egg", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR6AAAACAQAbmFtZRQAbWluZWNyYWZ0OmRyYWdvbl9lZ2cECQBuYW1lX2hhc2inMzXrV+/e1wMKAG5ldHdvcmtfaWTgO1yRCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWR6AAAACAQAbmFtZRQAbWluZWNyYWZ0OmRyYWdvbl9lZ2cECQBuYW1lX2hhc2inMzXrV+/e1wMKAG5ldHdvcmtfaWTgO1yRCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:turtle_egg", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSeAQAACAQAbmFtZRQAbWluZWNyYWZ0OnR1cnRsZV9lZ2cECQBuYW1lX2hhc2iwSRcxOJIJ9gMKAG5ldHdvcmtfaWSIRNUhCgYAc3RhdGVzCA0AY3JhY2tlZF9zdGF0ZQkAbm9fY3JhY2tzCBAAdHVydGxlX2VnZ19jb3VudAcAb25lX2VnZwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSeAQAACAQAbmFtZRQAbWluZWNyYWZ0OnR1cnRsZV9lZ2cECQBuYW1lX2hhc2iwSRcxOJIJ9gMKAG5ldHdvcmtfaWSIRNUhCgYAc3RhdGVzCA0AY3JhY2tlZF9zdGF0ZQkAbm9fY3JhY2tzCBAAdHVydGxlX2VnZ19jb3VudAcAb25lX2VnZwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:sniffer_egg", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRTAwAACAQAbmFtZRUAbWluZWNyYWZ0OnNuaWZmZXJfZWdnBAkAbmFtZV9oYXNoY1lozc8lPcYDCgBuZXR3b3JrX2lk7yb/2QoGAHN0YXRlcwgNAGNyYWNrZWRfc3RhdGUJAG5vX2NyYWNrcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRTAwAACAQAbmFtZRUAbWluZWNyYWZ0OnNuaWZmZXJfZWdnBAkAbmFtZV9oYXNoY1lozc8lPcYDCgBuZXR3b3JrX2lk7yb/2QoGAHN0YXRlcwgNAGNyYWNrZWRfc3RhdGUJAG5vX2NyYWNrcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:frog_spawn", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAgAACAQAbmFtZRQAbWluZWNyYWZ0OmZyb2dfc3Bhd24ECQBuYW1lX2hhc2iWmd7idp3ZZwMKAG5ldHdvcmtfaWRFzJudCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTTAgAACAQAbmFtZRQAbWluZWNyYWZ0OmZyb2dfc3Bhd24ECQBuYW1lX2hhc2iWmd7idp3ZZwMKAG5ldHdvcmtfaWRFzJudCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:pearlescent_froglight", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTUAgAACAQAbmFtZR8AbWluZWNyYWZ0OnBlYXJsZXNjZW50X2Zyb2dsaWdodAQJAG5hbWVfaGFzaKkcFRyycYGyAwoAbmV0d29ya19pZJqYakAKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTUAgAACAQAbmFtZR8AbWluZWNyYWZ0OnBlYXJsZXNjZW50X2Zyb2dsaWdodAQJAG5hbWVfaGFzaKkcFRyycYGyAwoAbmV0d29ya19pZJqYakAKBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:verdant_froglight", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTVAgAACAQAbmFtZRsAbWluZWNyYWZ0OnZlcmRhbnRfZnJvZ2xpZ2h0BAkAbmFtZV9oYXNoA+eXuTBohrQDCgBuZXR3b3JrX2lkDIVnsQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTVAgAACAQAbmFtZRsAbWluZWNyYWZ0OnZlcmRhbnRfZnJvZ2xpZ2h0BAkAbmFtZV9oYXNoA+eXuTBohrQDCgBuZXR3b3JrX2lkDIVnsQoGAHN0YXRlcwgLAHBpbGxhcl9heGlzAQB5AAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:ochre_froglight", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTWAgAACAQAbmFtZRkAbWluZWNyYWZ0Om9jaHJlX2Zyb2dsaWdodAQJAG5hbWVfaGFzaMY59kjPe+c3AwoAbmV0d29ya19pZO2TD50KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTWAgAACAQAbmFtZRkAbWluZWNyYWZ0Om9jaHJlX2Zyb2dsaWdodAQJAG5hbWVfaGFzaMY59kjPe+c3AwoAbmV0d29ya19pZO2TD50KBgBzdGF0ZXMICwBwaWxsYXJfYXhpcwEAeQADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:chicken_spawn_egg" @@ -2883,40 +3095,49 @@ { "id": "minecraft:sniffer_spawn_egg" }, + { + "id": "minecraft:breeze_spawn_egg" + }, + { + "id": "minecraft:armadillo_spawn_egg" + }, + { + "id": "minecraft:bogged_spawn_egg" + }, { "id": "minecraft:obsidian", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQxAAAACAQAbmFtZRIAbWluZWNyYWZ0Om9ic2lkaWFuBAkAbmFtZV9oYXNoiz4qrb8QjyEDCgBuZXR3b3JrX2lkuqnPpQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQxAAAACAQAbmFtZRIAbWluZWNyYWZ0Om9ic2lkaWFuBAkAbmFtZV9oYXNoiz4qrb8QjyEDCgBuZXR3b3JrX2lkuqnPpQoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:crying_obsidian", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQgAgAACAQAbmFtZRkAbWluZWNyYWZ0OmNyeWluZ19vYnNpZGlhbgQJAG5hbWVfaGFzaKT0JlA7Z1K+AwoAbmV0d29ya19pZCjbPV4KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQgAgAACAQAbmFtZRkAbWluZWNyYWZ0OmNyeWluZ19vYnNpZGlhbgQJAG5hbWVfaGFzaKT0JlA7Z1K+AwoAbmV0d29ya19pZCjbPV4KBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:bedrock", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQHAAAACAQAbmFtZREAbWluZWNyYWZ0OmJlZHJvY2sECQBuYW1lX2hhc2hWfFrh4LVtxwMKAG5ldHdvcmtfaWT7fKz1CgYAc3RhdGVzAQ4AaW5maW5pYnVybl9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQHAAAACAQAbmFtZREAbWluZWNyYWZ0OmJlZHJvY2sECQBuYW1lX2hhc2hWfFrh4LVtxwMKAG5ldHdvcmtfaWT7fKz1CgYAc3RhdGVzAQ4AaW5maW5pYnVybl9iaXQAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:soul_sand", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNvdWxfc2FuZAQJAG5hbWVfaGFzaMaf+bccu+KTAwoAbmV0d29ya19pZBQSHrMKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRYAAAACAQAbmFtZRMAbWluZWNyYWZ0OnNvdWxfc2FuZAQJAG5hbWVfaGFzaMaf+bccu+KTAwoAbmV0d29ya19pZBQSHrMKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:magma", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTVAAAACAQAbmFtZQ8AbWluZWNyYWZ0Om1hZ21hBAkAbmFtZV9oYXNoqyTjKaIsWfYDCgBuZXR3b3JrX2lkyfWAZgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTVAAAACAQAbmFtZQ8AbWluZWNyYWZ0Om1hZ21hBAkAbmFtZV9oYXNoqyTjKaIsWfYDCgBuZXR3b3JrX2lkyfWAZgoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:nether_wart" }, { "id": "minecraft:end_stone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR5AAAACAQAbmFtZRMAbWluZWNyYWZ0OmVuZF9zdG9uZQQJAG5hbWVfaGFzaH1J9jA39GJNAwoAbmV0d29ya19pZFeFQ7UKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWR5AAAACAQAbmFtZRMAbWluZWNyYWZ0OmVuZF9zdG9uZQQJAG5hbWVfaGFzaH1J9jA39GJNAwoAbmV0d29ya19pZFeFQ7UKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:chorus_flower", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTIAAAACAQAbmFtZRcAbWluZWNyYWZ0OmNob3J1c19mbG93ZXIECQBuYW1lX2hhc2iMpSodli5uawMKAG5ldHdvcmtfaWRnd1ZWCgYAc3RhdGVzAwMAYWdlAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTIAAAACAQAbmFtZRcAbWluZWNyYWZ0OmNob3J1c19mbG93ZXIECQBuYW1lX2hhc2iMpSodli5uawMKAG5ldHdvcmtfaWRnd1ZWCgYAc3RhdGVzAwMAYWdlAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:chorus_plant", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTwAAAACAQAbmFtZRYAbWluZWNyYWZ0OmNob3J1c19wbGFudAQJAG5hbWVfaGFzaJhSrmNGKwaMAwoAbmV0d29ya19pZA3uVqMKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTwAAAACAQAbmFtZRYAbWluZWNyYWZ0OmNob3J1c19wbGFudAQJAG5hbWVfaGFzaJhSrmNGKwaMAwoAbmV0d29ya19pZA3uVqMKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:chorus_fruit" @@ -2926,79 +3147,79 @@ }, { "id": "minecraft:sponge", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQTAAAACAQAbmFtZRAAbWluZWNyYWZ0OnNwb25nZQQJAG5hbWVfaGFzaLrd2ScYRDMiAwoAbmV0d29ya19pZF01rO0KBgBzdGF0ZXMICwBzcG9uZ2VfdHlwZQMAZHJ5AAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQTAAAACAQAbmFtZRAAbWluZWNyYWZ0OnNwb25nZQQJAG5hbWVfaGFzaLrd2ScYRDMiAwoAbmV0d29ya19pZF01rO0KBgBzdGF0ZXMICwBzcG9uZ2VfdHlwZQMAZHJ5AAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:sponge", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQTAAAACAQAbmFtZRAAbWluZWNyYWZ0OnNwb25nZQQJAG5hbWVfaGFzaLrd2ScYRDMiAwoAbmV0d29ya19pZPiOc4QKBgBzdGF0ZXMICwBzcG9uZ2VfdHlwZQMAd2V0AAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQTAAAACAQAbmFtZRAAbWluZWNyYWZ0OnNwb25nZQQJAG5hbWVfaGFzaLrd2ScYRDMiAwoAbmV0d29ya19pZPiOc4QKBgBzdGF0ZXMICwBzcG9uZ2VfdHlwZQMAd2V0AAMHAHZlcnNpb24DABUBAA==" }, { - "id": "minecraft:coral_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkGnlaAwoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABibHVlAQgAZGVhZF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + "id": "minecraft:tube_coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRoAbWluZWNyYWZ0OnR1YmVfY29yYWxfYmxvY2sECQBuYW1lX2hhc2iGkaiR7Eot4wMKAG5ldHdvcmtfaWQPNJ6sCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { - "id": "minecraft:coral_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkSnHuagoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABwaW5rAQgAZGVhZF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + "id": "minecraft:brain_coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRQBAAACAQAbmFtZRsAbWluZWNyYWZ0OmJyYWluX2NvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoeDNAK18yUo4DCgBuZXR3b3JrX2lkloN1vgoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { - "id": "minecraft:coral_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkmkHyegoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgBwdXJwbGUBCABkZWFkX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "id": "minecraft:bubble_coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRRBAAACAQAbmFtZRwAbWluZWNyYWZ0OmJ1YmJsZV9jb3JhbF9ibG9jawQJAG5hbWVfaGFzaAI2mwMlvcNbAwoAbmV0d29ya19pZBlkxKIKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { - "id": "minecraft:coral_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkdpUDxgoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yAwByZWQBCABkZWFkX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "id": "minecraft:fire_coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRSBAAACAQAbmFtZRoAbWluZWNyYWZ0OmZpcmVfY29yYWxfYmxvY2sECQBuYW1lX2hhc2gg1gLeXLmKaAMKAG5ldHdvcmtfaWSp3W57CgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { - "id": "minecraft:coral_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkYNWvYgoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgB5ZWxsb3cBCABkZWFkX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "id": "minecraft:horn_coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRTBAAACAQAbmFtZRoAbWluZWNyYWZ0Omhvcm5fY29yYWxfYmxvY2sECQBuYW1lX2hhc2hnZSLRWUwGhAMKAG5ldHdvcmtfaWRSK6ccCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { - "id": "minecraft:coral_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkZSxBQgoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABibHVlAQgAZGVhZF9iaXQBAAMHAHZlcnNpb24ERhQBAA==" + "id": "minecraft:dead_tube_coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRUBAAACAQAbmFtZR8AbWluZWNyYWZ0OmRlYWRfdHViZV9jb3JhbF9ibG9jawQJAG5hbWVfaGFzaB9+lY3hAkNNAwoAbmV0d29ya19pZF0hKKYKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { - "id": "minecraft:coral_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lklSTVqQoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBABwaW5rAQgAZGVhZF9iaXQBAAMHAHZlcnNpb24ERhQBAA==" + "id": "minecraft:dead_brain_coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRVBAAACAQAbmFtZSAAbWluZWNyYWZ0OmRlYWRfYnJhaW5fY29yYWxfYmxvY2sECQBuYW1lX2hhc2iHyDn52AO8uwMKAG5ldHdvcmtfaWQw7yCaCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { - "id": "minecraft:coral_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lk5fTYuQoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgBwdXJwbGUBCABkZWFkX2JpdAEAAwcAdmVyc2lvbgRGFAEA" + "id": "minecraft:dead_bubble_coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRWBAAACAQAbmFtZSEAbWluZWNyYWZ0OmRlYWRfYnViYmxlX2NvcmFsX2Jsb2NrBAkAbmFtZV9oYXNotwkk/ITrsjADCgBuZXR3b3JrX2lk56mXUgoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { - "id": "minecraft:coral_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkwUjqBAoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yAwByZWQBCABkZWFkX2JpdAEAAwcAdmVyc2lvbgRGFAEA" + "id": "minecraft:dead_fire_coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRXBAAACAQAbmFtZR8AbWluZWNyYWZ0OmRlYWRfZmlyZV9jb3JhbF9ibG9jawQJAG5hbWVfaGFzaG0qHxbIrBEyAwoAbmV0d29ya19pZFvnH88KBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { - "id": "minecraft:coral_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAQAACAQAbmFtZRUAbWluZWNyYWZ0OmNvcmFsX2Jsb2NrBAkAbmFtZV9oYXNoxTOVIjqYOYIDCgBuZXR3b3JrX2lkq4iWoQoGAHN0YXRlcwgLAGNvcmFsX2NvbG9yBgB5ZWxsb3cBCABkZWFkX2JpdAEAAwcAdmVyc2lvbgRGFAEA" + "id": "minecraft:dead_horn_coral_block", + "block_state_b64": "CgAAAwgAYmxvY2tfaWRYBAAACAQAbmFtZR8AbWluZWNyYWZ0OmRlYWRfaG9ybl9jb3JhbF9ibG9jawQJAG5hbWVfaGFzaL7D8bu4Fm+0AwoAbmV0d29ya19pZEALRLoKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:sculk", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAgAACAQAbmFtZQ8AbWluZWNyYWZ0OnNjdWxrBAkAbmFtZV9oYXNo2Lq7T5yQF8kDCgBuZXR3b3JrX2lkyqUPPgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAgAACAQAbmFtZQ8AbWluZWNyYWZ0OnNjdWxrBAkAbmFtZV9oYXNo2Lq7T5yQF8kDCgBuZXR3b3JrX2lkyqUPPgoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:sculk_vein", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTKAgAACAQAbmFtZRQAbWluZWNyYWZ0OnNjdWxrX3ZlaW4ECQBuYW1lX2hhc2gJUdhVooV4zwMKAG5ldHdvcmtfaWSUfn1XCgYAc3RhdGVzAxkAbXVsdGlfZmFjZV9kaXJlY3Rpb25fYml0cwAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTKAgAACAQAbmFtZRQAbWluZWNyYWZ0OnNjdWxrX3ZlaW4ECQBuYW1lX2hhc2gJUdhVooV4zwMKAG5ldHdvcmtfaWSUfn1XCgYAc3RhdGVzAxkAbXVsdGlfZmFjZV9kaXJlY3Rpb25fYml0cwAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:sculk_catalyst", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTLAgAACAQAbmFtZRgAbWluZWNyYWZ0OnNjdWxrX2NhdGFseXN0BAkAbmFtZV9oYXNo+gCpbrCHST4DCgBuZXR3b3JrX2lkMJ2n/woGAHN0YXRlcwEFAGJsb29tAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTLAgAACAQAbmFtZRgAbWluZWNyYWZ0OnNjdWxrX2NhdGFseXN0BAkAbmFtZV9oYXNo+gCpbrCHST4DCgBuZXR3b3JrX2lkMJ2n/woGAHN0YXRlcwEFAGJsb29tAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:sculk_shrieker", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTMAgAACAQAbmFtZRgAbWluZWNyYWZ0OnNjdWxrX3Nocmlla2VyBAkAbmFtZV9oYXNo5OXtyObniQ4DCgBuZXR3b3JrX2lkxapoNAoGAHN0YXRlcwEGAGFjdGl2ZQABCgBjYW5fc3VtbW9uAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTMAgAACAQAbmFtZRgAbWluZWNyYWZ0OnNjdWxrX3Nocmlla2VyBAkAbmFtZV9oYXNo5OXtyObniQ4DCgBuZXR3b3JrX2lkxapoNAoGAHN0YXRlcwEGAGFjdGl2ZQABCgBjYW5fc3VtbW9uAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:sculk_sensor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQyAgAACAQAbmFtZRYAbWluZWNyYWZ0OnNjdWxrX3NlbnNvcgQJAG5hbWVfaGFzaCkmHreeTgNnAwoAbmV0d29ya19pZLj2WPcKBgBzdGF0ZXMDEgBzY3Vsa19zZW5zb3JfcGhhc2UAAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQyAgAACAQAbmFtZRYAbWluZWNyYWZ0OnNjdWxrX3NlbnNvcgQJAG5hbWVfaGFzaCkmHreeTgNnAwoAbmV0d29ya19pZLj2WPcKBgBzdGF0ZXMDEgBzY3Vsa19zZW5zb3JfcGhhc2UAAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:calibrated_sculk_sensor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRDAwAACAQAbmFtZSEAbWluZWNyYWZ0OmNhbGlicmF0ZWRfc2N1bGtfc2Vuc29yBAkAbmFtZV9oYXNoffAcXXN/iJUDCgBuZXR3b3JrX2lkwOx3QQoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAxIAc2N1bGtfc2Vuc29yX3BoYXNlAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRDAwAACAQAbmFtZSEAbWluZWNyYWZ0OmNhbGlicmF0ZWRfc2N1bGtfc2Vuc29yBAkAbmFtZV9oYXNoffAcXXN/iJUDCgBuZXR3b3JrX2lkwOx3QQoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAxIAc2N1bGtfc2Vuc29yX3BoYXNlAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:reinforced_deepslate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTRAgAACAQAbmFtZR4AbWluZWNyYWZ0OnJlaW5mb3JjZWRfZGVlcHNsYXRlBAkAbmFtZV9oYXNoldDmj91EapQDCgBuZXR3b3JrX2lkHIt+aQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTRAgAACAQAbmFtZR4AbWluZWNyYWZ0OnJlaW5mb3JjZWRfZGVlcHNsYXRlBAkAbmFtZV9oYXNoldDmj91EapQDCgBuZXR3b3JrX2lkHIt+aQoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:leather_helmet" @@ -3168,6 +3389,9 @@ { "id": "minecraft:crossbow" }, + { + "id": "minecraft:mace" + }, { "id": "minecraft:arrow" }, @@ -3323,6 +3547,41 @@ "id": "minecraft:arrow", "damage": 43 }, + { + "id": "minecraft:arrow", + "damage": 44 + }, + { + "id": "minecraft:arrow", + "damage": 45 + }, + { + "id": "minecraft:arrow", + "damage": 46 + }, + { + "id": "minecraft:arrow", + "damage": 47 + }, + { + "id": "minecraft:ominous_bottle" + }, + { + "id": "minecraft:ominous_bottle", + "damage": 1 + }, + { + "id": "minecraft:ominous_bottle", + "damage": 2 + }, + { + "id": "minecraft:ominous_bottle", + "damage": 3 + }, + { + "id": "minecraft:ominous_bottle", + "damage": 4 + }, { "id": "minecraft:shield" }, @@ -3386,6 +3645,9 @@ { "id": "minecraft:snowball" }, + { + "id": "minecraft:wind_charge" + }, { "id": "minecraft:shears" }, @@ -3457,6 +3719,9 @@ { "id": "minecraft:diamond_horse_armor" }, + { + "id": "minecraft:wolf_armor" + }, { "id": "minecraft:trident" }, @@ -3646,6 +3911,22 @@ "id": "minecraft:potion", "damage": 42 }, + { + "id": "minecraft:potion", + "damage": 43 + }, + { + "id": "minecraft:potion", + "damage": 44 + }, + { + "id": "minecraft:potion", + "damage": 45 + }, + { + "id": "minecraft:potion", + "damage": 46 + }, { "id": "minecraft:splash_potion" }, @@ -3817,6 +4098,22 @@ "id": "minecraft:splash_potion", "damage": 42 }, + { + "id": "minecraft:splash_potion", + "damage": 43 + }, + { + "id": "minecraft:splash_potion", + "damage": 44 + }, + { + "id": "minecraft:splash_potion", + "damage": 45 + }, + { + "id": "minecraft:splash_potion", + "damage": 46 + }, { "id": "minecraft:lingering_potion" }, @@ -3988,6 +4285,22 @@ "id": "minecraft:lingering_potion", "damage": 42 }, + { + "id": "minecraft:lingering_potion", + "damage": 43 + }, + { + "id": "minecraft:lingering_potion", + "damage": 44 + }, + { + "id": "minecraft:lingering_potion", + "damage": 45 + }, + { + "id": "minecraft:lingering_potion", + "damage": 46 + }, { "id": "minecraft:spyglass" }, @@ -4062,119 +4375,119 @@ }, { "id": "minecraft:torch", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQyAAAACAQAbmFtZQ8AbWluZWNyYWZ0OnRvcmNoBAkAbmFtZV9oYXNoagn7rmDBzisDCgBuZXR3b3JrX2lk+BwwuQoGAHN0YXRlcwgWAHRvcmNoX2ZhY2luZ19kaXJlY3Rpb24HAHVua25vd24AAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQyAAAACAQAbmFtZQ8AbWluZWNyYWZ0OnRvcmNoBAkAbmFtZV9oYXNoagn7rmDBzisDCgBuZXR3b3JrX2lk+BwwuQoGAHN0YXRlcwgWAHRvcmNoX2ZhY2luZ19kaXJlY3Rpb24HAHVua25vd24AAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:soul_torch", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQLAgAACAQAbmFtZRQAbWluZWNyYWZ0OnNvdWxfdG9yY2gECQBuYW1lX2hhc2huixOT04BRdQMKAG5ldHdvcmtfaWShbFILCgYAc3RhdGVzCBYAdG9yY2hfZmFjaW5nX2RpcmVjdGlvbgcAdW5rbm93bgADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQLAgAACAQAbmFtZRQAbWluZWNyYWZ0OnNvdWxfdG9yY2gECQBuYW1lX2hhc2huixOT04BRdQMKAG5ldHdvcmtfaWShbFILCgYAc3RhdGVzCBYAdG9yY2hfZmFjaW5nX2RpcmVjdGlvbgcAdW5rbm93bgADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:sea_pickle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAQAACAQAbmFtZRQAbWluZWNyYWZ0OnNlYV9waWNrbGUECQBuYW1lX2hhc2iONEfZJB+glgMKAG5ldHdvcmtfaWSINWQyCgYAc3RhdGVzAw0AY2x1c3Rlcl9jb3VudAAAAAABCABkZWFkX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAQAACAQAbmFtZRQAbWluZWNyYWZ0OnNlYV9waWNrbGUECQBuYW1lX2hhc2iONEfZJB+glgMKAG5ldHdvcmtfaWSINWQyCgYAc3RhdGVzAw0AY2x1c3Rlcl9jb3VudAAAAAABCABkZWFkX2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:lantern", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTPAQAACAQAbmFtZREAbWluZWNyYWZ0OmxhbnRlcm4ECQBuYW1lX2hhc2hMw44VI2HWygMKAG5ldHdvcmtfaWRkjQvzCgYAc3RhdGVzAQcAaGFuZ2luZwAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTPAQAACAQAbmFtZREAbWluZWNyYWZ0OmxhbnRlcm4ECQBuYW1lX2hhc2hMw44VI2HWygMKAG5ldHdvcmtfaWRkjQvzCgYAc3RhdGVzAQcAaGFuZ2luZwAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:soul_lantern", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQMAgAACAQAbmFtZRYAbWluZWNyYWZ0OnNvdWxfbGFudGVybgQJAG5hbWVfaGFzaGjIpjxk9z+RAwoAbmV0d29ya19pZGfoP8cKBgBzdGF0ZXMBBwBoYW5naW5nAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQMAgAACAQAbmFtZRYAbWluZWNyYWZ0OnNvdWxfbGFudGVybgQJAG5hbWVfaGFzaGjIpjxk9z+RAwoAbmV0d29ya19pZGfoP8cKBgBzdGF0ZXMBBwBoYW5naW5nAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAgAACAQAbmFtZRAAbWluZWNyYWZ0OmNhbmRsZQQJAG5hbWVfaGFzaHPd+MsNdWTfAwoAbmV0d29ya19pZHsBMA0KBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSbAgAACAQAbmFtZRAAbWluZWNyYWZ0OmNhbmRsZQQJAG5hbWVfaGFzaHPd+MsNdWTfAwoAbmV0d29ya19pZHsBMA0KBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:white_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWScAgAACAQAbmFtZRYAbWluZWNyYWZ0OndoaXRlX2NhbmRsZQQJAG5hbWVfaGFzaN1EG5Q1mHiEAwoAbmV0d29ya19pZKN1mmgKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWScAgAACAQAbmFtZRYAbWluZWNyYWZ0OndoaXRlX2NhbmRsZQQJAG5hbWVfaGFzaN1EG5Q1mHiEAwoAbmV0d29ya19pZKN1mmgKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:orange_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSdAgAACAQAbmFtZRcAbWluZWNyYWZ0Om9yYW5nZV9jYW5kbGUECQBuYW1lX2hhc2jySEVWHgUIHQMKAG5ldHdvcmtfaWSfVz82CgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSdAgAACAQAbmFtZRcAbWluZWNyYWZ0Om9yYW5nZV9jYW5kbGUECQBuYW1lX2hhc2jySEVWHgUIHQMKAG5ldHdvcmtfaWSfVz82CgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:magenta_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSeAgAACAQAbmFtZRgAbWluZWNyYWZ0Om1hZ2VudGFfY2FuZGxlBAkAbmFtZV9oYXNoG0u6YIOoBSEDCgBuZXR3b3JrX2lk9xGNkQoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSeAgAACAQAbmFtZRgAbWluZWNyYWZ0Om1hZ2VudGFfY2FuZGxlBAkAbmFtZV9oYXNoG0u6YIOoBSEDCgBuZXR3b3JrX2lk9xGNkQoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:light_blue_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSfAgAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY2FuZGxlBAkAbmFtZV9oYXNocXGeK0zgrG0DCgBuZXR3b3JrX2lk2m1y8goGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSfAgAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfY2FuZGxlBAkAbmFtZV9oYXNocXGeK0zgrG0DCgBuZXR3b3JrX2lk2m1y8goGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:yellow_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSgAgAACAQAbmFtZRcAbWluZWNyYWZ0OnllbGxvd19jYW5kbGUECQBuYW1lX2hhc2i00dtusU3CqQMKAG5ldHdvcmtfaWR9LTmpCgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSgAgAACAQAbmFtZRcAbWluZWNyYWZ0OnllbGxvd19jYW5kbGUECQBuYW1lX2hhc2i00dtusU3CqQMKAG5ldHdvcmtfaWR9LTmpCgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:lime_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWShAgAACAQAbmFtZRUAbWluZWNyYWZ0OmxpbWVfY2FuZGxlBAkAbmFtZV9oYXNokcmrw5xvz7ADCgBuZXR3b3JrX2lkIAUu6QoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWShAgAACAQAbmFtZRUAbWluZWNyYWZ0OmxpbWVfY2FuZGxlBAkAbmFtZV9oYXNokcmrw5xvz7ADCgBuZXR3b3JrX2lkIAUu6QoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:pink_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSiAgAACAQAbmFtZRUAbWluZWNyYWZ0OnBpbmtfY2FuZGxlBAkAbmFtZV9oYXNoQJdEY4sZ0dwDCgBuZXR3b3JrX2lk23Rn5AoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSiAgAACAQAbmFtZRUAbWluZWNyYWZ0OnBpbmtfY2FuZGxlBAkAbmFtZV9oYXNoQJdEY4sZ0dwDCgBuZXR3b3JrX2lk23Rn5AoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:gray_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSjAgAACAQAbmFtZRUAbWluZWNyYWZ0OmdyYXlfY2FuZGxlBAkAbmFtZV9oYXNoS5poSo9wBDEDCgBuZXR3b3JrX2lk3trRCAoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSjAgAACAQAbmFtZRUAbWluZWNyYWZ0OmdyYXlfY2FuZGxlBAkAbmFtZV9oYXNoS5poSo9wBDEDCgBuZXR3b3JrX2lk3trRCAoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:light_gray_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSkAgAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY2FuZGxlBAkAbmFtZV9oYXNo9ruTZLBNMasDCgBuZXR3b3JrX2lkb6DOegoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSkAgAACAQAbmFtZRsAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfY2FuZGxlBAkAbmFtZV9oYXNo9ruTZLBNMasDCgBuZXR3b3JrX2lkb6DOegoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:cyan_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAgAACAQAbmFtZRUAbWluZWNyYWZ0OmN5YW5fY2FuZGxlBAkAbmFtZV9oYXNoc/M8PNVcjOwDCgBuZXR3b3JrX2lkZoIQOQoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSlAgAACAQAbmFtZRUAbWluZWNyYWZ0OmN5YW5fY2FuZGxlBAkAbmFtZV9oYXNoc/M8PNVcjOwDCgBuZXR3b3JrX2lkZoIQOQoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:purple_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSmAgAACAQAbmFtZRcAbWluZWNyYWZ0OnB1cnBsZV9jYW5kbGUECQBuYW1lX2hhc2jaI3xUW0/myQMKAG5ldHdvcmtfaWSnLI2BCgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSmAgAACAQAbmFtZRcAbWluZWNyYWZ0OnB1cnBsZV9jYW5kbGUECQBuYW1lX2hhc2jaI3xUW0/myQMKAG5ldHdvcmtfaWSnLI2BCgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:blue_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSnAgAACAQAbmFtZRUAbWluZWNyYWZ0OmJsdWVfY2FuZGxlBAkAbmFtZV9oYXNoAASSPW6TgQADCgBuZXR3b3JrX2lkrxrjQAoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSnAgAACAQAbmFtZRUAbWluZWNyYWZ0OmJsdWVfY2FuZGxlBAkAbmFtZV9oYXNoAASSPW6TgQADCgBuZXR3b3JrX2lkrxrjQAoGAHN0YXRlcwMHAGNhbmRsZXMAAAAAAQMAbGl0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:brown_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAgAACAQAbmFtZRYAbWluZWNyYWZ0OmJyb3duX2NhbmRsZQQJAG5hbWVfaGFzaDia0l6s1+WYAwoAbmV0d29ya19pZKSkBXYKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSoAgAACAQAbmFtZRYAbWluZWNyYWZ0OmJyb3duX2NhbmRsZQQJAG5hbWVfaGFzaDia0l6s1+WYAwoAbmV0d29ya19pZKSkBXYKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:green_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSpAgAACAQAbmFtZRYAbWluZWNyYWZ0OmdyZWVuX2NhbmRsZQQJAG5hbWVfaGFzaLeFPO1l+fIoAwoAbmV0d29ya19pZBkznDsKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSpAgAACAQAbmFtZRYAbWluZWNyYWZ0OmdyZWVuX2NhbmRsZQQJAG5hbWVfaGFzaLeFPO1l+fIoAwoAbmV0d29ya19pZBkznDsKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:red_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSqAgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9jYW5kbGUECQBuYW1lX2hhc2jjAQpGf59ZdwMKAG5ldHdvcmtfaWRbb88GCgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSqAgAACAQAbmFtZRQAbWluZWNyYWZ0OnJlZF9jYW5kbGUECQBuYW1lX2hhc2jjAQpGf59ZdwMKAG5ldHdvcmtfaWRbb88GCgYAc3RhdGVzAwcAY2FuZGxlcwAAAAABAwBsaXQAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:black_candle", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSrAgAACAQAbmFtZRYAbWluZWNyYWZ0OmJsYWNrX2NhbmRsZQQJAG5hbWVfaGFzaB+wRDpOqREKAwoAbmV0d29ya19pZNnOnuEKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSrAgAACAQAbmFtZRYAbWluZWNyYWZ0OmJsYWNrX2NhbmRsZQQJAG5hbWVfaGFzaB+wRDpOqREKAwoAbmV0d29ya19pZNnOnuEKBgBzdGF0ZXMDBwBjYW5kbGVzAAAAAAEDAGxpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:crafting_table", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ6AAAACAQAbmFtZRgAbWluZWNyYWZ0OmNyYWZ0aW5nX3RhYmxlBAkAbmFtZV9oYXNoe76VAmjvbpYDCgBuZXR3b3JrX2lkwCxwaAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ6AAAACAQAbmFtZRgAbWluZWNyYWZ0OmNyYWZ0aW5nX3RhYmxlBAkAbmFtZV9oYXNoe76VAmjvbpYDCgBuZXR3b3JrX2lkwCxwaAoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:cartography_table", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTHAQAACAQAbmFtZRsAbWluZWNyYWZ0OmNhcnRvZ3JhcGh5X3RhYmxlBAkAbmFtZV9oYXNomaWiiD/znP8DCgBuZXR3b3JrX2lkI6FzMwoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTHAQAACAQAbmFtZRsAbWluZWNyYWZ0OmNhcnRvZ3JhcGh5X3RhYmxlBAkAbmFtZV9oYXNomaWiiD/znP8DCgBuZXR3b3JrX2lkI6FzMwoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:fletching_table", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTIAQAACAQAbmFtZRkAbWluZWNyYWZ0OmZsZXRjaGluZ190YWJsZQQJAG5hbWVfaGFzaPFibh8unKyUAwoAbmV0d29ya19pZJ2mW0oKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTIAQAACAQAbmFtZRkAbWluZWNyYWZ0OmZsZXRjaGluZ190YWJsZQQJAG5hbWVfaGFzaPFibh8unKyUAwoAbmV0d29ya19pZJ2mW0oKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:smithing_table", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAQAACAQAbmFtZRgAbWluZWNyYWZ0OnNtaXRoaW5nX3RhYmxlBAkAbmFtZV9oYXNo4tFES2xOXEYDCgBuZXR3b3JrX2lkXWMBzQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTJAQAACAQAbmFtZRgAbWluZWNyYWZ0OnNtaXRoaW5nX3RhYmxlBAkAbmFtZV9oYXNo4tFES2xOXEYDCgBuZXR3b3JrX2lkXWMBzQoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:beehive", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTaAQAACAQAbmFtZREAbWluZWNyYWZ0OmJlZWhpdmUECQBuYW1lX2hhc2hCcqn12UbNpwMKAG5ldHdvcmtfaWR/idcaCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAMLAGhvbmV5X2xldmVsAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTaAQAACAQAbmFtZREAbWluZWNyYWZ0OmJlZWhpdmUECQBuYW1lX2hhc2hCcqn12UbNpwMKAG5ldHdvcmtfaWR/idcaCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAMLAGhvbmV5X2xldmVsAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:suspicious_sand", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQQAwAACAQAbmFtZRkAbWluZWNyYWZ0OnN1c3BpY2lvdXNfc2FuZAQJAG5hbWVfaGFzaL67QsuvLP00AwoAbmV0d29ya19pZKnkaIAKBgBzdGF0ZXMDEABicnVzaGVkX3Byb2dyZXNzAAAAAAEHAGhhbmdpbmcBAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQQAwAACAQAbmFtZRkAbWluZWNyYWZ0OnN1c3BpY2lvdXNfc2FuZAQJAG5hbWVfaGFzaL67QsuvLP00AwoAbmV0d29ya19pZKnkaIAKBgBzdGF0ZXMDEABicnVzaGVkX3Byb2dyZXNzAAAAAAEHAGhhbmdpbmcBAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:suspicious_gravel", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ8AwAACAQAbmFtZRsAbWluZWNyYWZ0OnN1c3BpY2lvdXNfZ3JhdmVsBAkAbmFtZV9oYXNoJSVbGNk7C3oDCgBuZXR3b3JrX2lkvIEJAAoGAHN0YXRlcwMQAGJydXNoZWRfcHJvZ3Jlc3MAAAAAAQcAaGFuZ2luZwEAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ8AwAACAQAbmFtZRsAbWluZWNyYWZ0OnN1c3BpY2lvdXNfZ3JhdmVsBAkAbmFtZV9oYXNoJSVbGNk7C3oDCgBuZXR3b3JrX2lkvIEJAAoGAHN0YXRlcwMQAGJydXNoZWRfcHJvZ3Jlc3MAAAAAAQcAaGFuZ2luZwEAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:campfire" @@ -4184,156 +4497,156 @@ }, { "id": "minecraft:furnace", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ9AAAACAQAbmFtZREAbWluZWNyYWZ0OmZ1cm5hY2UECQBuYW1lX2hhc2ioOQrludYY8wMKAG5ldHdvcmtfaWRZxnDOCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ9AAAACAQAbmFtZREAbWluZWNyYWZ0OmZ1cm5hY2UECQBuYW1lX2hhc2ioOQrludYY8wMKAG5ldHdvcmtfaWRZxnDOCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:blast_furnace", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTDAQAACAQAbmFtZRcAbWluZWNyYWZ0OmJsYXN0X2Z1cm5hY2UECQBuYW1lX2hhc2ivDbnjkpGm5QMKAG5ldHdvcmtfaWTcEbV/CgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTDAQAACAQAbmFtZRcAbWluZWNyYWZ0OmJsYXN0X2Z1cm5hY2UECQBuYW1lX2hhc2ivDbnjkpGm5QMKAG5ldHdvcmtfaWTcEbV/CgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:smoker", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTFAQAACAQAbmFtZRAAbWluZWNyYWZ0OnNtb2tlcgQJAG5hbWVfaGFzaJd1rDMkRWomAwoAbmV0d29ya19pZGWswMwKBgBzdGF0ZXMIHABtaW5lY3JhZnQ6Y2FyZGluYWxfZGlyZWN0aW9uBQBzb3V0aAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTFAQAACAQAbmFtZRAAbWluZWNyYWZ0OnNtb2tlcgQJAG5hbWVfaGFzaJd1rDMkRWomAwoAbmV0d29ya19pZGWswMwKBgBzdGF0ZXMIHABtaW5lY3JhZnQ6Y2FyZGluYWxfZGlyZWN0aW9uBQBzb3V0aAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:respawn_anchor", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQPAgAACAQAbmFtZRgAbWluZWNyYWZ0OnJlc3Bhd25fYW5jaG9yBAkAbmFtZV9oYXNoZOdcjW05qigDCgBuZXR3b3JrX2lkmhMcaQoGAHN0YXRlcwMVAHJlc3Bhd25fYW5jaG9yX2NoYXJnZQAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQPAgAACAQAbmFtZRgAbWluZWNyYWZ0OnJlc3Bhd25fYW5jaG9yBAkAbmFtZV9oYXNoZOdcjW05qigDCgBuZXR3b3JrX2lkmhMcaQoGAHN0YXRlcwMVAHJlc3Bhd25fYW5jaG9yX2NoYXJnZQAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:brewing_stand" }, { "id": "minecraft:anvil", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmFudmlsBAkAbmFtZV9oYXNoNqB3fgcUCbwDCgBuZXR3b3JrX2lk8Z3VowoGAHN0YXRlcwgGAGRhbWFnZQkAdW5kYW1hZ2VkCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmFudmlsBAkAbmFtZV9oYXNoNqB3fgcUCbwDCgBuZXR3b3JrX2lk8Z3VowoGAHN0YXRlcwgGAGRhbWFnZQkAdW5kYW1hZ2VkCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:anvil", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmFudmlsBAkAbmFtZV9oYXNoNqB3fgcUCbwDCgBuZXR3b3JrX2lkpiv8BAoGAHN0YXRlcwgGAGRhbWFnZRAAc2xpZ2h0bHlfZGFtYWdlZAgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmFudmlsBAkAbmFtZV9oYXNoNqB3fgcUCbwDCgBuZXR3b3JrX2lkpiv8BAoGAHN0YXRlcwgGAGRhbWFnZRAAc2xpZ2h0bHlfZGFtYWdlZAgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAHNvdXRoAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:anvil", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmFudmlsBAkAbmFtZV9oYXNoNqB3fgcUCbwDCgBuZXR3b3JrX2lkFu+pdwoGAHN0YXRlcwgGAGRhbWFnZQwAdmVyeV9kYW1hZ2VkCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSRAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmFudmlsBAkAbmFtZV9oYXNoNqB3fgcUCbwDCgBuZXR3b3JrX2lkFu+pdwoGAHN0YXRlcwgGAGRhbWFnZQwAdmVyeV9kYW1hZ2VkCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:grindstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTCAQAACAQAbmFtZRQAbWluZWNyYWZ0OmdyaW5kc3RvbmUECQBuYW1lX2hhc2id56zc0nk99wMKAG5ldHdvcmtfaWS4Es07CgYAc3RhdGVzCAoAYXR0YWNobWVudAgAc3RhbmRpbmcDCQBkaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTCAQAACAQAbmFtZRQAbWluZWNyYWZ0OmdyaW5kc3RvbmUECQBuYW1lX2hhc2id56zc0nk99wMKAG5ldHdvcmtfaWS4Es07CgYAc3RhdGVzCAoAYXR0YWNobWVudAgAc3RhbmRpbmcDCQBkaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:enchanting_table", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR0AAAACAQAbmFtZRoAbWluZWNyYWZ0OmVuY2hhbnRpbmdfdGFibGUECQBuYW1lX2hhc2jgIx24VLvMvwMKAG5ldHdvcmtfaWRliFFJCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWR0AAAACAQAbmFtZRoAbWluZWNyYWZ0OmVuY2hhbnRpbmdfdGFibGUECQBuYW1lX2hhc2jgIx24VLvMvwMKAG5ldHdvcmtfaWRliFFJCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:bookshelf", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQvAAAACAQAbmFtZRMAbWluZWNyYWZ0OmJvb2tzaGVsZgQJAG5hbWVfaGFzaDU04DrgJCS9AwoAbmV0d29ya19pZBcWwIwKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQvAAAACAQAbmFtZRMAbWluZWNyYWZ0OmJvb2tzaGVsZgQJAG5hbWVfaGFzaDU04DrgJCS9AwoAbmV0d29ya19pZBcWwIwKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:chiseled_bookshelf", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQNAwAACAQAbmFtZRwAbWluZWNyYWZ0OmNoaXNlbGVkX2Jvb2tzaGVsZgQJAG5hbWVfaGFzaNXDBnsIsywYAwoAbmV0d29ya19pZIprt5IKBgBzdGF0ZXMDDABib29rc19zdG9yZWQAAAAAAwkAZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQNAwAACAQAbmFtZRwAbWluZWNyYWZ0OmNoaXNlbGVkX2Jvb2tzaGVsZgQJAG5hbWVfaGFzaNXDBnsIsywYAwoAbmV0d29ya19pZIprt5IKBgBzdGF0ZXMDDABib29rc19zdG9yZWQAAAAAAwkAZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:lectern", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTBAQAACAQAbmFtZREAbWluZWNyYWZ0OmxlY3Rlcm4ECQBuYW1lX2hhc2j5Z4Mmi/1QxAMKAG5ldHdvcmtfaWR4JfDHCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgBCwBwb3dlcmVkX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTBAQAACAQAbmFtZREAbWluZWNyYWZ0OmxlY3Rlcm4ECQBuYW1lX2hhc2j5Z4Mmi/1QxAMKAG5ldHdvcmtfaWR4JfDHCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAc291dGgBCwBwb3dlcmVkX2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:cauldron" }, { "id": "minecraft:composter", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTUAQAACAQAbmFtZRMAbWluZWNyYWZ0OmNvbXBvc3RlcgQJAG5hbWVfaGFzaPAADHptzeWJAwoAbmV0d29ya19pZHIL6i4KBgBzdGF0ZXMDFABjb21wb3N0ZXJfZmlsbF9sZXZlbAAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTUAQAACAQAbmFtZRMAbWluZWNyYWZ0OmNvbXBvc3RlcgQJAG5hbWVfaGFzaPAADHptzeWJAwoAbmV0d29ya19pZHIL6i4KBgBzdGF0ZXMDFABjb21wb3N0ZXJfZmlsbF9sZXZlbAAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:chest", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ2AAAACAQAbmFtZQ8AbWluZWNyYWZ0OmNoZXN0BAkAbmFtZV9oYXNog9ozMxlcA88DCgBuZXR3b3JrX2lkDkOFvAoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAG5vcnRoAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ2AAAACAQAbmFtZQ8AbWluZWNyYWZ0OmNoZXN0BAkAbmFtZV9oYXNog9ozMxlcA88DCgBuZXR3b3JrX2lkDkOFvAoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAG5vcnRoAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:trapped_chest", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSSAAAACAQAbmFtZRcAbWluZWNyYWZ0OnRyYXBwZWRfY2hlc3QECQBuYW1lX2hhc2g2qpF9stsEjgMKAG5ldHdvcmtfaWTjJWYxCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAbm9ydGgAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSSAAAACAQAbmFtZRcAbWluZWNyYWZ0OnRyYXBwZWRfY2hlc3QECQBuYW1lX2hhc2g2qpF9stsEjgMKAG5ldHdvcmtfaWTjJWYxCgYAc3RhdGVzCBwAbWluZWNyYWZ0OmNhcmRpbmFsX2RpcmVjdGlvbgUAbm9ydGgAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:ender_chest", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSCAAAACAQAbmFtZRUAbWluZWNyYWZ0OmVuZGVyX2NoZXN0BAkAbmFtZV9oYXNohEZzOFdg0WUDCgBuZXR3b3JrX2lkx4jiSQoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAG5vcnRoAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSCAAAACAQAbmFtZRUAbWluZWNyYWZ0OmVuZGVyX2NoZXN0BAkAbmFtZV9oYXNohEZzOFdg0WUDCgBuZXR3b3JrX2lkx4jiSQoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAG5vcnRoAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:barrel", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTKAQAACAQAbmFtZRAAbWluZWNyYWZ0OmJhcnJlbAQJAG5hbWVfaGFzaHDkRPGymiRqAwoAbmV0d29ya19pZPnxzgsKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTKAQAACAQAbmFtZRAAbWluZWNyYWZ0OmJhcnJlbAQJAG5hbWVfaGFzaHDkRPGymiRqAwoAbmV0d29ya19pZPnxzgsKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAAAAAAEIAG9wZW5fYml0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:undyed_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTNAAAACAQAbmFtZRwAbWluZWNyYWZ0OnVuZHllZF9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaOC9mypm/MlBAwoAbmV0d29ya19pZJ8rxp0KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTNAAAACAQAbmFtZRwAbWluZWNyYWZ0OnVuZHllZF9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaOC9mypm/MlBAwoAbmV0d29ya19pZJ8rxp0KBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:white_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTaAAAACAQAbmFtZRsAbWluZWNyYWZ0OndoaXRlX3NodWxrZXJfYm94BAkAbmFtZV9oYXNosK79m1rPUBwDCgBuZXR3b3JrX2lkjrET6goGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTaAAAACAQAbmFtZRsAbWluZWNyYWZ0OndoaXRlX3NodWxrZXJfYm94BAkAbmFtZV9oYXNosK79m1rPUBwDCgBuZXR3b3JrX2lkjrET6goGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:light_gray_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRrAwAACAQAbmFtZSAAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2iBe5zq7PxHmgMKAG5ldHdvcmtfaWSCVJv0CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRrAwAACAQAbmFtZSAAbWluZWNyYWZ0OmxpZ2h0X2dyYXlfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2iBe5zq7PxHmgMKAG5ldHdvcmtfaWSCVJv0CgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:gray_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRqAwAACAQAbmFtZRoAbWluZWNyYWZ0OmdyYXlfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2ga2s8ctjHUhgMKAG5ldHdvcmtfaWS3WMsWCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRqAwAACAQAbmFtZRoAbWluZWNyYWZ0OmdyYXlfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2ga2s8ctjHUhgMKAG5ldHdvcmtfaWS3WMsWCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:black_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRyAwAACAQAbmFtZRsAbWluZWNyYWZ0OmJsYWNrX3NodWxrZXJfYm94BAkAbmFtZV9oYXNoPm03OZphrp8DCgBuZXR3b3JrX2lkXHztNAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRyAwAACAQAbmFtZRsAbWluZWNyYWZ0OmJsYWNrX3NodWxrZXJfYm94BAkAbmFtZV9oYXNoPm03OZphrp8DCgBuZXR3b3JrX2lkXHztNAoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:brown_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRvAwAACAQAbmFtZRsAbWluZWNyYWZ0OmJyb3duX3NodWxrZXJfYm94BAkAbmFtZV9oYXNoT3DD6qAL9cADCgBuZXR3b3JrX2lkaXxpYQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRvAwAACAQAbmFtZRsAbWluZWNyYWZ0OmJyb3duX3NodWxrZXJfYm94BAkAbmFtZV9oYXNoT3DD6qAL9cADCgBuZXR3b3JrX2lkaXxpYQoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:red_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRxAwAACAQAbmFtZRkAbWluZWNyYWZ0OnJlZF9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaMIlKSCzqSZoAwoAbmV0d29ya19pZNrf+icKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRxAwAACAQAbmFtZRkAbWluZWNyYWZ0OnJlZF9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaMIlKSCzqSZoAwoAbmV0d29ya19pZNrf+icKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:orange_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRkAwAACAQAbmFtZRwAbWluZWNyYWZ0Om9yYW5nZV9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaG2MAXU67wGrAwoAbmV0d29ya19pZGoO05gKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRkAwAACAQAbmFtZRwAbWluZWNyYWZ0Om9yYW5nZV9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaG2MAXU67wGrAwoAbmV0d29ya19pZGoO05gKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:yellow_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRnAwAACAQAbmFtZRwAbWluZWNyYWZ0OnllbGxvd19zaHVsa2VyX2JveAQJAG5hbWVfaGFzaIsLwQHYjcIEAwoAbmV0d29ya19pZBCBSiYKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRnAwAACAQAbmFtZRwAbWluZWNyYWZ0OnllbGxvd19zaHVsa2VyX2JveAQJAG5hbWVfaGFzaIsLwQHYjcIEAwoAbmV0d29ya19pZBCBSiYKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:lime_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRoAwAACAQAbmFtZRoAbWluZWNyYWZ0OmxpbWVfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2hUwBkg+faUGAMKAG5ldHdvcmtfaWRJeKqqCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRoAwAACAQAbmFtZRoAbWluZWNyYWZ0OmxpbWVfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2hUwBkg+faUGAMKAG5ldHdvcmtfaWRJeKqqCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:green_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRwAwAACAQAbmFtZRsAbWluZWNyYWZ0OmdyZWVuX3NodWxrZXJfYm94BAkAbmFtZV9oYXNoZgUeT3LupLUDCgBuZXR3b3JrX2lkzJiohQoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRwAwAACAQAbmFtZRsAbWluZWNyYWZ0OmdyZWVuX3NodWxrZXJfYm94BAkAbmFtZV9oYXNoZgUeT3LupLUDCgBuZXR3b3JrX2lkzJiohQoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:cyan_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRsAwAACAQAbmFtZRoAbWluZWNyYWZ0OmN5YW5fc2h1bGtlcl9ib3gECQBuYW1lX2hhc2gSfbjteXg5yAMKAG5ldHdvcmtfaWTHeliECgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRsAwAACAQAbmFtZRoAbWluZWNyYWZ0OmN5YW5fc2h1bGtlcl9ib3gECQBuYW1lX2hhc2gSfbjteXg5yAMKAG5ldHdvcmtfaWTHeliECgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:light_blue_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRmAwAACAQAbmFtZSAAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2h0VFCX0qsRxQMKAG5ldHdvcmtfaWQXD8U0CgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRmAwAACAQAbmFtZSAAbWluZWNyYWZ0OmxpZ2h0X2JsdWVfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2h0VFCX0qsRxQMKAG5ldHdvcmtfaWQXD8U0CgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:blue_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRuAwAACAQAbmFtZRoAbWluZWNyYWZ0OmJsdWVfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2hn9gS0XIe6rAMKAG5ldHdvcmtfaWTO4PJaCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRuAwAACAQAbmFtZRoAbWluZWNyYWZ0OmJsdWVfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2hn9gS0XIe6rAMKAG5ldHdvcmtfaWTO4PJaCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:purple_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRtAwAACAQAbmFtZRwAbWluZWNyYWZ0OnB1cnBsZV9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaEV/lkNPxRDdAwoAbmV0d29ya19pZFK25GAKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRtAwAACAQAbmFtZRwAbWluZWNyYWZ0OnB1cnBsZV9zaHVsa2VyX2JveAQJAG5hbWVfaGFzaEV/lkNPxRDdAwoAbmV0d29ya19pZFK25GAKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:magenta_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRlAwAACAQAbmFtZR0AbWluZWNyYWZ0Om1hZ2VudGFfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2iqWM7IJHxcFgMKAG5ldHdvcmtfaWTyyudTCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRlAwAACAQAbmFtZR0AbWluZWNyYWZ0Om1hZ2VudGFfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2iqWM7IJHxcFgMKAG5ldHdvcmtfaWTyyudTCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:pink_shulker_box", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRpAwAACAQAbmFtZRoAbWluZWNyYWZ0OnBpbmtfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2in1tkJ1GNcZgMKAG5ldHdvcmtfaWQOEGXjCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRpAwAACAQAbmFtZRoAbWluZWNyYWZ0OnBpbmtfc2h1bGtlcl9ib3gECQBuYW1lX2hhc2in1tkJ1GNcZgMKAG5ldHdvcmtfaWQOEGXjCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:armor_stand" }, { "id": "minecraft:noteblock", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQZAAAACAQAbmFtZRMAbWluZWNyYWZ0Om5vdGVibG9jawQJAG5hbWVfaGFzaHPA8dBBH0UaAwoAbmV0d29ya19pZH1U5QkKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQZAAAACAQAbmFtZRMAbWluZWNyYWZ0Om5vdGVibG9jawQJAG5hbWVfaGFzaHPA8dBBH0UaAwoAbmV0d29ya19pZH1U5QkKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:jukebox", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRUAAAACAQAbmFtZREAbWluZWNyYWZ0Omp1a2Vib3gECQBuYW1lX2hhc2ieAIPExf/ZfgMKAG5ldHdvcmtfaWSmR7JfCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRUAAAACAQAbmFtZREAbWluZWNyYWZ0Omp1a2Vib3gECQBuYW1lX2hhc2ieAIPExf/ZfgMKAG5ldHdvcmtfaWSmR7JfCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:music_disc_13" @@ -4383,6 +4696,15 @@ { "id": "minecraft:music_disc_relic" }, + { + "id": "minecraft:music_disc_creator" + }, + { + "id": "minecraft:music_disc_creator_music_box" + }, + { + "id": "minecraft:music_disc_precipice" + }, { "id": "minecraft:disc_fragment_5" }, @@ -4391,15 +4713,15 @@ }, { "id": "minecraft:glowstone", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRZAAAACAQAbmFtZRMAbWluZWNyYWZ0Omdsb3dzdG9uZQQJAG5hbWVfaGFzaFYqXNkefIlPAwoAbmV0d29ya19pZGT7WYYKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRZAAAACAQAbmFtZRMAbWluZWNyYWZ0Omdsb3dzdG9uZQQJAG5hbWVfaGFzaFYqXNkefIlPAwoAbmV0d29ya19pZGT7WYYKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:redstone_lamp", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR7AAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZHN0b25lX2xhbXAECQBuYW1lX2hhc2hJ9V80caPvEgMKAG5ldHdvcmtfaWRvNPwnCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWR7AAAACAQAbmFtZRcAbWluZWNyYWZ0OnJlZHN0b25lX2xhbXAECQBuYW1lX2hhc2hJ9V80caPvEgMKAG5ldHdvcmtfaWRvNPwnCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:sea_lantern", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSpAAAACAQAbmFtZRUAbWluZWNyYWZ0OnNlYV9sYW50ZXJuBAkAbmFtZV9oYXNoLPsv1TX9M+QDCgBuZXR3b3JrX2lk1PPVyAoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSpAAAACAQAbmFtZRUAbWluZWNyYWZ0OnNlYV9sYW50ZXJuBAkAbmFtZV9oYXNoLPsv1TX9M+QDCgBuZXR3b3JrX2lk1PPVyAoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:oak_sign" @@ -4547,19 +4869,19 @@ }, { "id": "minecraft:beacon", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSKAAAACAQAbmFtZRAAbWluZWNyYWZ0OmJlYWNvbgQJAG5hbWVfaGFzaACwhhfSkdkHAwoAbmV0d29ya19pZF8jfiEKBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSKAAAACAQAbmFtZRAAbWluZWNyYWZ0OmJlYWNvbgQJAG5hbWVfaGFzaACwhhfSkdkHAwoAbmV0d29ya19pZF8jfiEKBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:bell", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTNAQAACAQAbmFtZQ4AbWluZWNyYWZ0OmJlbGwECQBuYW1lX2hhc2iPqsgDXRcsxAMKAG5ldHdvcmtfaWT7zhOoCgYAc3RhdGVzCAoAYXR0YWNobWVudAgAc3RhbmRpbmcDCQBkaXJlY3Rpb24AAAAAAQoAdG9nZ2xlX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTNAQAACAQAbmFtZQ4AbWluZWNyYWZ0OmJlbGwECQBuYW1lX2hhc2iPqsgDXRcsxAMKAG5ldHdvcmtfaWT7zhOoCgYAc3RhdGVzCAoAYXR0YWNobWVudAgAc3RhbmRpbmcDCQBkaXJlY3Rpb24AAAAAAQoAdG9nZ2xlX2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:conduit", - "block_state_b64": "CgAAAwgAYmxvY2tfaWScAQAACAQAbmFtZREAbWluZWNyYWZ0OmNvbmR1aXQECQBuYW1lX2hhc2jqxKAxq2EaWQMKAG5ldHdvcmtfaWTWcBVnCgYAc3RhdGVzAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWScAQAACAQAbmFtZREAbWluZWNyYWZ0OmNvbmR1aXQECQBuYW1lX2hhc2jqxKAxq2EaWQMKAG5ldHdvcmtfaWTWcBVnCgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:stonecutter_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTEAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lY3V0dGVyX2Jsb2NrBAkAbmFtZV9oYXNoQAXTbAM3MeYDCgBuZXR3b3JrX2lkWS4RjAoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAG5vcnRoAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTEAQAACAQAbmFtZRsAbWluZWNyYWZ0OnN0b25lY3V0dGVyX2Jsb2NrBAkAbmFtZV9oYXNoQAXTbAM3MeYDCgBuZXR3b3JrX2lkWS4RjAoGAHN0YXRlcwgcAG1pbmVjcmFmdDpjYXJkaW5hbF9kaXJlY3Rpb24FAG5vcnRoAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:coal" @@ -4633,6 +4955,9 @@ { "id": "minecraft:turtle_scute" }, + { + "id": "minecraft:armadillo_scute" + }, { "id": "minecraft:phantom_membrane" }, @@ -4663,6 +4988,13 @@ { "id": "minecraft:blaze_rod" }, + { + "id": "minecraft:breeze_rod" + }, + { + "id": "minecraft:heavy_core", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ7AgAACAQAbmFtZRQAbWluZWNyYWZ0OmhlYXZ5X2NvcmUECQBuYW1lX2hhc2hhz/uNCtrC2QMKAG5ldHdvcmtfaWRaFu+8CgYAc3RhdGVzAAMHAHZlcnNpb24DABUBAA==" + }, { "id": "minecraft:blaze_powder" }, @@ -4698,11 +5030,11 @@ }, { "id": "minecraft:end_rod", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTQAAAACAQAbmFtZREAbWluZWNyYWZ0OmVuZF9yb2QECQBuYW1lX2hhc2jx/q5cEA0hmQMKAG5ldHdvcmtfaWQ2eM8kCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTQAAAACAQAbmFtZREAbWluZWNyYWZ0OmVuZF9yb2QECQBuYW1lX2hhc2jx/q5cEA0hmQMKAG5ldHdvcmtfaWQ2eM8kCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:lightning_rod", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQ3AgAACAQAbmFtZRcAbWluZWNyYWZ0OmxpZ2h0bmluZ19yb2QECQBuYW1lX2hhc2ioXQF1xvfHNQMKAG5ldHdvcmtfaWRLuHyACgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ3AgAACAQAbmFtZRcAbWluZWNyYWZ0OmxpZ2h0bmluZ19yb2QECQBuYW1lX2hhc2ioXQF1xvfHNQMKAG5ldHdvcmtfaWRLuHyACgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:end_crystal" @@ -4716,6 +5048,9 @@ { "id": "minecraft:writable_book" }, + { + "id": "minecraft:trial_key" + }, { "id": "minecraft:enchanted_book", "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQAAAIDAGx2bAEAAAA=" @@ -5156,6 +5491,54 @@ "id": "minecraft:enchanted_book", "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQlAAIDAGx2bAMAAAA=" }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQmAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQmAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQmAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQnAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQnAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQnAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQnAAIDAGx2bAQAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQnAAIDAGx2bAUAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQoAAIDAGx2bAEAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQoAAIDAGx2bAIAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQoAAIDAGx2bAMAAAA=" + }, + { + "id": "minecraft:enchanted_book", + "nbt_b64": "CgAACQQAZW5jaAoBAAAAAgIAaWQoAAIDAGx2bAQAAAA=" + }, { "id": "minecraft:oak_boat" }, @@ -5212,19 +5595,19 @@ }, { "id": "minecraft:rail", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRCAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnJhaWwECQBuYW1lX2hhc2hUzmhUXYJDUQMKAG5ldHdvcmtfaWR+Sp6YCgYAc3RhdGVzAw4AcmFpbF9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRCAAAACAQAbmFtZQ4AbWluZWNyYWZ0OnJhaWwECQBuYW1lX2hhc2hUzmhUXYJDUQMKAG5ldHdvcmtfaWR+Sp6YCgYAc3RhdGVzAw4AcmFpbF9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:golden_rail", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQbAAAACAQAbmFtZRUAbWluZWNyYWZ0OmdvbGRlbl9yYWlsBAkAbmFtZV9oYXNoOoV5MaKipoUDCgBuZXR3b3JrX2lkfAcxLwoGAHN0YXRlcwENAHJhaWxfZGF0YV9iaXQAAw4AcmFpbF9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQbAAAACAQAbmFtZRUAbWluZWNyYWZ0OmdvbGRlbl9yYWlsBAkAbmFtZV9oYXNoOoV5MaKipoUDCgBuZXR3b3JrX2lkfAcxLwoGAHN0YXRlcwENAHJhaWxfZGF0YV9iaXQAAw4AcmFpbF9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:detector_rail", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQcAAAACAQAbmFtZRcAbWluZWNyYWZ0OmRldGVjdG9yX3JhaWwECQBuYW1lX2hhc2gVUk31qOysUQMKAG5ldHdvcmtfaWRVW/aICgYAc3RhdGVzAQ0AcmFpbF9kYXRhX2JpdAADDgByYWlsX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQcAAAACAQAbmFtZRcAbWluZWNyYWZ0OmRldGVjdG9yX3JhaWwECQBuYW1lX2hhc2gVUk31qOysUQMKAG5ldHdvcmtfaWRVW/aICgYAc3RhdGVzAQ0AcmFpbF9kYXRhX2JpdAADDgByYWlsX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:activator_rail", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR+AAAACAQAbmFtZRgAbWluZWNyYWZ0OmFjdGl2YXRvcl9yYWlsBAkAbmFtZV9oYXNosIL91qriCRkDCgBuZXR3b3JrX2lkZfckmwoGAHN0YXRlcwENAHJhaWxfZGF0YV9iaXQAAw4AcmFpbF9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWR+AAAACAQAbmFtZRgAbWluZWNyYWZ0OmFjdGl2YXRvcl9yYWlsBAkAbmFtZV9oYXNosIL91qriCRkDCgBuZXR3b3JrX2lkZfckmwoGAHN0YXRlcwENAHJhaWxfZGF0YV9iaXQAAw4AcmFpbF9kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:minecart" @@ -5243,139 +5626,139 @@ }, { "id": "minecraft:redstone_block", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSYAAAACAQAbmFtZRgAbWluZWNyYWZ0OnJlZHN0b25lX2Jsb2NrBAkAbmFtZV9oYXNoRhULL0r8o0sDCgBuZXR3b3JrX2lklayOHgoGAHN0YXRlcwADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSYAAAACAQAbmFtZRgAbWluZWNyYWZ0OnJlZHN0b25lX2Jsb2NrBAkAbmFtZV9oYXNoRhULL0r8o0sDCgBuZXR3b3JrX2lklayOHgoGAHN0YXRlcwADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:redstone_torch", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRMAAAACAQAbmFtZRgAbWluZWNyYWZ0OnJlZHN0b25lX3RvcmNoBAkAbmFtZV9oYXNoizFRjpYMIDgDCgBuZXR3b3JrX2lkuHz7yAoGAHN0YXRlcwgWAHRvcmNoX2ZhY2luZ19kaXJlY3Rpb24HAHVua25vd24AAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRMAAAACAQAbmFtZRgAbWluZWNyYWZ0OnJlZHN0b25lX3RvcmNoBAkAbmFtZV9oYXNoizFRjpYMIDgDCgBuZXR3b3JrX2lkuHz7yAoGAHN0YXRlcwgWAHRvcmNoX2ZhY2luZ19kaXJlY3Rpb24HAHVua25vd24AAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:lever", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRFAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmxldmVyBAkAbmFtZV9oYXNoGMJeLJsUMLYDCgBuZXR3b3JrX2lkEF/GuAoGAHN0YXRlcwgPAGxldmVyX2RpcmVjdGlvbg4AZG93bl9lYXN0X3dlc3QBCABvcGVuX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRFAAAACAQAbmFtZQ8AbWluZWNyYWZ0OmxldmVyBAkAbmFtZV9oYXNoGMJeLJsUMLYDCgBuZXR3b3JrX2lkEF/GuAoGAHN0YXRlcwgPAGxldmVyX2RpcmVjdGlvbg4AZG93bl9lYXN0X3dlc3QBCABvcGVuX2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:wooden_button", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSPAAAACAQAbmFtZRcAbWluZWNyYWZ0Ondvb2Rlbl9idXR0b24ECQBuYW1lX2hhc2hR7PgSTQt0sQMKAG5ldHdvcmtfaWSU07kYCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSPAAAACAQAbmFtZRcAbWluZWNyYWZ0Ondvb2Rlbl9idXR0b24ECQBuYW1lX2hhc2hR7PgSTQt0sQMKAG5ldHdvcmtfaWSU07kYCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:spruce_button", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSPAQAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9idXR0b24ECQBuYW1lX2hhc2jBW9Z8aYE7YQMKAG5ldHdvcmtfaWTkUIGuCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSPAQAACAQAbmFtZRcAbWluZWNyYWZ0OnNwcnVjZV9idXR0b24ECQBuYW1lX2hhc2jBW9Z8aYE7YQMKAG5ldHdvcmtfaWTkUIGuCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:birch_button", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSMAQAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX2J1dHRvbgQJAG5hbWVfaGFzaJXYgGuSHbTwAwoAbmV0d29ya19pZGWp3yoKBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSMAQAACAQAbmFtZRYAbWluZWNyYWZ0OmJpcmNoX2J1dHRvbgQJAG5hbWVfaGFzaJXYgGuSHbTwAwoAbmV0d29ya19pZGWp3yoKBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:jungle_button", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSOAQAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9idXR0b24ECQBuYW1lX2hhc2iCgNANcJs+BQMKAG5ldHdvcmtfaWT9fImWCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSOAQAACAQAbmFtZRcAbWluZWNyYWZ0Omp1bmdsZV9idXR0b24ECQBuYW1lX2hhc2iCgNANcJs+BQMKAG5ldHdvcmtfaWT9fImWCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:acacia_button", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAQAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9idXR0b24ECQBuYW1lX2hhc2gVvmcT7LTO0wMKAG5ldHdvcmtfaWRQnxIJCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSLAQAACAQAbmFtZRcAbWluZWNyYWZ0OmFjYWNpYV9idXR0b24ECQBuYW1lX2hhc2gVvmcT7LTO0wMKAG5ldHdvcmtfaWRQnxIJCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:dark_oak_button", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSNAQAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX2J1dHRvbgQJAG5hbWVfaGFzaIV10ZGGrCIEAwoAbmV0d29ya19pZN5vAmIKBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSNAQAACAQAbmFtZRkAbWluZWNyYWZ0OmRhcmtfb2FrX2J1dHRvbgQJAG5hbWVfaGFzaIV10ZGGrCIEAwoAbmV0d29ya19pZN5vAmIKBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:mangrove_button", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTmAgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX2J1dHRvbgQJAG5hbWVfaGFzaNzeYYKLgOzJAwoAbmV0d29ya19pZAFEGQ0KBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTmAgAACAQAbmFtZRkAbWluZWNyYWZ0Om1hbmdyb3ZlX2J1dHRvbgQJAG5hbWVfaGFzaNzeYYKLgOzJAwoAbmV0d29ya19pZAFEGQ0KBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:cherry_button", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQRAwAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9idXR0b24ECQBuYW1lX2hhc2j2/IHjeAbUcwMKAG5ldHdvcmtfaWRJ1irQCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQRAwAACAQAbmFtZRcAbWluZWNyYWZ0OmNoZXJyeV9idXR0b24ECQBuYW1lX2hhc2j2/IHjeAbUcwMKAG5ldHdvcmtfaWRJ1irQCgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:bamboo_button", - "block_state_b64": "CgAAAwgAYmxvY2tfaWT+AgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19idXR0b24ECQBuYW1lX2hhc2j7AddMi+6nsgMKAG5ldHdvcmtfaWSa9w4/CgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWT+AgAACAQAbmFtZRcAbWluZWNyYWZ0OmJhbWJvb19idXR0b24ECQBuYW1lX2hhc2j7AddMi+6nsgMKAG5ldHdvcmtfaWSa9w4/CgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:stone_button", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRNAAAACAQAbmFtZRYAbWluZWNyYWZ0OnN0b25lX2J1dHRvbgQJAG5hbWVfaGFzaM4ejMctmvohAwoAbmV0d29ya19pZMw+aC0KBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRNAAAACAQAbmFtZRYAbWluZWNyYWZ0OnN0b25lX2J1dHRvbgQJAG5hbWVfaGFzaM4ejMctmvohAwoAbmV0d29ya19pZMw+aC0KBgBzdGF0ZXMBEgBidXR0b25fcHJlc3NlZF9iaXQAAxAAZmFjaW5nX2RpcmVjdGlvbgAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:crimson_button", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAgAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fYnV0dG9uBAkAbmFtZV9oYXNofnjYHaYIeWgDCgBuZXR3b3JrX2lk+n1vyQoGAHN0YXRlcwESAGJ1dHRvbl9wcmVzc2VkX2JpdAADEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQDAgAACAQAbmFtZRgAbWluZWNyYWZ0OmNyaW1zb25fYnV0dG9uBAkAbmFtZV9oYXNofnjYHaYIeWgDCgBuZXR3b3JrX2lk+n1vyQoGAHN0YXRlcwESAGJ1dHRvbl9wcmVzc2VkX2JpdAADEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:warped_button", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQEAgAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9idXR0b24ECQBuYW1lX2hhc2jwkV2EU6Cn1QMKAG5ldHdvcmtfaWTnHnk1CgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQEAgAACAQAbmFtZRcAbWluZWNyYWZ0OndhcnBlZF9idXR0b24ECQBuYW1lX2hhc2jwkV2EU6Cn1QMKAG5ldHdvcmtfaWTnHnk1CgYAc3RhdGVzARIAYnV0dG9uX3ByZXNzZWRfYml0AAMQAGZhY2luZ19kaXJlY3Rpb24AAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:polished_blackstone_button", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQnAgAACAQAbmFtZSQAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnV0dG9uBAkAbmFtZV9oYXNojmxzQKS0S/EDCgBuZXR3b3JrX2lkDtQ95woGAHN0YXRlcwESAGJ1dHRvbl9wcmVzc2VkX2JpdAADEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQnAgAACAQAbmFtZSQAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfYnV0dG9uBAkAbmFtZV9oYXNojmxzQKS0S/EDCgBuZXR3b3JrX2lkDtQ95woGAHN0YXRlcwESAGJ1dHRvbl9wcmVzc2VkX2JpdAADEABmYWNpbmdfZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:tripwire_hook", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAAAACAQAbmFtZRcAbWluZWNyYWZ0OnRyaXB3aXJlX2hvb2sECQBuYW1lX2hhc2gQdp+oGZLNnAMKAG5ldHdvcmtfaWSy+1KJCgYAc3RhdGVzAQwAYXR0YWNoZWRfYml0AAMJAGRpcmVjdGlvbgAAAAABCwBwb3dlcmVkX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSDAAAACAQAbmFtZRcAbWluZWNyYWZ0OnRyaXB3aXJlX2hvb2sECQBuYW1lX2hhc2gQdp+oGZLNnAMKAG5ldHdvcmtfaWSy+1KJCgYAc3RhdGVzAQwAYXR0YWNoZWRfYml0AAMJAGRpcmVjdGlvbgAAAAABCwBwb3dlcmVkX2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:wooden_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRIAAAACAQAbmFtZR8AbWluZWNyYWZ0Ondvb2Rlbl9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaGkGs5kCuA74AwoAbmV0d29ya19pZDRzPNwKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRIAAAACAQAbmFtZR8AbWluZWNyYWZ0Ondvb2Rlbl9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaGkGs5kCuA74AwoAbmV0d29ya19pZDRzPNwKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:spruce_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSZAQAACAQAbmFtZR8AbWluZWNyYWZ0OnNwcnVjZV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaNmwuq549fJKAwoAbmV0d29ya19pZLQMCw0KBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSZAQAACAQAbmFtZR8AbWluZWNyYWZ0OnNwcnVjZV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaNmwuq549fJKAwoAbmV0d29ya19pZLQMCw0KBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:birch_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSWAQAACAQAbmFtZR4AbWluZWNyYWZ0OmJpcmNoX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNorQkT9kDdlTwDCgBuZXR3b3JrX2lkH0G97AoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSWAQAACAQAbmFtZR4AbWluZWNyYWZ0OmJpcmNoX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNorQkT9kDdlTwDCgBuZXR3b3JrX2lkH0G97AoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:jungle_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSYAQAACAQAbmFtZR8AbWluZWNyYWZ0Omp1bmdsZV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaJ7DcteCkb8/AwoAbmV0d29ya19pZLdPBSAKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSYAQAACAQAbmFtZR8AbWluZWNyYWZ0Omp1bmdsZV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaJ7DcteCkb8/AwoAbmV0d29ya19pZLdPBSAKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:acacia_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSVAQAACAQAbmFtZR8AbWluZWNyYWZ0OmFjYWNpYV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaC2frZtfoYqCAwoAbmV0d29ya19pZIDdI18KBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSVAQAACAQAbmFtZR8AbWluZWNyYWZ0OmFjYWNpYV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaC2frZtfoYqCAwoAbmV0d29ya19pZIDdI18KBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:dark_oak_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSXAQAACAQAbmFtZSEAbWluZWNyYWZ0OmRhcmtfb2FrX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoHUCJsTy52pwDCgBuZXR3b3JrX2lkKpi8rAoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSXAQAACAQAbmFtZSEAbWluZWNyYWZ0OmRhcmtfb2FrX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoHUCJsTy52pwDCgBuZXR3b3JrX2lkKpi8rAoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:mangrove_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTpAgAACAQAbmFtZSEAbWluZWNyYWZ0Om1hbmdyb3ZlX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoiDsTfJaX100DCgBuZXR3b3JrX2lkuwWDyQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTpAgAACAQAbmFtZSEAbWluZWNyYWZ0Om1hbmdyb3ZlX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoiDsTfJaX100DCgBuZXR3b3JrX2lkuwWDyQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:cherry_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQZAwAACAQAbmFtZR8AbWluZWNyYWZ0OmNoZXJyeV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaALMqYEZDUQHAwoAbmV0d29ya19pZPNT+r0KBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQZAwAACAQAbmFtZR8AbWluZWNyYWZ0OmNoZXJyeV9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaALMqYEZDUQHAwoAbmV0d29ya19pZPNT+r0KBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:bamboo_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQBAwAACAQAbmFtZR8AbWluZWNyYWZ0OmJhbWJvb19wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaNvxJ7NIAaqlAwoAbmV0d29ya19pZIZ8XnYKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQBAwAACAQAbmFtZR8AbWluZWNyYWZ0OmJhbWJvb19wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaNvxJ7NIAaqlAwoAbmV0d29ya19pZIZ8XnYKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:crimson_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQFAgAACAQAbmFtZSAAbWluZWNyYWZ0OmNyaW1zb25fcHJlc3N1cmVfcGxhdGUECQBuYW1lX2hhc2hqBDVDAd31/gMKAG5ldHdvcmtfaWRmV18LCgYAc3RhdGVzAw8AcmVkc3RvbmVfc2lnbmFsAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQFAgAACAQAbmFtZSAAbWluZWNyYWZ0OmNyaW1zb25fcHJlc3N1cmVfcGxhdGUECQBuYW1lX2hhc2hqBDVDAd31/gMKAG5ldHdvcmtfaWRmV18LCgYAc3RhdGVzAw8AcmVkc3RvbmVfc2lnbmFsAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:warped_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAgAACAQAbmFtZR8AbWluZWNyYWZ0OndhcnBlZF9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaBxFoQksWtYUAwoAbmV0d29ya19pZJVRoIcKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQGAgAACAQAbmFtZR8AbWluZWNyYWZ0OndhcnBlZF9wcmVzc3VyZV9wbGF0ZQQJAG5hbWVfaGFzaBxFoQksWtYUAwoAbmV0d29ya19pZJVRoIcKBgBzdGF0ZXMDDwByZWRzdG9uZV9zaWduYWwAAAAAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:stone_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWRGAAAACAQAbmFtZR4AbWluZWNyYWZ0OnN0b25lX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNounJuTBUTrU8DCgBuZXR3b3JrX2lkjDydwQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWRGAAAACAQAbmFtZR4AbWluZWNyYWZ0OnN0b25lX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNounJuTBUTrU8DCgBuZXR3b3JrX2lkjDydwQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:light_weighted_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSTAAAACAQAbmFtZScAbWluZWNyYWZ0OmxpZ2h0X3dlaWdodGVkX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoOyOJkNxLtkEDCgBuZXR3b3JrX2lkrr2AjgoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSTAAAACAQAbmFtZScAbWluZWNyYWZ0OmxpZ2h0X3dlaWdodGVkX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoOyOJkNxLtkEDCgBuZXR3b3JrX2lkrr2AjgoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:heavy_weighted_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSUAAAACAQAbmFtZScAbWluZWNyYWZ0OmhlYXZ5X3dlaWdodGVkX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoltgDmDvTajUDCgBuZXR3b3JrX2lkFxVKuQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSUAAAACAQAbmFtZScAbWluZWNyYWZ0OmhlYXZ5X3dlaWdodGVkX3ByZXNzdXJlX3BsYXRlBAkAbmFtZV9oYXNoltgDmDvTajUDCgBuZXR3b3JrX2lkFxVKuQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:polished_blackstone_pressure_plate", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAgAACAQAbmFtZSwAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfcHJlc3N1cmVfcGxhdGUECQBuYW1lX2hhc2h65Ci6/CeGqwMKAG5ldHdvcmtfaWTaSW5xCgYAc3RhdGVzAw8AcmVkc3RvbmVfc2lnbmFsAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAgAACAQAbmFtZSwAbWluZWNyYWZ0OnBvbGlzaGVkX2JsYWNrc3RvbmVfcHJlc3N1cmVfcGxhdGUECQBuYW1lX2hhc2h65Ci6/CeGqwMKAG5ldHdvcmtfaWTaSW5xCgYAc3RhdGVzAw8AcmVkc3RvbmVfc2lnbmFsAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:observer", - "block_state_b64": "CgAAAwgAYmxvY2tfaWT7AAAACAQAbmFtZRIAbWluZWNyYWZ0Om9ic2VydmVyBAkAbmFtZV9oYXNoYhlh1lpmHTgDCgBuZXR3b3JrX2lkQEh55goGAHN0YXRlcwgaAG1pbmVjcmFmdDpmYWNpbmdfZGlyZWN0aW9uBABkb3duAQsAcG93ZXJlZF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWT7AAAACAQAbmFtZRIAbWluZWNyYWZ0Om9ic2VydmVyBAkAbmFtZV9oYXNoYhlh1lpmHTgDCgBuZXR3b3JrX2lkQEh55goGAHN0YXRlcwgaAG1pbmVjcmFmdDpmYWNpbmdfZGlyZWN0aW9uBABkb3duAQsAcG93ZXJlZF9iaXQAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:daylight_detector", - "block_state_b64": "CgAAAwgAYmxvY2tfaWSXAAAACAQAbmFtZRsAbWluZWNyYWZ0OmRheWxpZ2h0X2RldGVjdG9yBAkAbmFtZV9oYXNoV0F0s7B7PVgDCgBuZXR3b3JrX2lkri5afQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWSXAAAACAQAbmFtZRsAbWluZWNyYWZ0OmRheWxpZ2h0X2RldGVjdG9yBAkAbmFtZV9oYXNoV0F0s7B7PVgDCgBuZXR3b3JrX2lkri5afQoGAHN0YXRlcwMPAHJlZHN0b25lX3NpZ25hbAAAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:repeater" @@ -5388,30 +5771,34 @@ }, { "id": "minecraft:dropper", - "block_state_b64": "CgAAAwgAYmxvY2tfaWR9AAAACAQAbmFtZREAbWluZWNyYWZ0OmRyb3BwZXIECQBuYW1lX2hhc2joXP7XqU0l3QMKAG5ldHdvcmtfaWQfQN6zCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgMAAAABDQB0cmlnZ2VyZWRfYml0AAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWR9AAAACAQAbmFtZREAbWluZWNyYWZ0OmRyb3BwZXIECQBuYW1lX2hhc2joXP7XqU0l3QMKAG5ldHdvcmtfaWQfQN6zCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgMAAAABDQB0cmlnZ2VyZWRfYml0AAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:dispenser", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQXAAAACAQAbmFtZRMAbWluZWNyYWZ0OmRpc3BlbnNlcgQJAG5hbWVfaGFzaP1RR+zAbYP2AwoAbmV0d29ya19pZGAayD0KBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAwAAAAENAHRyaWdnZXJlZF9iaXQAAAMHAHZlcnNpb24ERhQBAA==" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQXAAAACAQAbmFtZRMAbWluZWNyYWZ0OmRpc3BlbnNlcgQJAG5hbWVfaGFzaP1RR+zAbYP2AwoAbmV0d29ya19pZGAayD0KBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAwAAAAENAHRyaWdnZXJlZF9iaXQAAAMHAHZlcnNpb24DABUBAA==" + }, + { + "id": "minecraft:crafter", + "block_state_b64": "CgAAAwgAYmxvY2tfaWQ4AgAACAQAbmFtZREAbWluZWNyYWZ0OmNyYWZ0ZXIECQBuYW1lX2hhc2iLCT/rJmRN8QMKAG5ldHdvcmtfaWTPTbvrCgYAc3RhdGVzAQgAY3JhZnRpbmcACAsAb3JpZW50YXRpb24JAGRvd25fZWFzdAENAHRyaWdnZXJlZF9iaXQAAAMHAHZlcnNpb24DABUBAA==" }, { "id": "minecraft:piston", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQhAAAACAQAbmFtZRAAbWluZWNyYWZ0OnBpc3RvbgQJAG5hbWVfaGFzaDs3AFh1fL0uAwoAbmV0d29ya19pZLD/5XQKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAQAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQhAAAACAQAbmFtZRAAbWluZWNyYWZ0OnBpc3RvbgQJAG5hbWVfaGFzaDs3AFh1fL0uAwoAbmV0d29ya19pZLD/5XQKBgBzdGF0ZXMDEABmYWNpbmdfZGlyZWN0aW9uAQAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:sticky_piston", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQdAAAACAQAbmFtZRcAbWluZWNyYWZ0OnN0aWNreV9waXN0b24ECQBuYW1lX2hhc2hPFJFJSiJ0ZQMKAG5ldHdvcmtfaWT/MzCJCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgEAAAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQdAAAACAQAbmFtZRcAbWluZWNyYWZ0OnN0aWNreV9waXN0b24ECQBuYW1lX2hhc2hPFJFJSiJ0ZQMKAG5ldHdvcmtfaWT/MzCJCgYAc3RhdGVzAxAAZmFjaW5nX2RpcmVjdGlvbgEAAAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:tnt", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQuAAAACAQAbmFtZQ0AbWluZWNyYWZ0OnRudAQJAG5hbWVfaGFzaEYOHwCvJH29AwoAbmV0d29ya19pZCGfjU4KBgBzdGF0ZXMBFABhbGxvd191bmRlcndhdGVyX2JpdAABCwBleHBsb2RlX2JpdAAAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQuAAAACAQAbmFtZQ0AbWluZWNyYWZ0OnRudAQJAG5hbWVfaGFzaEYOHwCvJH29AwoAbmV0d29ya19pZCGfjU4KBgBzdGF0ZXMBFABhbGxvd191bmRlcndhdGVyX2JpdAABCwBleHBsb2RlX2JpdAAAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:name_tag" }, { "id": "minecraft:loom", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTLAQAACAQAbmFtZQ4AbWluZWNyYWZ0Omxvb20ECQBuYW1lX2hhc2i7DKjAXNq8TAMKAG5ldHdvcmtfaWR/49HXCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTLAQAACAQAbmFtZQ4AbWluZWNyYWZ0Omxvb20ECQBuYW1lX2hhc2i7DKjAXNq8TAMKAG5ldHdvcmtfaWR/49HXCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:banner", @@ -5521,6 +5908,12 @@ { "id": "minecraft:globe_banner_pattern" }, + { + "id": "minecraft:flow_banner_pattern" + }, + { + "id": "minecraft:guster_banner_pattern" + }, { "id": "minecraft:angler_pottery_sherd" }, @@ -5545,9 +5938,15 @@ { "id": "minecraft:explorer_pottery_sherd" }, + { + "id": "minecraft:flow_pottery_sherd" + }, { "id": "minecraft:friend_pottery_sherd" }, + { + "id": "minecraft:guster_pottery_sherd" + }, { "id": "minecraft:heart_pottery_sherd" }, @@ -5569,6 +5968,9 @@ { "id": "minecraft:prize_pottery_sherd" }, + { + "id": "minecraft:scrape_pottery_sherd" + }, { "id": "minecraft:sheaf_pottery_sherd" }, @@ -5632,6 +6034,12 @@ { "id": "minecraft:spire_armor_trim_smithing_template" }, + { + "id": "minecraft:flow_armor_trim_smithing_template" + }, + { + "id": "minecraft:bolt_armor_trim_smithing_template" + }, { "id": "minecraft:firework_rocket", "nbt_b64": "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwAAAAAAAQYARmxpZ2h0AQAA" @@ -5784,11 +6192,11 @@ }, { "id": "minecraft:target", - "block_state_b64": "CgAAAwgAYmxvY2tfaWTuAQAACAQAbmFtZRAAbWluZWNyYWZ0OnRhcmdldAQJAG5hbWVfaGFzaJc66SVbYlaxAwoAbmV0d29ya19pZPBozs0KBgBzdGF0ZXMAAwcAdmVyc2lvbgRGFAEA" + "block_state_b64": "CgAAAwgAYmxvY2tfaWTuAQAACAQAbmFtZRAAbWluZWNyYWZ0OnRhcmdldAQJAG5hbWVfaGFzaJc66SVbYlaxAwoAbmV0d29ya19pZPBozs0KBgBzdGF0ZXMAAwcAdmVyc2lvbgMAFQEA" }, { "id": "minecraft:decorated_pot", - "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAwAACAQAbmFtZRcAbWluZWNyYWZ0OmRlY29yYXRlZF9wb3QECQBuYW1lX2hhc2jjQgckn8VTvwMKAG5ldHdvcmtfaWRwvkUUCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uBEYUAQA=" + "block_state_b64": "CgAAAwgAYmxvY2tfaWQmAwAACAQAbmFtZRcAbWluZWNyYWZ0OmRlY29yYXRlZF9wb3QECQBuYW1lX2hhc2jjQgckn8VTvwMKAG5ldHdvcmtfaWRwvkUUCgYAc3RhdGVzAwkAZGlyZWN0aW9uAAAAAAADBwB2ZXJzaW9uAwAVAQA=" }, { "id": "minecraft:lodestone_compass" @@ -5798,6 +6206,9 @@ }, { "id": "minecraft:ender_dragon_spawn_egg" + }, + { + "id": "minecraft:ominous_trial_key" } ] } \ No newline at end of file diff --git a/core/src/main/resources/bedrock/entity_identifiers.dat b/core/src/main/resources/bedrock/entity_identifiers.dat index 9a123f8d8834e6af5c98b000778665b6e2022887..e7cdeb08e65d446bef173af7cea4bc56d5023df3 100644 GIT binary patch delta 204 zcmeCT`{lsP#lXpynUa%PT*B4BG})0+V)7Yo?u`b#lKSeonR%(nMTu!8R!K#vsa2`* z<(YXY@yQv9Md_*W1x5K;smUdoIjPLdMVTqHm?j$ts7?zsAI&p#=FT`rF%nYW<3waEAlk(HkQ&Yeq N3qT^mlTXXJ006xXMWO%z delta 39 vcmez6&~L}f#lXpynUa%PT*CE@ak3+$#N;#F+#3yeB{%Cx^|4MiQ*Z$Q^=b>+ diff --git a/core/src/main/resources/bedrock/runtime_item_states.1_20_40.json b/core/src/main/resources/bedrock/runtime_item_states.1_20_40.json deleted file mode 100644 index 861b29c8a..000000000 --- a/core/src/main/resources/bedrock/runtime_item_states.1_20_40.json +++ /dev/null @@ -1,5570 +0,0 @@ -[ - { - "name": "minecraft:acacia_boat", - "id": 381 - }, - { - "name": "minecraft:acacia_button", - "id": -140 - }, - { - "name": "minecraft:acacia_chest_boat", - "id": 649 - }, - { - "name": "minecraft:acacia_door", - "id": 563 - }, - { - "name": "minecraft:acacia_fence", - "id": -575 - }, - { - "name": "minecraft:acacia_fence_gate", - "id": 187 - }, - { - "name": "minecraft:acacia_hanging_sign", - "id": -504 - }, - { - "name": "minecraft:acacia_log", - "id": 162 - }, - { - "name": "minecraft:acacia_pressure_plate", - "id": -150 - }, - { - "name": "minecraft:acacia_sign", - "id": 586 - }, - { - "name": "minecraft:acacia_stairs", - "id": 163 - }, - { - "name": "minecraft:acacia_standing_sign", - "id": -190 - }, - { - "name": "minecraft:acacia_trapdoor", - "id": -145 - }, - { - "name": "minecraft:acacia_wall_sign", - "id": -191 - }, - { - "name": "minecraft:activator_rail", - "id": 126 - }, - { - "name": "minecraft:agent_spawn_egg", - "id": 489 - }, - { - "name": "minecraft:air", - "id": -158 - }, - { - "name": "minecraft:allay_spawn_egg", - "id": 638 - }, - { - "name": "minecraft:allow", - "id": 210 - }, - { - "name": "minecraft:amethyst_block", - "id": -327 - }, - { - "name": "minecraft:amethyst_cluster", - "id": -329 - }, - { - "name": "minecraft:amethyst_shard", - "id": 631 - }, - { - "name": "minecraft:ancient_debris", - "id": -271 - }, - { - "name": "minecraft:andesite_stairs", - "id": -171 - }, - { - "name": "minecraft:angler_pottery_sherd", - "id": 663 - }, - { - "name": "minecraft:anvil", - "id": 145 - }, - { - "name": "minecraft:apple", - "id": 257 - }, - { - "name": "minecraft:archer_pottery_sherd", - "id": 664 - }, - { - "name": "minecraft:armor_stand", - "id": 559 - }, - { - "name": "minecraft:arms_up_pottery_sherd", - "id": 665 - }, - { - "name": "minecraft:arrow", - "id": 303 - }, - { - "name": "minecraft:axolotl_bucket", - "id": 371 - }, - { - "name": "minecraft:axolotl_spawn_egg", - "id": 503 - }, - { - "name": "minecraft:azalea", - "id": -337 - }, - { - "name": "minecraft:azalea_leaves", - "id": -324 - }, - { - "name": "minecraft:azalea_leaves_flowered", - "id": -325 - }, - { - "name": "minecraft:baked_potato", - "id": 281 - }, - { - "name": "minecraft:balloon", - "id": 605 - }, - { - "name": "minecraft:bamboo", - "id": -163 - }, - { - "name": "minecraft:bamboo_block", - "id": -527 - }, - { - "name": "minecraft:bamboo_button", - "id": -511 - }, - { - "name": "minecraft:bamboo_chest_raft", - "id": 661 - }, - { - "name": "minecraft:bamboo_door", - "id": -517 - }, - { - "name": "minecraft:bamboo_double_slab", - "id": -521 - }, - { - "name": "minecraft:bamboo_fence", - "id": -515 - }, - { - "name": "minecraft:bamboo_fence_gate", - "id": -516 - }, - { - "name": "minecraft:bamboo_hanging_sign", - "id": -522 - }, - { - "name": "minecraft:bamboo_mosaic", - "id": -509 - }, - { - "name": "minecraft:bamboo_mosaic_double_slab", - "id": -525 - }, - { - "name": "minecraft:bamboo_mosaic_slab", - "id": -524 - }, - { - "name": "minecraft:bamboo_mosaic_stairs", - "id": -523 - }, - { - "name": "minecraft:bamboo_planks", - "id": -510 - }, - { - "name": "minecraft:bamboo_pressure_plate", - "id": -514 - }, - { - "name": "minecraft:bamboo_raft", - "id": 660 - }, - { - "name": "minecraft:bamboo_sapling", - "id": -164 - }, - { - "name": "minecraft:bamboo_sign", - "id": 659 - }, - { - "name": "minecraft:bamboo_slab", - "id": -513 - }, - { - "name": "minecraft:bamboo_stairs", - "id": -512 - }, - { - "name": "minecraft:bamboo_standing_sign", - "id": -518 - }, - { - "name": "minecraft:bamboo_trapdoor", - "id": -520 - }, - { - "name": "minecraft:bamboo_wall_sign", - "id": -519 - }, - { - "name": "minecraft:banner", - "id": 574 - }, - { - "name": "minecraft:banner_pattern", - "id": 716 - }, - { - "name": "minecraft:barrel", - "id": -203 - }, - { - "name": "minecraft:barrier", - "id": -161 - }, - { - "name": "minecraft:basalt", - "id": -234 - }, - { - "name": "minecraft:bat_spawn_egg", - "id": 455 - }, - { - "name": "minecraft:beacon", - "id": 138 - }, - { - "name": "minecraft:bed", - "id": 420 - }, - { - "name": "minecraft:bedrock", - "id": 7 - }, - { - "name": "minecraft:bee_nest", - "id": -218 - }, - { - "name": "minecraft:bee_spawn_egg", - "id": 496 - }, - { - "name": "minecraft:beef", - "id": 273 - }, - { - "name": "minecraft:beehive", - "id": -219 - }, - { - "name": "minecraft:beetroot", - "id": 285 - }, - { - "name": "minecraft:beetroot_seeds", - "id": 295 - }, - { - "name": "minecraft:beetroot_soup", - "id": 286 - }, - { - "name": "minecraft:bell", - "id": -206 - }, - { - "name": "minecraft:big_dripleaf", - "id": -323 - }, - { - "name": "minecraft:birch_boat", - "id": 378 - }, - { - "name": "minecraft:birch_button", - "id": -141 - }, - { - "name": "minecraft:birch_chest_boat", - "id": 646 - }, - { - "name": "minecraft:birch_door", - "id": 561 - }, - { - "name": "minecraft:birch_fence", - "id": -576 - }, - { - "name": "minecraft:birch_fence_gate", - "id": 184 - }, - { - "name": "minecraft:birch_hanging_sign", - "id": -502 - }, - { - "name": "minecraft:birch_log", - "id": -570 - }, - { - "name": "minecraft:birch_pressure_plate", - "id": -151 - }, - { - "name": "minecraft:birch_sign", - "id": 584 - }, - { - "name": "minecraft:birch_stairs", - "id": 135 - }, - { - "name": "minecraft:birch_standing_sign", - "id": -186 - }, - { - "name": "minecraft:birch_trapdoor", - "id": -146 - }, - { - "name": "minecraft:birch_wall_sign", - "id": -187 - }, - { - "name": "minecraft:black_candle", - "id": -428 - }, - { - "name": "minecraft:black_candle_cake", - "id": -445 - }, - { - "name": "minecraft:black_carpet", - "id": -611 - }, - { - "name": "minecraft:black_concrete", - "id": -642 - }, - { - "name": "minecraft:black_concrete_powder", - "id": -723 - }, - { - "name": "minecraft:black_dye", - "id": 397 - }, - { - "name": "minecraft:black_glazed_terracotta", - "id": 235 - }, - { - "name": "minecraft:black_shulker_box", - "id": -627 - }, - { - "name": "minecraft:black_stained_glass", - "id": -687 - }, - { - "name": "minecraft:black_stained_glass_pane", - "id": -657 - }, - { - "name": "minecraft:black_terracotta", - "id": -738 - }, - { - "name": "minecraft:black_wool", - "id": -554 - }, - { - "name": "minecraft:blackstone", - "id": -273 - }, - { - "name": "minecraft:blackstone_double_slab", - "id": -283 - }, - { - "name": "minecraft:blackstone_slab", - "id": -282 - }, - { - "name": "minecraft:blackstone_stairs", - "id": -276 - }, - { - "name": "minecraft:blackstone_wall", - "id": -277 - }, - { - "name": "minecraft:blade_pottery_sherd", - "id": 666 - }, - { - "name": "minecraft:blast_furnace", - "id": -196 - }, - { - "name": "minecraft:blaze_powder", - "id": 431 - }, - { - "name": "minecraft:blaze_rod", - "id": 425 - }, - { - "name": "minecraft:blaze_spawn_egg", - "id": 458 - }, - { - "name": "minecraft:bleach", - "id": 603 - }, - { - "name": "minecraft:blue_candle", - "id": -424 - }, - { - "name": "minecraft:blue_candle_cake", - "id": -441 - }, - { - "name": "minecraft:blue_carpet", - "id": -607 - }, - { - "name": "minecraft:blue_concrete", - "id": -638 - }, - { - "name": "minecraft:blue_concrete_powder", - "id": -719 - }, - { - "name": "minecraft:blue_dye", - "id": 401 - }, - { - "name": "minecraft:blue_glazed_terracotta", - "id": 231 - }, - { - "name": "minecraft:blue_ice", - "id": -11 - }, - { - "name": "minecraft:blue_shulker_box", - "id": -623 - }, - { - "name": "minecraft:blue_stained_glass", - "id": -683 - }, - { - "name": "minecraft:blue_stained_glass_pane", - "id": -653 - }, - { - "name": "minecraft:blue_terracotta", - "id": -734 - }, - { - "name": "minecraft:blue_wool", - "id": -563 - }, - { - "name": "minecraft:boat", - "id": 714 - }, - { - "name": "minecraft:bone", - "id": 417 - }, - { - "name": "minecraft:bone_block", - "id": 216 - }, - { - "name": "minecraft:bone_meal", - "id": 413 - }, - { - "name": "minecraft:book", - "id": 389 - }, - { - "name": "minecraft:bookshelf", - "id": 47 - }, - { - "name": "minecraft:border_block", - "id": 212 - }, - { - "name": "minecraft:bordure_indented_banner_pattern", - "id": 593 - }, - { - "name": "minecraft:bow", - "id": 302 - }, - { - "name": "minecraft:bowl", - "id": 323 - }, - { - "name": "minecraft:brain_coral", - "id": -581 - }, - { - "name": "minecraft:bread", - "id": 261 - }, - { - "name": "minecraft:brewer_pottery_sherd", - "id": 667 - }, - { - "name": "minecraft:brewing_stand", - "id": 433 - }, - { - "name": "minecraft:brick", - "id": 385 - }, - { - "name": "minecraft:brick_block", - "id": 45 - }, - { - "name": "minecraft:brick_stairs", - "id": 108 - }, - { - "name": "minecraft:brown_candle", - "id": -425 - }, - { - "name": "minecraft:brown_candle_cake", - "id": -442 - }, - { - "name": "minecraft:brown_carpet", - "id": -608 - }, - { - "name": "minecraft:brown_concrete", - "id": -639 - }, - { - "name": "minecraft:brown_concrete_powder", - "id": -720 - }, - { - "name": "minecraft:brown_dye", - "id": 400 - }, - { - "name": "minecraft:brown_glazed_terracotta", - "id": 232 - }, - { - "name": "minecraft:brown_mushroom", - "id": 39 - }, - { - "name": "minecraft:brown_mushroom_block", - "id": 99 - }, - { - "name": "minecraft:brown_shulker_box", - "id": -624 - }, - { - "name": "minecraft:brown_stained_glass", - "id": -684 - }, - { - "name": "minecraft:brown_stained_glass_pane", - "id": -654 - }, - { - "name": "minecraft:brown_terracotta", - "id": -735 - }, - { - "name": "minecraft:brown_wool", - "id": -555 - }, - { - "name": "minecraft:brush", - "id": 683 - }, - { - "name": "minecraft:bubble_column", - "id": -160 - }, - { - "name": "minecraft:bubble_coral", - "id": -582 - }, - { - "name": "minecraft:bucket", - "id": 362 - }, - { - "name": "minecraft:budding_amethyst", - "id": -328 - }, - { - "name": "minecraft:burn_pottery_sherd", - "id": 668 - }, - { - "name": "minecraft:cactus", - "id": 81 - }, - { - "name": "minecraft:cake", - "id": 419 - }, - { - "name": "minecraft:calcite", - "id": -326 - }, - { - "name": "minecraft:calibrated_sculk_sensor", - "id": -580 - }, - { - "name": "minecraft:camel_spawn_egg", - "id": 662 - }, - { - "name": "minecraft:camera", - "id": 600 - }, - { - "name": "minecraft:campfire", - "id": 596 - }, - { - "name": "minecraft:candle", - "id": -412 - }, - { - "name": "minecraft:candle_cake", - "id": -429 - }, - { - "name": "minecraft:carpet", - "id": 704 - }, - { - "name": "minecraft:carrot", - "id": 279 - }, - { - "name": "minecraft:carrot_on_a_stick", - "id": 524 - }, - { - "name": "minecraft:carrots", - "id": 141 - }, - { - "name": "minecraft:cartography_table", - "id": -200 - }, - { - "name": "minecraft:carved_pumpkin", - "id": -155 - }, - { - "name": "minecraft:cat_spawn_egg", - "id": 490 - }, - { - "name": "minecraft:cauldron", - "id": 434 - }, - { - "name": "minecraft:cave_spider_spawn_egg", - "id": 459 - }, - { - "name": "minecraft:cave_vines", - "id": -322 - }, - { - "name": "minecraft:cave_vines_body_with_berries", - "id": -375 - }, - { - "name": "minecraft:cave_vines_head_with_berries", - "id": -376 - }, - { - "name": "minecraft:chain", - "id": 626 - }, - { - "name": "minecraft:chain_command_block", - "id": 189 - }, - { - "name": "minecraft:chainmail_boots", - "id": 344 - }, - { - "name": "minecraft:chainmail_chestplate", - "id": 342 - }, - { - "name": "minecraft:chainmail_helmet", - "id": 341 - }, - { - "name": "minecraft:chainmail_leggings", - "id": 343 - }, - { - "name": "minecraft:charcoal", - "id": 305 - }, - { - "name": "minecraft:chemical_heat", - "id": 192 - }, - { - "name": "minecraft:chemistry_table", - "id": 238 - }, - { - "name": "minecraft:cherry_boat", - "id": 656 - }, - { - "name": "minecraft:cherry_button", - "id": -530 - }, - { - "name": "minecraft:cherry_chest_boat", - "id": 657 - }, - { - "name": "minecraft:cherry_door", - "id": -531 - }, - { - "name": "minecraft:cherry_double_slab", - "id": -540 - }, - { - "name": "minecraft:cherry_fence", - "id": -532 - }, - { - "name": "minecraft:cherry_fence_gate", - "id": -533 - }, - { - "name": "minecraft:cherry_hanging_sign", - "id": -534 - }, - { - "name": "minecraft:cherry_leaves", - "id": -548 - }, - { - "name": "minecraft:cherry_log", - "id": -536 - }, - { - "name": "minecraft:cherry_planks", - "id": -537 - }, - { - "name": "minecraft:cherry_pressure_plate", - "id": -538 - }, - { - "name": "minecraft:cherry_sapling", - "id": -547 - }, - { - "name": "minecraft:cherry_sign", - "id": 658 - }, - { - "name": "minecraft:cherry_slab", - "id": -539 - }, - { - "name": "minecraft:cherry_stairs", - "id": -541 - }, - { - "name": "minecraft:cherry_standing_sign", - "id": -542 - }, - { - "name": "minecraft:cherry_trapdoor", - "id": -543 - }, - { - "name": "minecraft:cherry_wall_sign", - "id": -544 - }, - { - "name": "minecraft:cherry_wood", - "id": -546 - }, - { - "name": "minecraft:chest", - "id": 54 - }, - { - "name": "minecraft:chest_boat", - "id": 652 - }, - { - "name": "minecraft:chest_minecart", - "id": 391 - }, - { - "name": "minecraft:chicken", - "id": 275 - }, - { - "name": "minecraft:chicken_spawn_egg", - "id": 437 - }, - { - "name": "minecraft:chiseled_bookshelf", - "id": -526 - }, - { - "name": "minecraft:chiseled_deepslate", - "id": -395 - }, - { - "name": "minecraft:chiseled_nether_bricks", - "id": -302 - }, - { - "name": "minecraft:chiseled_polished_blackstone", - "id": -279 - }, - { - "name": "minecraft:chorus_flower", - "id": 200 - }, - { - "name": "minecraft:chorus_fruit", - "id": 565 - }, - { - "name": "minecraft:chorus_plant", - "id": 240 - }, - { - "name": "minecraft:clay", - "id": 82 - }, - { - "name": "minecraft:clay_ball", - "id": 386 - }, - { - "name": "minecraft:client_request_placeholder_block", - "id": -465 - }, - { - "name": "minecraft:clock", - "id": 395 - }, - { - "name": "minecraft:coal", - "id": 304 - }, - { - "name": "minecraft:coal_block", - "id": 173 - }, - { - "name": "minecraft:coal_ore", - "id": 16 - }, - { - "name": "minecraft:coast_armor_trim_smithing_template", - "id": 687 - }, - { - "name": "minecraft:cobbled_deepslate", - "id": -379 - }, - { - "name": "minecraft:cobbled_deepslate_double_slab", - "id": -396 - }, - { - "name": "minecraft:cobbled_deepslate_slab", - "id": -380 - }, - { - "name": "minecraft:cobbled_deepslate_stairs", - "id": -381 - }, - { - "name": "minecraft:cobbled_deepslate_wall", - "id": -382 - }, - { - "name": "minecraft:cobblestone", - "id": 4 - }, - { - "name": "minecraft:cobblestone_wall", - "id": 139 - }, - { - "name": "minecraft:cocoa", - "id": 127 - }, - { - "name": "minecraft:cocoa_beans", - "id": 414 - }, - { - "name": "minecraft:cod", - "id": 264 - }, - { - "name": "minecraft:cod_bucket", - "id": 366 - }, - { - "name": "minecraft:cod_spawn_egg", - "id": 482 - }, - { - "name": "minecraft:colored_torch_bp", - "id": 204 - }, - { - "name": "minecraft:colored_torch_rg", - "id": 202 - }, - { - "name": "minecraft:command_block", - "id": 137 - }, - { - "name": "minecraft:command_block_minecart", - "id": 570 - }, - { - "name": "minecraft:comparator", - "id": 529 - }, - { - "name": "minecraft:compass", - "id": 393 - }, - { - "name": "minecraft:composter", - "id": -213 - }, - { - "name": "minecraft:compound", - "id": 601 - }, - { - "name": "minecraft:concrete", - "id": 709 - }, - { - "name": "minecraft:concrete_powder", - "id": 710 - }, - { - "name": "minecraft:conduit", - "id": -157 - }, - { - "name": "minecraft:cooked_beef", - "id": 274 - }, - { - "name": "minecraft:cooked_chicken", - "id": 276 - }, - { - "name": "minecraft:cooked_cod", - "id": 268 - }, - { - "name": "minecraft:cooked_mutton", - "id": 558 - }, - { - "name": "minecraft:cooked_porkchop", - "id": 263 - }, - { - "name": "minecraft:cooked_rabbit", - "id": 289 - }, - { - "name": "minecraft:cooked_salmon", - "id": 269 - }, - { - "name": "minecraft:cookie", - "id": 271 - }, - { - "name": "minecraft:copper_block", - "id": -340 - }, - { - "name": "minecraft:copper_ingot", - "id": 511 - }, - { - "name": "minecraft:copper_ore", - "id": -311 - }, - { - "name": "minecraft:coral", - "id": 707 - }, - { - "name": "minecraft:coral_block", - "id": -132 - }, - { - "name": "minecraft:coral_fan", - "id": -133 - }, - { - "name": "minecraft:coral_fan_dead", - "id": -134 - }, - { - "name": "minecraft:coral_fan_hang", - "id": -135 - }, - { - "name": "minecraft:coral_fan_hang2", - "id": -136 - }, - { - "name": "minecraft:coral_fan_hang3", - "id": -137 - }, - { - "name": "minecraft:cow_spawn_egg", - "id": 438 - }, - { - "name": "minecraft:cracked_deepslate_bricks", - "id": -410 - }, - { - "name": "minecraft:cracked_deepslate_tiles", - "id": -409 - }, - { - "name": "minecraft:cracked_nether_bricks", - "id": -303 - }, - { - "name": "minecraft:cracked_polished_blackstone_bricks", - "id": -280 - }, - { - "name": "minecraft:crafting_table", - "id": 58 - }, - { - "name": "minecraft:creeper_banner_pattern", - "id": 589 - }, - { - "name": "minecraft:creeper_spawn_egg", - "id": 443 - }, - { - "name": "minecraft:crimson_button", - "id": -260 - }, - { - "name": "minecraft:crimson_door", - "id": 623 - }, - { - "name": "minecraft:crimson_double_slab", - "id": -266 - }, - { - "name": "minecraft:crimson_fence", - "id": -256 - }, - { - "name": "minecraft:crimson_fence_gate", - "id": -258 - }, - { - "name": "minecraft:crimson_fungus", - "id": -228 - }, - { - "name": "minecraft:crimson_hanging_sign", - "id": -506 - }, - { - "name": "minecraft:crimson_hyphae", - "id": -299 - }, - { - "name": "minecraft:crimson_nylium", - "id": -232 - }, - { - "name": "minecraft:crimson_planks", - "id": -242 - }, - { - "name": "minecraft:crimson_pressure_plate", - "id": -262 - }, - { - "name": "minecraft:crimson_roots", - "id": -223 - }, - { - "name": "minecraft:crimson_sign", - "id": 621 - }, - { - "name": "minecraft:crimson_slab", - "id": -264 - }, - { - "name": "minecraft:crimson_stairs", - "id": -254 - }, - { - "name": "minecraft:crimson_standing_sign", - "id": -250 - }, - { - "name": "minecraft:crimson_stem", - "id": -225 - }, - { - "name": "minecraft:crimson_trapdoor", - "id": -246 - }, - { - "name": "minecraft:crimson_wall_sign", - "id": -252 - }, - { - "name": "minecraft:crossbow", - "id": 582 - }, - { - "name": "minecraft:crying_obsidian", - "id": -289 - }, - { - "name": "minecraft:cut_copper", - "id": -347 - }, - { - "name": "minecraft:cut_copper_slab", - "id": -361 - }, - { - "name": "minecraft:cut_copper_stairs", - "id": -354 - }, - { - "name": "minecraft:cyan_candle", - "id": -422 - }, - { - "name": "minecraft:cyan_candle_cake", - "id": -439 - }, - { - "name": "minecraft:cyan_carpet", - "id": -605 - }, - { - "name": "minecraft:cyan_concrete", - "id": -636 - }, - { - "name": "minecraft:cyan_concrete_powder", - "id": -717 - }, - { - "name": "minecraft:cyan_dye", - "id": 403 - }, - { - "name": "minecraft:cyan_glazed_terracotta", - "id": 229 - }, - { - "name": "minecraft:cyan_shulker_box", - "id": -621 - }, - { - "name": "minecraft:cyan_stained_glass", - "id": -681 - }, - { - "name": "minecraft:cyan_stained_glass_pane", - "id": -651 - }, - { - "name": "minecraft:cyan_terracotta", - "id": -732 - }, - { - "name": "minecraft:cyan_wool", - "id": -561 - }, - { - "name": "minecraft:danger_pottery_sherd", - "id": 669 - }, - { - "name": "minecraft:dark_oak_boat", - "id": 382 - }, - { - "name": "minecraft:dark_oak_button", - "id": -142 - }, - { - "name": "minecraft:dark_oak_chest_boat", - "id": 650 - }, - { - "name": "minecraft:dark_oak_door", - "id": 564 - }, - { - "name": "minecraft:dark_oak_fence", - "id": -577 - }, - { - "name": "minecraft:dark_oak_fence_gate", - "id": 186 - }, - { - "name": "minecraft:dark_oak_hanging_sign", - "id": -505 - }, - { - "name": "minecraft:dark_oak_log", - "id": -572 - }, - { - "name": "minecraft:dark_oak_pressure_plate", - "id": -152 - }, - { - "name": "minecraft:dark_oak_sign", - "id": 587 - }, - { - "name": "minecraft:dark_oak_stairs", - "id": 164 - }, - { - "name": "minecraft:dark_oak_trapdoor", - "id": -147 - }, - { - "name": "minecraft:dark_prismarine_stairs", - "id": -3 - }, - { - "name": "minecraft:darkoak_standing_sign", - "id": -192 - }, - { - "name": "minecraft:darkoak_wall_sign", - "id": -193 - }, - { - "name": "minecraft:daylight_detector", - "id": 151 - }, - { - "name": "minecraft:daylight_detector_inverted", - "id": 178 - }, - { - "name": "minecraft:dead_brain_coral", - "id": -586 - }, - { - "name": "minecraft:dead_bubble_coral", - "id": -587 - }, - { - "name": "minecraft:dead_fire_coral", - "id": -588 - }, - { - "name": "minecraft:dead_horn_coral", - "id": -589 - }, - { - "name": "minecraft:dead_tube_coral", - "id": -585 - }, - { - "name": "minecraft:deadbush", - "id": 32 - }, - { - "name": "minecraft:decorated_pot", - "id": -551 - }, - { - "name": "minecraft:deepslate", - "id": -378 - }, - { - "name": "minecraft:deepslate_brick_double_slab", - "id": -399 - }, - { - "name": "minecraft:deepslate_brick_slab", - "id": -392 - }, - { - "name": "minecraft:deepslate_brick_stairs", - "id": -393 - }, - { - "name": "minecraft:deepslate_brick_wall", - "id": -394 - }, - { - "name": "minecraft:deepslate_bricks", - "id": -391 - }, - { - "name": "minecraft:deepslate_coal_ore", - "id": -406 - }, - { - "name": "minecraft:deepslate_copper_ore", - "id": -408 - }, - { - "name": "minecraft:deepslate_diamond_ore", - "id": -405 - }, - { - "name": "minecraft:deepslate_emerald_ore", - "id": -407 - }, - { - "name": "minecraft:deepslate_gold_ore", - "id": -402 - }, - { - "name": "minecraft:deepslate_iron_ore", - "id": -401 - }, - { - "name": "minecraft:deepslate_lapis_ore", - "id": -400 - }, - { - "name": "minecraft:deepslate_redstone_ore", - "id": -403 - }, - { - "name": "minecraft:deepslate_tile_double_slab", - "id": -398 - }, - { - "name": "minecraft:deepslate_tile_slab", - "id": -388 - }, - { - "name": "minecraft:deepslate_tile_stairs", - "id": -389 - }, - { - "name": "minecraft:deepslate_tile_wall", - "id": -390 - }, - { - "name": "minecraft:deepslate_tiles", - "id": -387 - }, - { - "name": "minecraft:deny", - "id": 211 - }, - { - "name": "minecraft:detector_rail", - "id": 28 - }, - { - "name": "minecraft:diamond", - "id": 306 - }, - { - "name": "minecraft:diamond_axe", - "id": 321 - }, - { - "name": "minecraft:diamond_block", - "id": 57 - }, - { - "name": "minecraft:diamond_boots", - "id": 352 - }, - { - "name": "minecraft:diamond_chestplate", - "id": 350 - }, - { - "name": "minecraft:diamond_helmet", - "id": 349 - }, - { - "name": "minecraft:diamond_hoe", - "id": 334 - }, - { - "name": "minecraft:diamond_horse_armor", - "id": 540 - }, - { - "name": "minecraft:diamond_leggings", - "id": 351 - }, - { - "name": "minecraft:diamond_ore", - "id": 56 - }, - { - "name": "minecraft:diamond_pickaxe", - "id": 320 - }, - { - "name": "minecraft:diamond_shovel", - "id": 319 - }, - { - "name": "minecraft:diamond_sword", - "id": 318 - }, - { - "name": "minecraft:diorite_stairs", - "id": -170 - }, - { - "name": "minecraft:dirt", - "id": 3 - }, - { - "name": "minecraft:dirt_with_roots", - "id": -318 - }, - { - "name": "minecraft:disc_fragment_5", - "id": 644 - }, - { - "name": "minecraft:dispenser", - "id": 23 - }, - { - "name": "minecraft:dolphin_spawn_egg", - "id": 486 - }, - { - "name": "minecraft:donkey_spawn_egg", - "id": 467 - }, - { - "name": "minecraft:double_cut_copper_slab", - "id": -368 - }, - { - "name": "minecraft:double_plant", - "id": 175 - }, - { - "name": "minecraft:double_stone_block_slab", - "id": 43 - }, - { - "name": "minecraft:double_stone_block_slab2", - "id": 181 - }, - { - "name": "minecraft:double_stone_block_slab3", - "id": -167 - }, - { - "name": "minecraft:double_stone_block_slab4", - "id": -168 - }, - { - "name": "minecraft:double_wooden_slab", - "id": 157 - }, - { - "name": "minecraft:dragon_breath", - "id": 567 - }, - { - "name": "minecraft:dragon_egg", - "id": 122 - }, - { - "name": "minecraft:dried_kelp", - "id": 270 - }, - { - "name": "minecraft:dried_kelp_block", - "id": -139 - }, - { - "name": "minecraft:dripstone_block", - "id": -317 - }, - { - "name": "minecraft:dropper", - "id": 125 - }, - { - "name": "minecraft:drowned_spawn_egg", - "id": 485 - }, - { - "name": "minecraft:dune_armor_trim_smithing_template", - "id": 686 - }, - { - "name": "minecraft:dye", - "id": 715 - }, - { - "name": "minecraft:echo_shard", - "id": 654 - }, - { - "name": "minecraft:egg", - "id": 392 - }, - { - "name": "minecraft:elder_guardian_spawn_egg", - "id": 473 - }, - { - "name": "minecraft:element_0", - "id": 36 - }, - { - "name": "minecraft:element_1", - "id": -12 - }, - { - "name": "minecraft:element_10", - "id": -21 - }, - { - "name": "minecraft:element_100", - "id": -111 - }, - { - "name": "minecraft:element_101", - "id": -112 - }, - { - "name": "minecraft:element_102", - "id": -113 - }, - { - "name": "minecraft:element_103", - "id": -114 - }, - { - "name": "minecraft:element_104", - "id": -115 - }, - { - "name": "minecraft:element_105", - "id": -116 - }, - { - "name": "minecraft:element_106", - "id": -117 - }, - { - "name": "minecraft:element_107", - "id": -118 - }, - { - "name": "minecraft:element_108", - "id": -119 - }, - { - "name": "minecraft:element_109", - "id": -120 - }, - { - "name": "minecraft:element_11", - "id": -22 - }, - { - "name": "minecraft:element_110", - "id": -121 - }, - { - "name": "minecraft:element_111", - "id": -122 - }, - { - "name": "minecraft:element_112", - "id": -123 - }, - { - "name": "minecraft:element_113", - "id": -124 - }, - { - "name": "minecraft:element_114", - "id": -125 - }, - { - "name": "minecraft:element_115", - "id": -126 - }, - { - "name": "minecraft:element_116", - "id": -127 - }, - { - "name": "minecraft:element_117", - "id": -128 - }, - { - "name": "minecraft:element_118", - "id": -129 - }, - { - "name": "minecraft:element_12", - "id": -23 - }, - { - "name": "minecraft:element_13", - "id": -24 - }, - { - "name": "minecraft:element_14", - "id": -25 - }, - { - "name": "minecraft:element_15", - "id": -26 - }, - { - "name": "minecraft:element_16", - "id": -27 - }, - { - "name": "minecraft:element_17", - "id": -28 - }, - { - "name": "minecraft:element_18", - "id": -29 - }, - { - "name": "minecraft:element_19", - "id": -30 - }, - { - "name": "minecraft:element_2", - "id": -13 - }, - { - "name": "minecraft:element_20", - "id": -31 - }, - { - "name": "minecraft:element_21", - "id": -32 - }, - { - "name": "minecraft:element_22", - "id": -33 - }, - { - "name": "minecraft:element_23", - "id": -34 - }, - { - "name": "minecraft:element_24", - "id": -35 - }, - { - "name": "minecraft:element_25", - "id": -36 - }, - { - "name": "minecraft:element_26", - "id": -37 - }, - { - "name": "minecraft:element_27", - "id": -38 - }, - { - "name": "minecraft:element_28", - "id": -39 - }, - { - "name": "minecraft:element_29", - "id": -40 - }, - { - "name": "minecraft:element_3", - "id": -14 - }, - { - "name": "minecraft:element_30", - "id": -41 - }, - { - "name": "minecraft:element_31", - "id": -42 - }, - { - "name": "minecraft:element_32", - "id": -43 - }, - { - "name": "minecraft:element_33", - "id": -44 - }, - { - "name": "minecraft:element_34", - "id": -45 - }, - { - "name": "minecraft:element_35", - "id": -46 - }, - { - "name": "minecraft:element_36", - "id": -47 - }, - { - "name": "minecraft:element_37", - "id": -48 - }, - { - "name": "minecraft:element_38", - "id": -49 - }, - { - "name": "minecraft:element_39", - "id": -50 - }, - { - "name": "minecraft:element_4", - "id": -15 - }, - { - "name": "minecraft:element_40", - "id": -51 - }, - { - "name": "minecraft:element_41", - "id": -52 - }, - { - "name": "minecraft:element_42", - "id": -53 - }, - { - "name": "minecraft:element_43", - "id": -54 - }, - { - "name": "minecraft:element_44", - "id": -55 - }, - { - "name": "minecraft:element_45", - "id": -56 - }, - { - "name": "minecraft:element_46", - "id": -57 - }, - { - "name": "minecraft:element_47", - "id": -58 - }, - { - "name": "minecraft:element_48", - "id": -59 - }, - { - "name": "minecraft:element_49", - "id": -60 - }, - { - "name": "minecraft:element_5", - "id": -16 - }, - { - "name": "minecraft:element_50", - "id": -61 - }, - { - "name": "minecraft:element_51", - "id": -62 - }, - { - "name": "minecraft:element_52", - "id": -63 - }, - { - "name": "minecraft:element_53", - "id": -64 - }, - { - "name": "minecraft:element_54", - "id": -65 - }, - { - "name": "minecraft:element_55", - "id": -66 - }, - { - "name": "minecraft:element_56", - "id": -67 - }, - { - "name": "minecraft:element_57", - "id": -68 - }, - { - "name": "minecraft:element_58", - "id": -69 - }, - { - "name": "minecraft:element_59", - "id": -70 - }, - { - "name": "minecraft:element_6", - "id": -17 - }, - { - "name": "minecraft:element_60", - "id": -71 - }, - { - "name": "minecraft:element_61", - "id": -72 - }, - { - "name": "minecraft:element_62", - "id": -73 - }, - { - "name": "minecraft:element_63", - "id": -74 - }, - { - "name": "minecraft:element_64", - "id": -75 - }, - { - "name": "minecraft:element_65", - "id": -76 - }, - { - "name": "minecraft:element_66", - "id": -77 - }, - { - "name": "minecraft:element_67", - "id": -78 - }, - { - "name": "minecraft:element_68", - "id": -79 - }, - { - "name": "minecraft:element_69", - "id": -80 - }, - { - "name": "minecraft:element_7", - "id": -18 - }, - { - "name": "minecraft:element_70", - "id": -81 - }, - { - "name": "minecraft:element_71", - "id": -82 - }, - { - "name": "minecraft:element_72", - "id": -83 - }, - { - "name": "minecraft:element_73", - "id": -84 - }, - { - "name": "minecraft:element_74", - "id": -85 - }, - { - "name": "minecraft:element_75", - "id": -86 - }, - { - "name": "minecraft:element_76", - "id": -87 - }, - { - "name": "minecraft:element_77", - "id": -88 - }, - { - "name": "minecraft:element_78", - "id": -89 - }, - { - "name": "minecraft:element_79", - "id": -90 - }, - { - "name": "minecraft:element_8", - "id": -19 - }, - { - "name": "minecraft:element_80", - "id": -91 - }, - { - "name": "minecraft:element_81", - "id": -92 - }, - { - "name": "minecraft:element_82", - "id": -93 - }, - { - "name": "minecraft:element_83", - "id": -94 - }, - { - "name": "minecraft:element_84", - "id": -95 - }, - { - "name": "minecraft:element_85", - "id": -96 - }, - { - "name": "minecraft:element_86", - "id": -97 - }, - { - "name": "minecraft:element_87", - "id": -98 - }, - { - "name": "minecraft:element_88", - "id": -99 - }, - { - "name": "minecraft:element_89", - "id": -100 - }, - { - "name": "minecraft:element_9", - "id": -20 - }, - { - "name": "minecraft:element_90", - "id": -101 - }, - { - "name": "minecraft:element_91", - "id": -102 - }, - { - "name": "minecraft:element_92", - "id": -103 - }, - { - "name": "minecraft:element_93", - "id": -104 - }, - { - "name": "minecraft:element_94", - "id": -105 - }, - { - "name": "minecraft:element_95", - "id": -106 - }, - { - "name": "minecraft:element_96", - "id": -107 - }, - { - "name": "minecraft:element_97", - "id": -108 - }, - { - "name": "minecraft:element_98", - "id": -109 - }, - { - "name": "minecraft:element_99", - "id": -110 - }, - { - "name": "minecraft:elytra", - "id": 571 - }, - { - "name": "minecraft:emerald", - "id": 519 - }, - { - "name": "minecraft:emerald_block", - "id": 133 - }, - { - "name": "minecraft:emerald_ore", - "id": 129 - }, - { - "name": "minecraft:empty_map", - "id": 522 - }, - { - "name": "minecraft:enchanted_book", - "id": 528 - }, - { - "name": "minecraft:enchanted_golden_apple", - "id": 259 - }, - { - "name": "minecraft:enchanting_table", - "id": 116 - }, - { - "name": "minecraft:end_brick_stairs", - "id": -178 - }, - { - "name": "minecraft:end_bricks", - "id": 206 - }, - { - "name": "minecraft:end_crystal", - "id": 718 - }, - { - "name": "minecraft:end_gateway", - "id": 209 - }, - { - "name": "minecraft:end_portal", - "id": 119 - }, - { - "name": "minecraft:end_portal_frame", - "id": 120 - }, - { - "name": "minecraft:end_rod", - "id": 208 - }, - { - "name": "minecraft:end_stone", - "id": 121 - }, - { - "name": "minecraft:ender_chest", - "id": 130 - }, - { - "name": "minecraft:ender_dragon_spawn_egg", - "id": 508 - }, - { - "name": "minecraft:ender_eye", - "id": 435 - }, - { - "name": "minecraft:ender_pearl", - "id": 424 - }, - { - "name": "minecraft:enderman_spawn_egg", - "id": 444 - }, - { - "name": "minecraft:endermite_spawn_egg", - "id": 462 - }, - { - "name": "minecraft:evoker_spawn_egg", - "id": 477 - }, - { - "name": "minecraft:experience_bottle", - "id": 515 - }, - { - "name": "minecraft:explorer_pottery_sherd", - "id": 670 - }, - { - "name": "minecraft:exposed_copper", - "id": -341 - }, - { - "name": "minecraft:exposed_cut_copper", - "id": -348 - }, - { - "name": "minecraft:exposed_cut_copper_slab", - "id": -362 - }, - { - "name": "minecraft:exposed_cut_copper_stairs", - "id": -355 - }, - { - "name": "minecraft:exposed_double_cut_copper_slab", - "id": -369 - }, - { - "name": "minecraft:eye_armor_trim_smithing_template", - "id": 690 - }, - { - "name": "minecraft:farmland", - "id": 60 - }, - { - "name": "minecraft:feather", - "id": 329 - }, - { - "name": "minecraft:fence", - "id": 706 - }, - { - "name": "minecraft:fence_gate", - "id": 107 - }, - { - "name": "minecraft:fermented_spider_eye", - "id": 430 - }, - { - "name": "minecraft:field_masoned_banner_pattern", - "id": 592 - }, - { - "name": "minecraft:filled_map", - "id": 422 - }, - { - "name": "minecraft:fire", - "id": 51 - }, - { - "name": "minecraft:fire_charge", - "id": 516 - }, - { - "name": "minecraft:fire_coral", - "id": -583 - }, - { - "name": "minecraft:firework_rocket", - "id": 526 - }, - { - "name": "minecraft:firework_star", - "id": 527 - }, - { - "name": "minecraft:fishing_rod", - "id": 394 - }, - { - "name": "minecraft:fletching_table", - "id": -201 - }, - { - "name": "minecraft:flint", - "id": 358 - }, - { - "name": "minecraft:flint_and_steel", - "id": 301 - }, - { - "name": "minecraft:flower_banner_pattern", - "id": 588 - }, - { - "name": "minecraft:flower_pot", - "id": 521 - }, - { - "name": "minecraft:flowering_azalea", - "id": -338 - }, - { - "name": "minecraft:flowing_lava", - "id": 10 - }, - { - "name": "minecraft:flowing_water", - "id": 8 - }, - { - "name": "minecraft:fox_spawn_egg", - "id": 492 - }, - { - "name": "minecraft:frame", - "id": 520 - }, - { - "name": "minecraft:friend_pottery_sherd", - "id": 671 - }, - { - "name": "minecraft:frog_spawn", - "id": -468 - }, - { - "name": "minecraft:frog_spawn_egg", - "id": 635 - }, - { - "name": "minecraft:frosted_ice", - "id": 207 - }, - { - "name": "minecraft:furnace", - "id": 61 - }, - { - "name": "minecraft:ghast_spawn_egg", - "id": 456 - }, - { - "name": "minecraft:ghast_tear", - "id": 426 - }, - { - "name": "minecraft:gilded_blackstone", - "id": -281 - }, - { - "name": "minecraft:glass", - "id": 20 - }, - { - "name": "minecraft:glass_bottle", - "id": 429 - }, - { - "name": "minecraft:glass_pane", - "id": 102 - }, - { - "name": "minecraft:glistering_melon_slice", - "id": 436 - }, - { - "name": "minecraft:globe_banner_pattern", - "id": 595 - }, - { - "name": "minecraft:glow_berries", - "id": 719 - }, - { - "name": "minecraft:glow_frame", - "id": 630 - }, - { - "name": "minecraft:glow_ink_sac", - "id": 510 - }, - { - "name": "minecraft:glow_lichen", - "id": -411 - }, - { - "name": "minecraft:glow_squid_spawn_egg", - "id": 505 - }, - { - "name": "minecraft:glow_stick", - "id": 608 - }, - { - "name": "minecraft:glowingobsidian", - "id": 246 - }, - { - "name": "minecraft:glowstone", - "id": 89 - }, - { - "name": "minecraft:glowstone_dust", - "id": 396 - }, - { - "name": "minecraft:goat_horn", - "id": 634 - }, - { - "name": "minecraft:goat_spawn_egg", - "id": 504 - }, - { - "name": "minecraft:gold_block", - "id": 41 - }, - { - "name": "minecraft:gold_ingot", - "id": 308 - }, - { - "name": "minecraft:gold_nugget", - "id": 427 - }, - { - "name": "minecraft:gold_ore", - "id": 14 - }, - { - "name": "minecraft:golden_apple", - "id": 258 - }, - { - "name": "minecraft:golden_axe", - "id": 327 - }, - { - "name": "minecraft:golden_boots", - "id": 356 - }, - { - "name": "minecraft:golden_carrot", - "id": 283 - }, - { - "name": "minecraft:golden_chestplate", - "id": 354 - }, - { - "name": "minecraft:golden_helmet", - "id": 353 - }, - { - "name": "minecraft:golden_hoe", - "id": 335 - }, - { - "name": "minecraft:golden_horse_armor", - "id": 539 - }, - { - "name": "minecraft:golden_leggings", - "id": 355 - }, - { - "name": "minecraft:golden_pickaxe", - "id": 326 - }, - { - "name": "minecraft:golden_rail", - "id": 27 - }, - { - "name": "minecraft:golden_shovel", - "id": 325 - }, - { - "name": "minecraft:golden_sword", - "id": 324 - }, - { - "name": "minecraft:granite_stairs", - "id": -169 - }, - { - "name": "minecraft:grass", - "id": 2 - }, - { - "name": "minecraft:grass_path", - "id": 198 - }, - { - "name": "minecraft:gravel", - "id": 13 - }, - { - "name": "minecraft:gray_candle", - "id": -420 - }, - { - "name": "minecraft:gray_candle_cake", - "id": -437 - }, - { - "name": "minecraft:gray_carpet", - "id": -603 - }, - { - "name": "minecraft:gray_concrete", - "id": -634 - }, - { - "name": "minecraft:gray_concrete_powder", - "id": -715 - }, - { - "name": "minecraft:gray_dye", - "id": 405 - }, - { - "name": "minecraft:gray_glazed_terracotta", - "id": 227 - }, - { - "name": "minecraft:gray_shulker_box", - "id": -619 - }, - { - "name": "minecraft:gray_stained_glass", - "id": -679 - }, - { - "name": "minecraft:gray_stained_glass_pane", - "id": -649 - }, - { - "name": "minecraft:gray_terracotta", - "id": -730 - }, - { - "name": "minecraft:gray_wool", - "id": -553 - }, - { - "name": "minecraft:green_candle", - "id": -426 - }, - { - "name": "minecraft:green_candle_cake", - "id": -443 - }, - { - "name": "minecraft:green_carpet", - "id": -609 - }, - { - "name": "minecraft:green_concrete", - "id": -640 - }, - { - "name": "minecraft:green_concrete_powder", - "id": -721 - }, - { - "name": "minecraft:green_dye", - "id": 399 - }, - { - "name": "minecraft:green_glazed_terracotta", - "id": 233 - }, - { - "name": "minecraft:green_shulker_box", - "id": -625 - }, - { - "name": "minecraft:green_stained_glass", - "id": -685 - }, - { - "name": "minecraft:green_stained_glass_pane", - "id": -655 - }, - { - "name": "minecraft:green_terracotta", - "id": -736 - }, - { - "name": "minecraft:green_wool", - "id": -560 - }, - { - "name": "minecraft:grindstone", - "id": -195 - }, - { - "name": "minecraft:guardian_spawn_egg", - "id": 463 - }, - { - "name": "minecraft:gunpowder", - "id": 330 - }, - { - "name": "minecraft:hanging_roots", - "id": -319 - }, - { - "name": "minecraft:hard_glass", - "id": 253 - }, - { - "name": "minecraft:hard_glass_pane", - "id": 190 - }, - { - "name": "minecraft:hard_stained_glass", - "id": 254 - }, - { - "name": "minecraft:hard_stained_glass_pane", - "id": 191 - }, - { - "name": "minecraft:hardened_clay", - "id": 172 - }, - { - "name": "minecraft:hay_block", - "id": 170 - }, - { - "name": "minecraft:heart_of_the_sea", - "id": 578 - }, - { - "name": "minecraft:heart_pottery_sherd", - "id": 672 - }, - { - "name": "minecraft:heartbreak_pottery_sherd", - "id": 673 - }, - { - "name": "minecraft:heavy_weighted_pressure_plate", - "id": 148 - }, - { - "name": "minecraft:hoglin_spawn_egg", - "id": 498 - }, - { - "name": "minecraft:honey_block", - "id": -220 - }, - { - "name": "minecraft:honey_bottle", - "id": 599 - }, - { - "name": "minecraft:honeycomb", - "id": 598 - }, - { - "name": "minecraft:honeycomb_block", - "id": -221 - }, - { - "name": "minecraft:hopper", - "id": 534 - }, - { - "name": "minecraft:hopper_minecart", - "id": 533 - }, - { - "name": "minecraft:horn_coral", - "id": -584 - }, - { - "name": "minecraft:horse_spawn_egg", - "id": 460 - }, - { - "name": "minecraft:host_armor_trim_smithing_template", - "id": 700 - }, - { - "name": "minecraft:howl_pottery_sherd", - "id": 674 - }, - { - "name": "minecraft:husk_spawn_egg", - "id": 465 - }, - { - "name": "minecraft:ice", - "id": 79 - }, - { - "name": "minecraft:ice_bomb", - "id": 602 - }, - { - "name": "minecraft:infested_deepslate", - "id": -454 - }, - { - "name": "minecraft:info_update", - "id": 248 - }, - { - "name": "minecraft:info_update2", - "id": 249 - }, - { - "name": "minecraft:ink_sac", - "id": 415 - }, - { - "name": "minecraft:invisible_bedrock", - "id": 95 - }, - { - "name": "minecraft:iron_axe", - "id": 300 - }, - { - "name": "minecraft:iron_bars", - "id": 101 - }, - { - "name": "minecraft:iron_block", - "id": 42 - }, - { - "name": "minecraft:iron_boots", - "id": 348 - }, - { - "name": "minecraft:iron_chestplate", - "id": 346 - }, - { - "name": "minecraft:iron_door", - "id": 374 - }, - { - "name": "minecraft:iron_golem_spawn_egg", - "id": 506 - }, - { - "name": "minecraft:iron_helmet", - "id": 345 - }, - { - "name": "minecraft:iron_hoe", - "id": 333 - }, - { - "name": "minecraft:iron_horse_armor", - "id": 538 - }, - { - "name": "minecraft:iron_ingot", - "id": 307 - }, - { - "name": "minecraft:iron_leggings", - "id": 347 - }, - { - "name": "minecraft:iron_nugget", - "id": 576 - }, - { - "name": "minecraft:iron_ore", - "id": 15 - }, - { - "name": "minecraft:iron_pickaxe", - "id": 299 - }, - { - "name": "minecraft:iron_shovel", - "id": 298 - }, - { - "name": "minecraft:iron_sword", - "id": 309 - }, - { - "name": "minecraft:iron_trapdoor", - "id": 167 - }, - { - "name": "minecraft:item.acacia_door", - "id": 196 - }, - { - "name": "minecraft:item.bed", - "id": 26 - }, - { - "name": "minecraft:item.beetroot", - "id": 244 - }, - { - "name": "minecraft:item.birch_door", - "id": 194 - }, - { - "name": "minecraft:item.brewing_stand", - "id": 117 - }, - { - "name": "minecraft:item.cake", - "id": 92 - }, - { - "name": "minecraft:item.camera", - "id": 242 - }, - { - "name": "minecraft:item.campfire", - "id": -209 - }, - { - "name": "minecraft:item.cauldron", - "id": 118 - }, - { - "name": "minecraft:item.chain", - "id": -286 - }, - { - "name": "minecraft:item.crimson_door", - "id": -244 - }, - { - "name": "minecraft:item.dark_oak_door", - "id": 197 - }, - { - "name": "minecraft:item.flower_pot", - "id": 140 - }, - { - "name": "minecraft:item.frame", - "id": 199 - }, - { - "name": "minecraft:item.glow_frame", - "id": -339 - }, - { - "name": "minecraft:item.hopper", - "id": 154 - }, - { - "name": "minecraft:item.iron_door", - "id": 71 - }, - { - "name": "minecraft:item.jungle_door", - "id": 195 - }, - { - "name": "minecraft:item.kelp", - "id": -138 - }, - { - "name": "minecraft:item.mangrove_door", - "id": -493 - }, - { - "name": "minecraft:item.nether_sprouts", - "id": -238 - }, - { - "name": "minecraft:item.nether_wart", - "id": 115 - }, - { - "name": "minecraft:item.reeds", - "id": 83 - }, - { - "name": "minecraft:item.skull", - "id": 144 - }, - { - "name": "minecraft:item.soul_campfire", - "id": -290 - }, - { - "name": "minecraft:item.spruce_door", - "id": 193 - }, - { - "name": "minecraft:item.warped_door", - "id": -245 - }, - { - "name": "minecraft:item.wheat", - "id": 59 - }, - { - "name": "minecraft:item.wooden_door", - "id": 64 - }, - { - "name": "minecraft:jigsaw", - "id": -211 - }, - { - "name": "minecraft:jukebox", - "id": 84 - }, - { - "name": "minecraft:jungle_boat", - "id": 379 - }, - { - "name": "minecraft:jungle_button", - "id": -143 - }, - { - "name": "minecraft:jungle_chest_boat", - "id": 647 - }, - { - "name": "minecraft:jungle_door", - "id": 562 - }, - { - "name": "minecraft:jungle_fence", - "id": -578 - }, - { - "name": "minecraft:jungle_fence_gate", - "id": 185 - }, - { - "name": "minecraft:jungle_hanging_sign", - "id": -503 - }, - { - "name": "minecraft:jungle_log", - "id": -571 - }, - { - "name": "minecraft:jungle_pressure_plate", - "id": -153 - }, - { - "name": "minecraft:jungle_sign", - "id": 585 - }, - { - "name": "minecraft:jungle_stairs", - "id": 136 - }, - { - "name": "minecraft:jungle_standing_sign", - "id": -188 - }, - { - "name": "minecraft:jungle_trapdoor", - "id": -148 - }, - { - "name": "minecraft:jungle_wall_sign", - "id": -189 - }, - { - "name": "minecraft:kelp", - "id": 384 - }, - { - "name": "minecraft:ladder", - "id": 65 - }, - { - "name": "minecraft:lantern", - "id": -208 - }, - { - "name": "minecraft:lapis_block", - "id": 22 - }, - { - "name": "minecraft:lapis_lazuli", - "id": 416 - }, - { - "name": "minecraft:lapis_ore", - "id": 21 - }, - { - "name": "minecraft:large_amethyst_bud", - "id": -330 - }, - { - "name": "minecraft:lava", - "id": 11 - }, - { - "name": "minecraft:lava_bucket", - "id": 365 - }, - { - "name": "minecraft:lead", - "id": 554 - }, - { - "name": "minecraft:leather", - "id": 383 - }, - { - "name": "minecraft:leather_boots", - "id": 340 - }, - { - "name": "minecraft:leather_chestplate", - "id": 338 - }, - { - "name": "minecraft:leather_helmet", - "id": 337 - }, - { - "name": "minecraft:leather_horse_armor", - "id": 537 - }, - { - "name": "minecraft:leather_leggings", - "id": 339 - }, - { - "name": "minecraft:leaves", - "id": 18 - }, - { - "name": "minecraft:leaves2", - "id": 161 - }, - { - "name": "minecraft:lectern", - "id": -194 - }, - { - "name": "minecraft:lever", - "id": 69 - }, - { - "name": "minecraft:light_block", - "id": -215 - }, - { - "name": "minecraft:light_blue_candle", - "id": -416 - }, - { - "name": "minecraft:light_blue_candle_cake", - "id": -433 - }, - { - "name": "minecraft:light_blue_carpet", - "id": -599 - }, - { - "name": "minecraft:light_blue_concrete", - "id": -630 - }, - { - "name": "minecraft:light_blue_concrete_powder", - "id": -711 - }, - { - "name": "minecraft:light_blue_dye", - "id": 409 - }, - { - "name": "minecraft:light_blue_glazed_terracotta", - "id": 223 - }, - { - "name": "minecraft:light_blue_shulker_box", - "id": -615 - }, - { - "name": "minecraft:light_blue_stained_glass", - "id": -675 - }, - { - "name": "minecraft:light_blue_stained_glass_pane", - "id": -645 - }, - { - "name": "minecraft:light_blue_terracotta", - "id": -726 - }, - { - "name": "minecraft:light_blue_wool", - "id": -562 - }, - { - "name": "minecraft:light_gray_candle", - "id": -421 - }, - { - "name": "minecraft:light_gray_candle_cake", - "id": -438 - }, - { - "name": "minecraft:light_gray_carpet", - "id": -604 - }, - { - "name": "minecraft:light_gray_concrete", - "id": -635 - }, - { - "name": "minecraft:light_gray_concrete_powder", - "id": -716 - }, - { - "name": "minecraft:light_gray_dye", - "id": 404 - }, - { - "name": "minecraft:light_gray_shulker_box", - "id": -620 - }, - { - "name": "minecraft:light_gray_stained_glass", - "id": -680 - }, - { - "name": "minecraft:light_gray_stained_glass_pane", - "id": -650 - }, - { - "name": "minecraft:light_gray_terracotta", - "id": -731 - }, - { - "name": "minecraft:light_gray_wool", - "id": -552 - }, - { - "name": "minecraft:light_weighted_pressure_plate", - "id": 147 - }, - { - "name": "minecraft:lightning_rod", - "id": -312 - }, - { - "name": "minecraft:lime_candle", - "id": -418 - }, - { - "name": "minecraft:lime_candle_cake", - "id": -435 - }, - { - "name": "minecraft:lime_carpet", - "id": -601 - }, - { - "name": "minecraft:lime_concrete", - "id": -632 - }, - { - "name": "minecraft:lime_concrete_powder", - "id": -713 - }, - { - "name": "minecraft:lime_dye", - "id": 407 - }, - { - "name": "minecraft:lime_glazed_terracotta", - "id": 225 - }, - { - "name": "minecraft:lime_shulker_box", - "id": -617 - }, - { - "name": "minecraft:lime_stained_glass", - "id": -677 - }, - { - "name": "minecraft:lime_stained_glass_pane", - "id": -647 - }, - { - "name": "minecraft:lime_terracotta", - "id": -728 - }, - { - "name": "minecraft:lime_wool", - "id": -559 - }, - { - "name": "minecraft:lingering_potion", - "id": 569 - }, - { - "name": "minecraft:lit_blast_furnace", - "id": -214 - }, - { - "name": "minecraft:lit_deepslate_redstone_ore", - "id": -404 - }, - { - "name": "minecraft:lit_furnace", - "id": 62 - }, - { - "name": "minecraft:lit_pumpkin", - "id": 91 - }, - { - "name": "minecraft:lit_redstone_lamp", - "id": 124 - }, - { - "name": "minecraft:lit_redstone_ore", - "id": 74 - }, - { - "name": "minecraft:lit_smoker", - "id": -199 - }, - { - "name": "minecraft:llama_spawn_egg", - "id": 475 - }, - { - "name": "minecraft:lodestone", - "id": -222 - }, - { - "name": "minecraft:lodestone_compass", - "id": 609 - }, - { - "name": "minecraft:log", - "id": 705 - }, - { - "name": "minecraft:log2", - "id": 708 - }, - { - "name": "minecraft:loom", - "id": -204 - }, - { - "name": "minecraft:magenta_candle", - "id": -415 - }, - { - "name": "minecraft:magenta_candle_cake", - "id": -432 - }, - { - "name": "minecraft:magenta_carpet", - "id": -598 - }, - { - "name": "minecraft:magenta_concrete", - "id": -629 - }, - { - "name": "minecraft:magenta_concrete_powder", - "id": -710 - }, - { - "name": "minecraft:magenta_dye", - "id": 410 - }, - { - "name": "minecraft:magenta_glazed_terracotta", - "id": 222 - }, - { - "name": "minecraft:magenta_shulker_box", - "id": -614 - }, - { - "name": "minecraft:magenta_stained_glass", - "id": -674 - }, - { - "name": "minecraft:magenta_stained_glass_pane", - "id": -644 - }, - { - "name": "minecraft:magenta_terracotta", - "id": -725 - }, - { - "name": "minecraft:magenta_wool", - "id": -565 - }, - { - "name": "minecraft:magma", - "id": 213 - }, - { - "name": "minecraft:magma_cream", - "id": 432 - }, - { - "name": "minecraft:magma_cube_spawn_egg", - "id": 457 - }, - { - "name": "minecraft:mangrove_boat", - "id": 642 - }, - { - "name": "minecraft:mangrove_button", - "id": -487 - }, - { - "name": "minecraft:mangrove_chest_boat", - "id": 651 - }, - { - "name": "minecraft:mangrove_door", - "id": 640 - }, - { - "name": "minecraft:mangrove_double_slab", - "id": -499 - }, - { - "name": "minecraft:mangrove_fence", - "id": -491 - }, - { - "name": "minecraft:mangrove_fence_gate", - "id": -492 - }, - { - "name": "minecraft:mangrove_hanging_sign", - "id": -508 - }, - { - "name": "minecraft:mangrove_leaves", - "id": -472 - }, - { - "name": "minecraft:mangrove_log", - "id": -484 - }, - { - "name": "minecraft:mangrove_planks", - "id": -486 - }, - { - "name": "minecraft:mangrove_pressure_plate", - "id": -490 - }, - { - "name": "minecraft:mangrove_propagule", - "id": -474 - }, - { - "name": "minecraft:mangrove_roots", - "id": -482 - }, - { - "name": "minecraft:mangrove_sign", - "id": 641 - }, - { - "name": "minecraft:mangrove_slab", - "id": -489 - }, - { - "name": "minecraft:mangrove_stairs", - "id": -488 - }, - { - "name": "minecraft:mangrove_standing_sign", - "id": -494 - }, - { - "name": "minecraft:mangrove_trapdoor", - "id": -496 - }, - { - "name": "minecraft:mangrove_wall_sign", - "id": -495 - }, - { - "name": "minecraft:mangrove_wood", - "id": -497 - }, - { - "name": "minecraft:medicine", - "id": 606 - }, - { - "name": "minecraft:medium_amethyst_bud", - "id": -331 - }, - { - "name": "minecraft:melon_block", - "id": 103 - }, - { - "name": "minecraft:melon_seeds", - "id": 293 - }, - { - "name": "minecraft:melon_slice", - "id": 272 - }, - { - "name": "minecraft:melon_stem", - "id": 105 - }, - { - "name": "minecraft:milk_bucket", - "id": 363 - }, - { - "name": "minecraft:minecart", - "id": 372 - }, - { - "name": "minecraft:miner_pottery_sherd", - "id": 675 - }, - { - "name": "minecraft:mob_spawner", - "id": 52 - }, - { - "name": "minecraft:mojang_banner_pattern", - "id": 591 - }, - { - "name": "minecraft:monster_egg", - "id": 97 - }, - { - "name": "minecraft:mooshroom_spawn_egg", - "id": 442 - }, - { - "name": "minecraft:moss_block", - "id": -320 - }, - { - "name": "minecraft:moss_carpet", - "id": -335 - }, - { - "name": "minecraft:mossy_cobblestone", - "id": 48 - }, - { - "name": "minecraft:mossy_cobblestone_stairs", - "id": -179 - }, - { - "name": "minecraft:mossy_stone_brick_stairs", - "id": -175 - }, - { - "name": "minecraft:mourner_pottery_sherd", - "id": 676 - }, - { - "name": "minecraft:moving_block", - "id": 250 - }, - { - "name": "minecraft:mud", - "id": -473 - }, - { - "name": "minecraft:mud_brick_double_slab", - "id": -479 - }, - { - "name": "minecraft:mud_brick_slab", - "id": -478 - }, - { - "name": "minecraft:mud_brick_stairs", - "id": -480 - }, - { - "name": "minecraft:mud_brick_wall", - "id": -481 - }, - { - "name": "minecraft:mud_bricks", - "id": -475 - }, - { - "name": "minecraft:muddy_mangrove_roots", - "id": -483 - }, - { - "name": "minecraft:mule_spawn_egg", - "id": 468 - }, - { - "name": "minecraft:mushroom_stew", - "id": 260 - }, - { - "name": "minecraft:music_disc_11", - "id": 551 - }, - { - "name": "minecraft:music_disc_13", - "id": 541 - }, - { - "name": "minecraft:music_disc_5", - "id": 643 - }, - { - "name": "minecraft:music_disc_blocks", - "id": 543 - }, - { - "name": "minecraft:music_disc_cat", - "id": 542 - }, - { - "name": "minecraft:music_disc_chirp", - "id": 544 - }, - { - "name": "minecraft:music_disc_far", - "id": 545 - }, - { - "name": "minecraft:music_disc_mall", - "id": 546 - }, - { - "name": "minecraft:music_disc_mellohi", - "id": 547 - }, - { - "name": "minecraft:music_disc_otherside", - "id": 633 - }, - { - "name": "minecraft:music_disc_pigstep", - "id": 627 - }, - { - "name": "minecraft:music_disc_relic", - "id": 701 - }, - { - "name": "minecraft:music_disc_stal", - "id": 548 - }, - { - "name": "minecraft:music_disc_strad", - "id": 549 - }, - { - "name": "minecraft:music_disc_wait", - "id": 552 - }, - { - "name": "minecraft:music_disc_ward", - "id": 550 - }, - { - "name": "minecraft:mutton", - "id": 557 - }, - { - "name": "minecraft:mycelium", - "id": 110 - }, - { - "name": "minecraft:name_tag", - "id": 555 - }, - { - "name": "minecraft:nautilus_shell", - "id": 577 - }, - { - "name": "minecraft:nether_brick", - "id": 112 - }, - { - "name": "minecraft:nether_brick_fence", - "id": 113 - }, - { - "name": "minecraft:nether_brick_stairs", - "id": 114 - }, - { - "name": "minecraft:nether_gold_ore", - "id": -288 - }, - { - "name": "minecraft:nether_sprouts", - "id": 628 - }, - { - "name": "minecraft:nether_star", - "id": 525 - }, - { - "name": "minecraft:nether_wart", - "id": 294 - }, - { - "name": "minecraft:nether_wart_block", - "id": 214 - }, - { - "name": "minecraft:netherbrick", - "id": 530 - }, - { - "name": "minecraft:netherite_axe", - "id": 613 - }, - { - "name": "minecraft:netherite_block", - "id": -270 - }, - { - "name": "minecraft:netherite_boots", - "id": 619 - }, - { - "name": "minecraft:netherite_chestplate", - "id": 617 - }, - { - "name": "minecraft:netherite_helmet", - "id": 616 - }, - { - "name": "minecraft:netherite_hoe", - "id": 614 - }, - { - "name": "minecraft:netherite_ingot", - "id": 615 - }, - { - "name": "minecraft:netherite_leggings", - "id": 618 - }, - { - "name": "minecraft:netherite_pickaxe", - "id": 612 - }, - { - "name": "minecraft:netherite_scrap", - "id": 620 - }, - { - "name": "minecraft:netherite_shovel", - "id": 611 - }, - { - "name": "minecraft:netherite_sword", - "id": 610 - }, - { - "name": "minecraft:netherite_upgrade_smithing_template", - "id": 684 - }, - { - "name": "minecraft:netherrack", - "id": 87 - }, - { - "name": "minecraft:netherreactor", - "id": 247 - }, - { - "name": "minecraft:normal_stone_stairs", - "id": -180 - }, - { - "name": "minecraft:noteblock", - "id": 25 - }, - { - "name": "minecraft:npc_spawn_egg", - "id": 472 - }, - { - "name": "minecraft:oak_boat", - "id": 377 - }, - { - "name": "minecraft:oak_chest_boat", - "id": 645 - }, - { - "name": "minecraft:oak_fence", - "id": 85 - }, - { - "name": "minecraft:oak_hanging_sign", - "id": -500 - }, - { - "name": "minecraft:oak_log", - "id": 17 - }, - { - "name": "minecraft:oak_sign", - "id": 360 - }, - { - "name": "minecraft:oak_stairs", - "id": 53 - }, - { - "name": "minecraft:observer", - "id": 251 - }, - { - "name": "minecraft:obsidian", - "id": 49 - }, - { - "name": "minecraft:ocelot_spawn_egg", - "id": 453 - }, - { - "name": "minecraft:ochre_froglight", - "id": -471 - }, - { - "name": "minecraft:orange_candle", - "id": -414 - }, - { - "name": "minecraft:orange_candle_cake", - "id": -431 - }, - { - "name": "minecraft:orange_carpet", - "id": -597 - }, - { - "name": "minecraft:orange_concrete", - "id": -628 - }, - { - "name": "minecraft:orange_concrete_powder", - "id": -709 - }, - { - "name": "minecraft:orange_dye", - "id": 411 - }, - { - "name": "minecraft:orange_glazed_terracotta", - "id": 221 - }, - { - "name": "minecraft:orange_shulker_box", - "id": -613 - }, - { - "name": "minecraft:orange_stained_glass", - "id": -673 - }, - { - "name": "minecraft:orange_stained_glass_pane", - "id": -643 - }, - { - "name": "minecraft:orange_terracotta", - "id": -724 - }, - { - "name": "minecraft:orange_wool", - "id": -557 - }, - { - "name": "minecraft:oxidized_copper", - "id": -343 - }, - { - "name": "minecraft:oxidized_cut_copper", - "id": -350 - }, - { - "name": "minecraft:oxidized_cut_copper_slab", - "id": -364 - }, - { - "name": "minecraft:oxidized_cut_copper_stairs", - "id": -357 - }, - { - "name": "minecraft:oxidized_double_cut_copper_slab", - "id": -371 - }, - { - "name": "minecraft:packed_ice", - "id": 174 - }, - { - "name": "minecraft:packed_mud", - "id": -477 - }, - { - "name": "minecraft:painting", - "id": 359 - }, - { - "name": "minecraft:panda_spawn_egg", - "id": 491 - }, - { - "name": "minecraft:paper", - "id": 388 - }, - { - "name": "minecraft:parrot_spawn_egg", - "id": 480 - }, - { - "name": "minecraft:pearlescent_froglight", - "id": -469 - }, - { - "name": "minecraft:phantom_membrane", - "id": 581 - }, - { - "name": "minecraft:phantom_spawn_egg", - "id": 488 - }, - { - "name": "minecraft:pig_spawn_egg", - "id": 439 - }, - { - "name": "minecraft:piglin_banner_pattern", - "id": 594 - }, - { - "name": "minecraft:piglin_brute_spawn_egg", - "id": 501 - }, - { - "name": "minecraft:piglin_spawn_egg", - "id": 499 - }, - { - "name": "minecraft:pillager_spawn_egg", - "id": 493 - }, - { - "name": "minecraft:pink_candle", - "id": -419 - }, - { - "name": "minecraft:pink_candle_cake", - "id": -436 - }, - { - "name": "minecraft:pink_carpet", - "id": -602 - }, - { - "name": "minecraft:pink_concrete", - "id": -633 - }, - { - "name": "minecraft:pink_concrete_powder", - "id": -714 - }, - { - "name": "minecraft:pink_dye", - "id": 406 - }, - { - "name": "minecraft:pink_glazed_terracotta", - "id": 226 - }, - { - "name": "minecraft:pink_petals", - "id": -549 - }, - { - "name": "minecraft:pink_shulker_box", - "id": -618 - }, - { - "name": "minecraft:pink_stained_glass", - "id": -678 - }, - { - "name": "minecraft:pink_stained_glass_pane", - "id": -648 - }, - { - "name": "minecraft:pink_terracotta", - "id": -729 - }, - { - "name": "minecraft:pink_wool", - "id": -566 - }, - { - "name": "minecraft:piston", - "id": 33 - }, - { - "name": "minecraft:piston_arm_collision", - "id": 34 - }, - { - "name": "minecraft:pitcher_crop", - "id": -574 - }, - { - "name": "minecraft:pitcher_plant", - "id": -612 - }, - { - "name": "minecraft:pitcher_pod", - "id": 297 - }, - { - "name": "minecraft:planks", - "id": 5 - }, - { - "name": "minecraft:plenty_pottery_sherd", - "id": 677 - }, - { - "name": "minecraft:podzol", - "id": 243 - }, - { - "name": "minecraft:pointed_dripstone", - "id": -308 - }, - { - "name": "minecraft:poisonous_potato", - "id": 282 - }, - { - "name": "minecraft:polar_bear_spawn_egg", - "id": 474 - }, - { - "name": "minecraft:polished_andesite_stairs", - "id": -174 - }, - { - "name": "minecraft:polished_basalt", - "id": -235 - }, - { - "name": "minecraft:polished_blackstone", - "id": -291 - }, - { - "name": "minecraft:polished_blackstone_brick_double_slab", - "id": -285 - }, - { - "name": "minecraft:polished_blackstone_brick_slab", - "id": -284 - }, - { - "name": "minecraft:polished_blackstone_brick_stairs", - "id": -275 - }, - { - "name": "minecraft:polished_blackstone_brick_wall", - "id": -278 - }, - { - "name": "minecraft:polished_blackstone_bricks", - "id": -274 - }, - { - "name": "minecraft:polished_blackstone_button", - "id": -296 - }, - { - "name": "minecraft:polished_blackstone_double_slab", - "id": -294 - }, - { - "name": "minecraft:polished_blackstone_pressure_plate", - "id": -295 - }, - { - "name": "minecraft:polished_blackstone_slab", - "id": -293 - }, - { - "name": "minecraft:polished_blackstone_stairs", - "id": -292 - }, - { - "name": "minecraft:polished_blackstone_wall", - "id": -297 - }, - { - "name": "minecraft:polished_deepslate", - "id": -383 - }, - { - "name": "minecraft:polished_deepslate_double_slab", - "id": -397 - }, - { - "name": "minecraft:polished_deepslate_slab", - "id": -384 - }, - { - "name": "minecraft:polished_deepslate_stairs", - "id": -385 - }, - { - "name": "minecraft:polished_deepslate_wall", - "id": -386 - }, - { - "name": "minecraft:polished_diorite_stairs", - "id": -173 - }, - { - "name": "minecraft:polished_granite_stairs", - "id": -172 - }, - { - "name": "minecraft:popped_chorus_fruit", - "id": 566 - }, - { - "name": "minecraft:porkchop", - "id": 262 - }, - { - "name": "minecraft:portal", - "id": 90 - }, - { - "name": "minecraft:potato", - "id": 280 - }, - { - "name": "minecraft:potatoes", - "id": 142 - }, - { - "name": "minecraft:potion", - "id": 428 - }, - { - "name": "minecraft:powder_snow", - "id": -306 - }, - { - "name": "minecraft:powder_snow_bucket", - "id": 370 - }, - { - "name": "minecraft:powered_comparator", - "id": 150 - }, - { - "name": "minecraft:powered_repeater", - "id": 94 - }, - { - "name": "minecraft:prismarine", - "id": 168 - }, - { - "name": "minecraft:prismarine_bricks_stairs", - "id": -4 - }, - { - "name": "minecraft:prismarine_crystals", - "id": 556 - }, - { - "name": "minecraft:prismarine_shard", - "id": 572 - }, - { - "name": "minecraft:prismarine_stairs", - "id": -2 - }, - { - "name": "minecraft:prize_pottery_sherd", - "id": 678 - }, - { - "name": "minecraft:pufferfish", - "id": 267 - }, - { - "name": "minecraft:pufferfish_bucket", - "id": 369 - }, - { - "name": "minecraft:pufferfish_spawn_egg", - "id": 483 - }, - { - "name": "minecraft:pumpkin", - "id": 86 - }, - { - "name": "minecraft:pumpkin_pie", - "id": 284 - }, - { - "name": "minecraft:pumpkin_seeds", - "id": 292 - }, - { - "name": "minecraft:pumpkin_stem", - "id": 104 - }, - { - "name": "minecraft:purple_candle", - "id": -423 - }, - { - "name": "minecraft:purple_candle_cake", - "id": -440 - }, - { - "name": "minecraft:purple_carpet", - "id": -606 - }, - { - "name": "minecraft:purple_concrete", - "id": -637 - }, - { - "name": "minecraft:purple_concrete_powder", - "id": -718 - }, - { - "name": "minecraft:purple_dye", - "id": 402 - }, - { - "name": "minecraft:purple_glazed_terracotta", - "id": 219 - }, - { - "name": "minecraft:purple_shulker_box", - "id": -622 - }, - { - "name": "minecraft:purple_stained_glass", - "id": -682 - }, - { - "name": "minecraft:purple_stained_glass_pane", - "id": -652 - }, - { - "name": "minecraft:purple_terracotta", - "id": -733 - }, - { - "name": "minecraft:purple_wool", - "id": -564 - }, - { - "name": "minecraft:purpur_block", - "id": 201 - }, - { - "name": "minecraft:purpur_stairs", - "id": 203 - }, - { - "name": "minecraft:quartz", - "id": 531 - }, - { - "name": "minecraft:quartz_block", - "id": 155 - }, - { - "name": "minecraft:quartz_bricks", - "id": -304 - }, - { - "name": "minecraft:quartz_ore", - "id": 153 - }, - { - "name": "minecraft:quartz_stairs", - "id": 156 - }, - { - "name": "minecraft:rabbit", - "id": 288 - }, - { - "name": "minecraft:rabbit_foot", - "id": 535 - }, - { - "name": "minecraft:rabbit_hide", - "id": 536 - }, - { - "name": "minecraft:rabbit_spawn_egg", - "id": 461 - }, - { - "name": "minecraft:rabbit_stew", - "id": 290 - }, - { - "name": "minecraft:rail", - "id": 66 - }, - { - "name": "minecraft:raiser_armor_trim_smithing_template", - "id": 698 - }, - { - "name": "minecraft:rapid_fertilizer", - "id": 604 - }, - { - "name": "minecraft:ravager_spawn_egg", - "id": 495 - }, - { - "name": "minecraft:raw_copper", - "id": 514 - }, - { - "name": "minecraft:raw_copper_block", - "id": -452 - }, - { - "name": "minecraft:raw_gold", - "id": 513 - }, - { - "name": "minecraft:raw_gold_block", - "id": -453 - }, - { - "name": "minecraft:raw_iron", - "id": 512 - }, - { - "name": "minecraft:raw_iron_block", - "id": -451 - }, - { - "name": "minecraft:recovery_compass", - "id": 653 - }, - { - "name": "minecraft:red_candle", - "id": -427 - }, - { - "name": "minecraft:red_candle_cake", - "id": -444 - }, - { - "name": "minecraft:red_carpet", - "id": -610 - }, - { - "name": "minecraft:red_concrete", - "id": -641 - }, - { - "name": "minecraft:red_concrete_powder", - "id": -722 - }, - { - "name": "minecraft:red_dye", - "id": 398 - }, - { - "name": "minecraft:red_flower", - "id": 38 - }, - { - "name": "minecraft:red_glazed_terracotta", - "id": 234 - }, - { - "name": "minecraft:red_mushroom", - "id": 40 - }, - { - "name": "minecraft:red_mushroom_block", - "id": 100 - }, - { - "name": "minecraft:red_nether_brick", - "id": 215 - }, - { - "name": "minecraft:red_nether_brick_stairs", - "id": -184 - }, - { - "name": "minecraft:red_sandstone", - "id": 179 - }, - { - "name": "minecraft:red_sandstone_stairs", - "id": 180 - }, - { - "name": "minecraft:red_shulker_box", - "id": -626 - }, - { - "name": "minecraft:red_stained_glass", - "id": -686 - }, - { - "name": "minecraft:red_stained_glass_pane", - "id": -656 - }, - { - "name": "minecraft:red_terracotta", - "id": -737 - }, - { - "name": "minecraft:red_wool", - "id": -556 - }, - { - "name": "minecraft:redstone", - "id": 375 - }, - { - "name": "minecraft:redstone_block", - "id": 152 - }, - { - "name": "minecraft:redstone_lamp", - "id": 123 - }, - { - "name": "minecraft:redstone_ore", - "id": 73 - }, - { - "name": "minecraft:redstone_torch", - "id": 76 - }, - { - "name": "minecraft:redstone_wire", - "id": 55 - }, - { - "name": "minecraft:reinforced_deepslate", - "id": -466 - }, - { - "name": "minecraft:repeater", - "id": 421 - }, - { - "name": "minecraft:repeating_command_block", - "id": 188 - }, - { - "name": "minecraft:reserved6", - "id": 255 - }, - { - "name": "minecraft:respawn_anchor", - "id": -272 - }, - { - "name": "minecraft:rib_armor_trim_smithing_template", - "id": 694 - }, - { - "name": "minecraft:rotten_flesh", - "id": 277 - }, - { - "name": "minecraft:saddle", - "id": 373 - }, - { - "name": "minecraft:salmon", - "id": 265 - }, - { - "name": "minecraft:salmon_bucket", - "id": 367 - }, - { - "name": "minecraft:salmon_spawn_egg", - "id": 484 - }, - { - "name": "minecraft:sand", - "id": 12 - }, - { - "name": "minecraft:sandstone", - "id": 24 - }, - { - "name": "minecraft:sandstone_stairs", - "id": 128 - }, - { - "name": "minecraft:sapling", - "id": 6 - }, - { - "name": "minecraft:scaffolding", - "id": -165 - }, - { - "name": "minecraft:sculk", - "id": -458 - }, - { - "name": "minecraft:sculk_catalyst", - "id": -460 - }, - { - "name": "minecraft:sculk_sensor", - "id": -307 - }, - { - "name": "minecraft:sculk_shrieker", - "id": -461 - }, - { - "name": "minecraft:sculk_vein", - "id": -459 - }, - { - "name": "minecraft:scute", - "id": 579 - }, - { - "name": "minecraft:sea_lantern", - "id": 169 - }, - { - "name": "minecraft:sea_pickle", - "id": -156 - }, - { - "name": "minecraft:seagrass", - "id": -130 - }, - { - "name": "minecraft:sentry_armor_trim_smithing_template", - "id": 685 - }, - { - "name": "minecraft:shaper_armor_trim_smithing_template", - "id": 699 - }, - { - "name": "minecraft:sheaf_pottery_sherd", - "id": 679 - }, - { - "name": "minecraft:shears", - "id": 423 - }, - { - "name": "minecraft:sheep_spawn_egg", - "id": 440 - }, - { - "name": "minecraft:shelter_pottery_sherd", - "id": 680 - }, - { - "name": "minecraft:shield", - "id": 357 - }, - { - "name": "minecraft:shroomlight", - "id": -230 - }, - { - "name": "minecraft:shulker_box", - "id": 713 - }, - { - "name": "minecraft:shulker_shell", - "id": 573 - }, - { - "name": "minecraft:shulker_spawn_egg", - "id": 471 - }, - { - "name": "minecraft:silence_armor_trim_smithing_template", - "id": 696 - }, - { - "name": "minecraft:silver_glazed_terracotta", - "id": 228 - }, - { - "name": "minecraft:silverfish_spawn_egg", - "id": 445 - }, - { - "name": "minecraft:skeleton_horse_spawn_egg", - "id": 469 - }, - { - "name": "minecraft:skeleton_spawn_egg", - "id": 446 - }, - { - "name": "minecraft:skull", - "id": 523 - }, - { - "name": "minecraft:skull_banner_pattern", - "id": 590 - }, - { - "name": "minecraft:skull_pottery_sherd", - "id": 681 - }, - { - "name": "minecraft:slime", - "id": 165 - }, - { - "name": "minecraft:slime_ball", - "id": 390 - }, - { - "name": "minecraft:slime_spawn_egg", - "id": 447 - }, - { - "name": "minecraft:small_amethyst_bud", - "id": -332 - }, - { - "name": "minecraft:small_dripleaf_block", - "id": -336 - }, - { - "name": "minecraft:smithing_table", - "id": -202 - }, - { - "name": "minecraft:smoker", - "id": -198 - }, - { - "name": "minecraft:smooth_basalt", - "id": -377 - }, - { - "name": "minecraft:smooth_quartz_stairs", - "id": -185 - }, - { - "name": "minecraft:smooth_red_sandstone_stairs", - "id": -176 - }, - { - "name": "minecraft:smooth_sandstone_stairs", - "id": -177 - }, - { - "name": "minecraft:smooth_stone", - "id": -183 - }, - { - "name": "minecraft:sniffer_egg", - "id": -596 - }, - { - "name": "minecraft:sniffer_spawn_egg", - "id": 502 - }, - { - "name": "minecraft:snort_pottery_sherd", - "id": 682 - }, - { - "name": "minecraft:snout_armor_trim_smithing_template", - "id": 693 - }, - { - "name": "minecraft:snow", - "id": 80 - }, - { - "name": "minecraft:snow_golem_spawn_egg", - "id": 507 - }, - { - "name": "minecraft:snow_layer", - "id": 78 - }, - { - "name": "minecraft:snowball", - "id": 376 - }, - { - "name": "minecraft:soul_campfire", - "id": 629 - }, - { - "name": "minecraft:soul_fire", - "id": -237 - }, - { - "name": "minecraft:soul_lantern", - "id": -269 - }, - { - "name": "minecraft:soul_sand", - "id": 88 - }, - { - "name": "minecraft:soul_soil", - "id": -236 - }, - { - "name": "minecraft:soul_torch", - "id": -268 - }, - { - "name": "minecraft:sparkler", - "id": 607 - }, - { - "name": "minecraft:spawn_egg", - "id": 717 - }, - { - "name": "minecraft:spider_eye", - "id": 278 - }, - { - "name": "minecraft:spider_spawn_egg", - "id": 448 - }, - { - "name": "minecraft:spire_armor_trim_smithing_template", - "id": 695 - }, - { - "name": "minecraft:splash_potion", - "id": 568 - }, - { - "name": "minecraft:sponge", - "id": 19 - }, - { - "name": "minecraft:spore_blossom", - "id": -321 - }, - { - "name": "minecraft:spruce_boat", - "id": 380 - }, - { - "name": "minecraft:spruce_button", - "id": -144 - }, - { - "name": "minecraft:spruce_chest_boat", - "id": 648 - }, - { - "name": "minecraft:spruce_door", - "id": 560 - }, - { - "name": "minecraft:spruce_fence", - "id": -579 - }, - { - "name": "minecraft:spruce_fence_gate", - "id": 183 - }, - { - "name": "minecraft:spruce_hanging_sign", - "id": -501 - }, - { - "name": "minecraft:spruce_log", - "id": -569 - }, - { - "name": "minecraft:spruce_pressure_plate", - "id": -154 - }, - { - "name": "minecraft:spruce_sign", - "id": 583 - }, - { - "name": "minecraft:spruce_stairs", - "id": 134 - }, - { - "name": "minecraft:spruce_standing_sign", - "id": -181 - }, - { - "name": "minecraft:spruce_trapdoor", - "id": -149 - }, - { - "name": "minecraft:spruce_wall_sign", - "id": -182 - }, - { - "name": "minecraft:spyglass", - "id": 632 - }, - { - "name": "minecraft:squid_spawn_egg", - "id": 452 - }, - { - "name": "minecraft:stained_glass", - "id": 711 - }, - { - "name": "minecraft:stained_glass_pane", - "id": 712 - }, - { - "name": "minecraft:stained_hardened_clay", - "id": 702 - }, - { - "name": "minecraft:standing_banner", - "id": 176 - }, - { - "name": "minecraft:standing_sign", - "id": 63 - }, - { - "name": "minecraft:stick", - "id": 322 - }, - { - "name": "minecraft:sticky_piston", - "id": 29 - }, - { - "name": "minecraft:sticky_piston_arm_collision", - "id": -217 - }, - { - "name": "minecraft:stone", - "id": 1 - }, - { - "name": "minecraft:stone_axe", - "id": 317 - }, - { - "name": "minecraft:stone_block_slab", - "id": 44 - }, - { - "name": "minecraft:stone_block_slab2", - "id": 182 - }, - { - "name": "minecraft:stone_block_slab3", - "id": -162 - }, - { - "name": "minecraft:stone_block_slab4", - "id": -166 - }, - { - "name": "minecraft:stone_brick_stairs", - "id": 109 - }, - { - "name": "minecraft:stone_button", - "id": 77 - }, - { - "name": "minecraft:stone_hoe", - "id": 332 - }, - { - "name": "minecraft:stone_pickaxe", - "id": 316 - }, - { - "name": "minecraft:stone_pressure_plate", - "id": 70 - }, - { - "name": "minecraft:stone_shovel", - "id": 315 - }, - { - "name": "minecraft:stone_stairs", - "id": 67 - }, - { - "name": "minecraft:stone_sword", - "id": 314 - }, - { - "name": "minecraft:stonebrick", - "id": 98 - }, - { - "name": "minecraft:stonecutter", - "id": 245 - }, - { - "name": "minecraft:stonecutter_block", - "id": -197 - }, - { - "name": "minecraft:stray_spawn_egg", - "id": 464 - }, - { - "name": "minecraft:strider_spawn_egg", - "id": 497 - }, - { - "name": "minecraft:string", - "id": 328 - }, - { - "name": "minecraft:stripped_acacia_log", - "id": -8 - }, - { - "name": "minecraft:stripped_bamboo_block", - "id": -528 - }, - { - "name": "minecraft:stripped_birch_log", - "id": -6 - }, - { - "name": "minecraft:stripped_cherry_log", - "id": -535 - }, - { - "name": "minecraft:stripped_cherry_wood", - "id": -545 - }, - { - "name": "minecraft:stripped_crimson_hyphae", - "id": -300 - }, - { - "name": "minecraft:stripped_crimson_stem", - "id": -240 - }, - { - "name": "minecraft:stripped_dark_oak_log", - "id": -9 - }, - { - "name": "minecraft:stripped_jungle_log", - "id": -7 - }, - { - "name": "minecraft:stripped_mangrove_log", - "id": -485 - }, - { - "name": "minecraft:stripped_mangrove_wood", - "id": -498 - }, - { - "name": "minecraft:stripped_oak_log", - "id": -10 - }, - { - "name": "minecraft:stripped_spruce_log", - "id": -5 - }, - { - "name": "minecraft:stripped_warped_hyphae", - "id": -301 - }, - { - "name": "minecraft:stripped_warped_stem", - "id": -241 - }, - { - "name": "minecraft:structure_block", - "id": 252 - }, - { - "name": "minecraft:structure_void", - "id": 217 - }, - { - "name": "minecraft:sugar", - "id": 418 - }, - { - "name": "minecraft:sugar_cane", - "id": 387 - }, - { - "name": "minecraft:suspicious_gravel", - "id": -573 - }, - { - "name": "minecraft:suspicious_sand", - "id": -529 - }, - { - "name": "minecraft:suspicious_stew", - "id": 597 - }, - { - "name": "minecraft:sweet_berries", - "id": 287 - }, - { - "name": "minecraft:sweet_berry_bush", - "id": -207 - }, - { - "name": "minecraft:tadpole_bucket", - "id": 637 - }, - { - "name": "minecraft:tadpole_spawn_egg", - "id": 636 - }, - { - "name": "minecraft:tallgrass", - "id": 31 - }, - { - "name": "minecraft:target", - "id": -239 - }, - { - "name": "minecraft:tide_armor_trim_smithing_template", - "id": 692 - }, - { - "name": "minecraft:tinted_glass", - "id": -334 - }, - { - "name": "minecraft:tnt", - "id": 46 - }, - { - "name": "minecraft:tnt_minecart", - "id": 532 - }, - { - "name": "minecraft:torch", - "id": 50 - }, - { - "name": "minecraft:torchflower", - "id": -568 - }, - { - "name": "minecraft:torchflower_crop", - "id": -567 - }, - { - "name": "minecraft:torchflower_seeds", - "id": 296 - }, - { - "name": "minecraft:totem_of_undying", - "id": 575 - }, - { - "name": "minecraft:trader_llama_spawn_egg", - "id": 655 - }, - { - "name": "minecraft:trapdoor", - "id": 96 - }, - { - "name": "minecraft:trapped_chest", - "id": 146 - }, - { - "name": "minecraft:trident", - "id": 553 - }, - { - "name": "minecraft:trip_wire", - "id": 132 - }, - { - "name": "minecraft:tripwire_hook", - "id": 131 - }, - { - "name": "minecraft:tropical_fish", - "id": 266 - }, - { - "name": "minecraft:tropical_fish_bucket", - "id": 368 - }, - { - "name": "minecraft:tropical_fish_spawn_egg", - "id": 481 - }, - { - "name": "minecraft:tube_coral", - "id": -131 - }, - { - "name": "minecraft:tuff", - "id": -333 - }, - { - "name": "minecraft:turtle_egg", - "id": -159 - }, - { - "name": "minecraft:turtle_helmet", - "id": 580 - }, - { - "name": "minecraft:turtle_spawn_egg", - "id": 487 - }, - { - "name": "minecraft:twisting_vines", - "id": -287 - }, - { - "name": "minecraft:underwater_torch", - "id": 239 - }, - { - "name": "minecraft:undyed_shulker_box", - "id": 205 - }, - { - "name": "minecraft:unknown", - "id": -305 - }, - { - "name": "minecraft:unlit_redstone_torch", - "id": 75 - }, - { - "name": "minecraft:unpowered_comparator", - "id": 149 - }, - { - "name": "minecraft:unpowered_repeater", - "id": 93 - }, - { - "name": "minecraft:verdant_froglight", - "id": -470 - }, - { - "name": "minecraft:vex_armor_trim_smithing_template", - "id": 691 - }, - { - "name": "minecraft:vex_spawn_egg", - "id": 478 - }, - { - "name": "minecraft:villager_spawn_egg", - "id": 451 - }, - { - "name": "minecraft:vindicator_spawn_egg", - "id": 476 - }, - { - "name": "minecraft:vine", - "id": 106 - }, - { - "name": "minecraft:wall_banner", - "id": 177 - }, - { - "name": "minecraft:wall_sign", - "id": 68 - }, - { - "name": "minecraft:wandering_trader_spawn_egg", - "id": 494 - }, - { - "name": "minecraft:ward_armor_trim_smithing_template", - "id": 689 - }, - { - "name": "minecraft:warden_spawn_egg", - "id": 639 - }, - { - "name": "minecraft:warped_button", - "id": -261 - }, - { - "name": "minecraft:warped_door", - "id": 624 - }, - { - "name": "minecraft:warped_double_slab", - "id": -267 - }, - { - "name": "minecraft:warped_fence", - "id": -257 - }, - { - "name": "minecraft:warped_fence_gate", - "id": -259 - }, - { - "name": "minecraft:warped_fungus", - "id": -229 - }, - { - "name": "minecraft:warped_fungus_on_a_stick", - "id": 625 - }, - { - "name": "minecraft:warped_hanging_sign", - "id": -507 - }, - { - "name": "minecraft:warped_hyphae", - "id": -298 - }, - { - "name": "minecraft:warped_nylium", - "id": -233 - }, - { - "name": "minecraft:warped_planks", - "id": -243 - }, - { - "name": "minecraft:warped_pressure_plate", - "id": -263 - }, - { - "name": "minecraft:warped_roots", - "id": -224 - }, - { - "name": "minecraft:warped_sign", - "id": 622 - }, - { - "name": "minecraft:warped_slab", - "id": -265 - }, - { - "name": "minecraft:warped_stairs", - "id": -255 - }, - { - "name": "minecraft:warped_standing_sign", - "id": -251 - }, - { - "name": "minecraft:warped_stem", - "id": -226 - }, - { - "name": "minecraft:warped_trapdoor", - "id": -247 - }, - { - "name": "minecraft:warped_wall_sign", - "id": -253 - }, - { - "name": "minecraft:warped_wart_block", - "id": -227 - }, - { - "name": "minecraft:water", - "id": 9 - }, - { - "name": "minecraft:water_bucket", - "id": 364 - }, - { - "name": "minecraft:waterlily", - "id": 111 - }, - { - "name": "minecraft:waxed_copper", - "id": -344 - }, - { - "name": "minecraft:waxed_cut_copper", - "id": -351 - }, - { - "name": "minecraft:waxed_cut_copper_slab", - "id": -365 - }, - { - "name": "minecraft:waxed_cut_copper_stairs", - "id": -358 - }, - { - "name": "minecraft:waxed_double_cut_copper_slab", - "id": -372 - }, - { - "name": "minecraft:waxed_exposed_copper", - "id": -345 - }, - { - "name": "minecraft:waxed_exposed_cut_copper", - "id": -352 - }, - { - "name": "minecraft:waxed_exposed_cut_copper_slab", - "id": -366 - }, - { - "name": "minecraft:waxed_exposed_cut_copper_stairs", - "id": -359 - }, - { - "name": "minecraft:waxed_exposed_double_cut_copper_slab", - "id": -373 - }, - { - "name": "minecraft:waxed_oxidized_copper", - "id": -446 - }, - { - "name": "minecraft:waxed_oxidized_cut_copper", - "id": -447 - }, - { - "name": "minecraft:waxed_oxidized_cut_copper_slab", - "id": -449 - }, - { - "name": "minecraft:waxed_oxidized_cut_copper_stairs", - "id": -448 - }, - { - "name": "minecraft:waxed_oxidized_double_cut_copper_slab", - "id": -450 - }, - { - "name": "minecraft:waxed_weathered_copper", - "id": -346 - }, - { - "name": "minecraft:waxed_weathered_cut_copper", - "id": -353 - }, - { - "name": "minecraft:waxed_weathered_cut_copper_slab", - "id": -367 - }, - { - "name": "minecraft:waxed_weathered_cut_copper_stairs", - "id": -360 - }, - { - "name": "minecraft:waxed_weathered_double_cut_copper_slab", - "id": -374 - }, - { - "name": "minecraft:wayfinder_armor_trim_smithing_template", - "id": 697 - }, - { - "name": "minecraft:weathered_copper", - "id": -342 - }, - { - "name": "minecraft:weathered_cut_copper", - "id": -349 - }, - { - "name": "minecraft:weathered_cut_copper_slab", - "id": -363 - }, - { - "name": "minecraft:weathered_cut_copper_stairs", - "id": -356 - }, - { - "name": "minecraft:weathered_double_cut_copper_slab", - "id": -370 - }, - { - "name": "minecraft:web", - "id": 30 - }, - { - "name": "minecraft:weeping_vines", - "id": -231 - }, - { - "name": "minecraft:wheat", - "id": 336 - }, - { - "name": "minecraft:wheat_seeds", - "id": 291 - }, - { - "name": "minecraft:white_candle", - "id": -413 - }, - { - "name": "minecraft:white_candle_cake", - "id": -430 - }, - { - "name": "minecraft:white_carpet", - "id": 171 - }, - { - "name": "minecraft:white_concrete", - "id": 236 - }, - { - "name": "minecraft:white_concrete_powder", - "id": 237 - }, - { - "name": "minecraft:white_dye", - "id": 412 - }, - { - "name": "minecraft:white_glazed_terracotta", - "id": 220 - }, - { - "name": "minecraft:white_shulker_box", - "id": 218 - }, - { - "name": "minecraft:white_stained_glass", - "id": 241 - }, - { - "name": "minecraft:white_stained_glass_pane", - "id": 160 - }, - { - "name": "minecraft:white_terracotta", - "id": 159 - }, - { - "name": "minecraft:white_wool", - "id": 35 - }, - { - "name": "minecraft:wild_armor_trim_smithing_template", - "id": 688 - }, - { - "name": "minecraft:witch_spawn_egg", - "id": 454 - }, - { - "name": "minecraft:wither_rose", - "id": -216 - }, - { - "name": "minecraft:wither_skeleton_spawn_egg", - "id": 466 - }, - { - "name": "minecraft:wither_spawn_egg", - "id": 509 - }, - { - "name": "minecraft:wolf_spawn_egg", - "id": 441 - }, - { - "name": "minecraft:wood", - "id": -212 - }, - { - "name": "minecraft:wooden_axe", - "id": 313 - }, - { - "name": "minecraft:wooden_button", - "id": 143 - }, - { - "name": "minecraft:wooden_door", - "id": 361 - }, - { - "name": "minecraft:wooden_hoe", - "id": 331 - }, - { - "name": "minecraft:wooden_pickaxe", - "id": 312 - }, - { - "name": "minecraft:wooden_pressure_plate", - "id": 72 - }, - { - "name": "minecraft:wooden_shovel", - "id": 311 - }, - { - "name": "minecraft:wooden_slab", - "id": 158 - }, - { - "name": "minecraft:wooden_sword", - "id": 310 - }, - { - "name": "minecraft:wool", - "id": 703 - }, - { - "name": "minecraft:writable_book", - "id": 517 - }, - { - "name": "minecraft:written_book", - "id": 518 - }, - { - "name": "minecraft:yellow_candle", - "id": -417 - }, - { - "name": "minecraft:yellow_candle_cake", - "id": -434 - }, - { - "name": "minecraft:yellow_carpet", - "id": -600 - }, - { - "name": "minecraft:yellow_concrete", - "id": -631 - }, - { - "name": "minecraft:yellow_concrete_powder", - "id": -712 - }, - { - "name": "minecraft:yellow_dye", - "id": 408 - }, - { - "name": "minecraft:yellow_flower", - "id": 37 - }, - { - "name": "minecraft:yellow_glazed_terracotta", - "id": 224 - }, - { - "name": "minecraft:yellow_shulker_box", - "id": -616 - }, - { - "name": "minecraft:yellow_stained_glass", - "id": -676 - }, - { - "name": "minecraft:yellow_stained_glass_pane", - "id": -646 - }, - { - "name": "minecraft:yellow_terracotta", - "id": -727 - }, - { - "name": "minecraft:yellow_wool", - "id": -558 - }, - { - "name": "minecraft:zoglin_spawn_egg", - "id": 500 - }, - { - "name": "minecraft:zombie_horse_spawn_egg", - "id": 470 - }, - { - "name": "minecraft:zombie_pigman_spawn_egg", - "id": 450 - }, - { - "name": "minecraft:zombie_spawn_egg", - "id": 449 - }, - { - "name": "minecraft:zombie_villager_spawn_egg", - "id": 479 - } -] \ No newline at end of file diff --git a/core/src/main/resources/bedrock/runtime_item_states.1_20_50.json b/core/src/main/resources/bedrock/runtime_item_states.1_20_50.json deleted file mode 100644 index d7535269f..000000000 --- a/core/src/main/resources/bedrock/runtime_item_states.1_20_50.json +++ /dev/null @@ -1,5846 +0,0 @@ -[ - { - "name": "minecraft:acacia_boat", - "id": 382 - }, - { - "name": "minecraft:acacia_button", - "id": -140 - }, - { - "name": "minecraft:acacia_chest_boat", - "id": 650 - }, - { - "name": "minecraft:acacia_door", - "id": 564 - }, - { - "name": "minecraft:acacia_fence", - "id": -575 - }, - { - "name": "minecraft:acacia_fence_gate", - "id": 187 - }, - { - "name": "minecraft:acacia_hanging_sign", - "id": -504 - }, - { - "name": "minecraft:acacia_log", - "id": 162 - }, - { - "name": "minecraft:acacia_planks", - "id": -742 - }, - { - "name": "minecraft:acacia_pressure_plate", - "id": -150 - }, - { - "name": "minecraft:acacia_sign", - "id": 587 - }, - { - "name": "minecraft:acacia_stairs", - "id": 163 - }, - { - "name": "minecraft:acacia_standing_sign", - "id": -190 - }, - { - "name": "minecraft:acacia_trapdoor", - "id": -145 - }, - { - "name": "minecraft:acacia_wall_sign", - "id": -191 - }, - { - "name": "minecraft:activator_rail", - "id": 126 - }, - { - "name": "minecraft:agent_spawn_egg", - "id": 490 - }, - { - "name": "minecraft:air", - "id": -158 - }, - { - "name": "minecraft:allay_spawn_egg", - "id": 639 - }, - { - "name": "minecraft:allow", - "id": 210 - }, - { - "name": "minecraft:amethyst_block", - "id": -327 - }, - { - "name": "minecraft:amethyst_cluster", - "id": -329 - }, - { - "name": "minecraft:amethyst_shard", - "id": 632 - }, - { - "name": "minecraft:ancient_debris", - "id": -271 - }, - { - "name": "minecraft:andesite", - "id": -594 - }, - { - "name": "minecraft:andesite_stairs", - "id": -171 - }, - { - "name": "minecraft:angler_pottery_sherd", - "id": 664 - }, - { - "name": "minecraft:anvil", - "id": 145 - }, - { - "name": "minecraft:apple", - "id": 257 - }, - { - "name": "minecraft:archer_pottery_sherd", - "id": 665 - }, - { - "name": "minecraft:armor_stand", - "id": 560 - }, - { - "name": "minecraft:arms_up_pottery_sherd", - "id": 666 - }, - { - "name": "minecraft:arrow", - "id": 304 - }, - { - "name": "minecraft:axolotl_bucket", - "id": 372 - }, - { - "name": "minecraft:axolotl_spawn_egg", - "id": 504 - }, - { - "name": "minecraft:azalea", - "id": -337 - }, - { - "name": "minecraft:azalea_leaves", - "id": -324 - }, - { - "name": "minecraft:azalea_leaves_flowered", - "id": -325 - }, - { - "name": "minecraft:baked_potato", - "id": 282 - }, - { - "name": "minecraft:balloon", - "id": 606 - }, - { - "name": "minecraft:bamboo", - "id": -163 - }, - { - "name": "minecraft:bamboo_block", - "id": -527 - }, - { - "name": "minecraft:bamboo_button", - "id": -511 - }, - { - "name": "minecraft:bamboo_chest_raft", - "id": 662 - }, - { - "name": "minecraft:bamboo_door", - "id": -517 - }, - { - "name": "minecraft:bamboo_double_slab", - "id": -521 - }, - { - "name": "minecraft:bamboo_fence", - "id": -515 - }, - { - "name": "minecraft:bamboo_fence_gate", - "id": -516 - }, - { - "name": "minecraft:bamboo_hanging_sign", - "id": -522 - }, - { - "name": "minecraft:bamboo_mosaic", - "id": -509 - }, - { - "name": "minecraft:bamboo_mosaic_double_slab", - "id": -525 - }, - { - "name": "minecraft:bamboo_mosaic_slab", - "id": -524 - }, - { - "name": "minecraft:bamboo_mosaic_stairs", - "id": -523 - }, - { - "name": "minecraft:bamboo_planks", - "id": -510 - }, - { - "name": "minecraft:bamboo_pressure_plate", - "id": -514 - }, - { - "name": "minecraft:bamboo_raft", - "id": 661 - }, - { - "name": "minecraft:bamboo_sapling", - "id": -164 - }, - { - "name": "minecraft:bamboo_sign", - "id": 660 - }, - { - "name": "minecraft:bamboo_slab", - "id": -513 - }, - { - "name": "minecraft:bamboo_stairs", - "id": -512 - }, - { - "name": "minecraft:bamboo_standing_sign", - "id": -518 - }, - { - "name": "minecraft:bamboo_trapdoor", - "id": -520 - }, - { - "name": "minecraft:bamboo_wall_sign", - "id": -519 - }, - { - "name": "minecraft:banner", - "id": 575 - }, - { - "name": "minecraft:banner_pattern", - "id": 718 - }, - { - "name": "minecraft:barrel", - "id": -203 - }, - { - "name": "minecraft:barrier", - "id": -161 - }, - { - "name": "minecraft:basalt", - "id": -234 - }, - { - "name": "minecraft:bat_spawn_egg", - "id": 456 - }, - { - "name": "minecraft:beacon", - "id": 138 - }, - { - "name": "minecraft:bed", - "id": 421 - }, - { - "name": "minecraft:bedrock", - "id": 7 - }, - { - "name": "minecraft:bee_nest", - "id": -218 - }, - { - "name": "minecraft:bee_spawn_egg", - "id": 497 - }, - { - "name": "minecraft:beef", - "id": 274 - }, - { - "name": "minecraft:beehive", - "id": -219 - }, - { - "name": "minecraft:beetroot", - "id": 286 - }, - { - "name": "minecraft:beetroot_seeds", - "id": 296 - }, - { - "name": "minecraft:beetroot_soup", - "id": 287 - }, - { - "name": "minecraft:bell", - "id": -206 - }, - { - "name": "minecraft:big_dripleaf", - "id": -323 - }, - { - "name": "minecraft:birch_boat", - "id": 379 - }, - { - "name": "minecraft:birch_button", - "id": -141 - }, - { - "name": "minecraft:birch_chest_boat", - "id": 647 - }, - { - "name": "minecraft:birch_door", - "id": 562 - }, - { - "name": "minecraft:birch_fence", - "id": -576 - }, - { - "name": "minecraft:birch_fence_gate", - "id": 184 - }, - { - "name": "minecraft:birch_hanging_sign", - "id": -502 - }, - { - "name": "minecraft:birch_log", - "id": -570 - }, - { - "name": "minecraft:birch_planks", - "id": -740 - }, - { - "name": "minecraft:birch_pressure_plate", - "id": -151 - }, - { - "name": "minecraft:birch_sign", - "id": 585 - }, - { - "name": "minecraft:birch_stairs", - "id": 135 - }, - { - "name": "minecraft:birch_standing_sign", - "id": -186 - }, - { - "name": "minecraft:birch_trapdoor", - "id": -146 - }, - { - "name": "minecraft:birch_wall_sign", - "id": -187 - }, - { - "name": "minecraft:black_candle", - "id": -428 - }, - { - "name": "minecraft:black_candle_cake", - "id": -445 - }, - { - "name": "minecraft:black_carpet", - "id": -611 - }, - { - "name": "minecraft:black_concrete", - "id": -642 - }, - { - "name": "minecraft:black_concrete_powder", - "id": -723 - }, - { - "name": "minecraft:black_dye", - "id": 398 - }, - { - "name": "minecraft:black_glazed_terracotta", - "id": 235 - }, - { - "name": "minecraft:black_shulker_box", - "id": -627 - }, - { - "name": "minecraft:black_stained_glass", - "id": -687 - }, - { - "name": "minecraft:black_stained_glass_pane", - "id": -657 - }, - { - "name": "minecraft:black_terracotta", - "id": -738 - }, - { - "name": "minecraft:black_wool", - "id": -554 - }, - { - "name": "minecraft:blackstone", - "id": -273 - }, - { - "name": "minecraft:blackstone_double_slab", - "id": -283 - }, - { - "name": "minecraft:blackstone_slab", - "id": -282 - }, - { - "name": "minecraft:blackstone_stairs", - "id": -276 - }, - { - "name": "minecraft:blackstone_wall", - "id": -277 - }, - { - "name": "minecraft:blade_pottery_sherd", - "id": 667 - }, - { - "name": "minecraft:blast_furnace", - "id": -196 - }, - { - "name": "minecraft:blaze_powder", - "id": 432 - }, - { - "name": "minecraft:blaze_rod", - "id": 426 - }, - { - "name": "minecraft:blaze_spawn_egg", - "id": 459 - }, - { - "name": "minecraft:bleach", - "id": 604 - }, - { - "name": "minecraft:blue_candle", - "id": -424 - }, - { - "name": "minecraft:blue_candle_cake", - "id": -441 - }, - { - "name": "minecraft:blue_carpet", - "id": -607 - }, - { - "name": "minecraft:blue_concrete", - "id": -638 - }, - { - "name": "minecraft:blue_concrete_powder", - "id": -719 - }, - { - "name": "minecraft:blue_dye", - "id": 402 - }, - { - "name": "minecraft:blue_glazed_terracotta", - "id": 231 - }, - { - "name": "minecraft:blue_ice", - "id": -11 - }, - { - "name": "minecraft:blue_shulker_box", - "id": -623 - }, - { - "name": "minecraft:blue_stained_glass", - "id": -683 - }, - { - "name": "minecraft:blue_stained_glass_pane", - "id": -653 - }, - { - "name": "minecraft:blue_terracotta", - "id": -734 - }, - { - "name": "minecraft:blue_wool", - "id": -563 - }, - { - "name": "minecraft:boat", - "id": 716 - }, - { - "name": "minecraft:bone", - "id": 418 - }, - { - "name": "minecraft:bone_block", - "id": 216 - }, - { - "name": "minecraft:bone_meal", - "id": 414 - }, - { - "name": "minecraft:book", - "id": 390 - }, - { - "name": "minecraft:bookshelf", - "id": 47 - }, - { - "name": "minecraft:border_block", - "id": 212 - }, - { - "name": "minecraft:bordure_indented_banner_pattern", - "id": 594 - }, - { - "name": "minecraft:bow", - "id": 303 - }, - { - "name": "minecraft:bowl", - "id": 324 - }, - { - "name": "minecraft:brain_coral", - "id": -581 - }, - { - "name": "minecraft:bread", - "id": 262 - }, - { - "name": "minecraft:brewer_pottery_sherd", - "id": 668 - }, - { - "name": "minecraft:brewing_stand", - "id": 434 - }, - { - "name": "minecraft:brick", - "id": 386 - }, - { - "name": "minecraft:brick_block", - "id": 45 - }, - { - "name": "minecraft:brick_stairs", - "id": 108 - }, - { - "name": "minecraft:brown_candle", - "id": -425 - }, - { - "name": "minecraft:brown_candle_cake", - "id": -442 - }, - { - "name": "minecraft:brown_carpet", - "id": -608 - }, - { - "name": "minecraft:brown_concrete", - "id": -639 - }, - { - "name": "minecraft:brown_concrete_powder", - "id": -720 - }, - { - "name": "minecraft:brown_dye", - "id": 401 - }, - { - "name": "minecraft:brown_glazed_terracotta", - "id": 232 - }, - { - "name": "minecraft:brown_mushroom", - "id": 39 - }, - { - "name": "minecraft:brown_mushroom_block", - "id": 99 - }, - { - "name": "minecraft:brown_shulker_box", - "id": -624 - }, - { - "name": "minecraft:brown_stained_glass", - "id": -684 - }, - { - "name": "minecraft:brown_stained_glass_pane", - "id": -654 - }, - { - "name": "minecraft:brown_terracotta", - "id": -735 - }, - { - "name": "minecraft:brown_wool", - "id": -555 - }, - { - "name": "minecraft:brush", - "id": 684 - }, - { - "name": "minecraft:bubble_column", - "id": -160 - }, - { - "name": "minecraft:bubble_coral", - "id": -582 - }, - { - "name": "minecraft:bucket", - "id": 363 - }, - { - "name": "minecraft:budding_amethyst", - "id": -328 - }, - { - "name": "minecraft:burn_pottery_sherd", - "id": 669 - }, - { - "name": "minecraft:cactus", - "id": 81 - }, - { - "name": "minecraft:cake", - "id": 420 - }, - { - "name": "minecraft:calcite", - "id": -326 - }, - { - "name": "minecraft:calibrated_sculk_sensor", - "id": -580 - }, - { - "name": "minecraft:camel_spawn_egg", - "id": 663 - }, - { - "name": "minecraft:camera", - "id": 601 - }, - { - "name": "minecraft:campfire", - "id": 597 - }, - { - "name": "minecraft:candle", - "id": -412 - }, - { - "name": "minecraft:candle_cake", - "id": -429 - }, - { - "name": "minecraft:carpet", - "id": 705 - }, - { - "name": "minecraft:carrot", - "id": 280 - }, - { - "name": "minecraft:carrot_on_a_stick", - "id": 525 - }, - { - "name": "minecraft:carrots", - "id": 141 - }, - { - "name": "minecraft:cartography_table", - "id": -200 - }, - { - "name": "minecraft:carved_pumpkin", - "id": -155 - }, - { - "name": "minecraft:cat_spawn_egg", - "id": 491 - }, - { - "name": "minecraft:cauldron", - "id": 435 - }, - { - "name": "minecraft:cave_spider_spawn_egg", - "id": 460 - }, - { - "name": "minecraft:cave_vines", - "id": -322 - }, - { - "name": "minecraft:cave_vines_body_with_berries", - "id": -375 - }, - { - "name": "minecraft:cave_vines_head_with_berries", - "id": -376 - }, - { - "name": "minecraft:chain", - "id": 627 - }, - { - "name": "minecraft:chain_command_block", - "id": 189 - }, - { - "name": "minecraft:chainmail_boots", - "id": 345 - }, - { - "name": "minecraft:chainmail_chestplate", - "id": 343 - }, - { - "name": "minecraft:chainmail_helmet", - "id": 342 - }, - { - "name": "minecraft:chainmail_leggings", - "id": 344 - }, - { - "name": "minecraft:charcoal", - "id": 306 - }, - { - "name": "minecraft:chemical_heat", - "id": 192 - }, - { - "name": "minecraft:chemistry_table", - "id": 238 - }, - { - "name": "minecraft:cherry_boat", - "id": 657 - }, - { - "name": "minecraft:cherry_button", - "id": -530 - }, - { - "name": "minecraft:cherry_chest_boat", - "id": 658 - }, - { - "name": "minecraft:cherry_door", - "id": -531 - }, - { - "name": "minecraft:cherry_double_slab", - "id": -540 - }, - { - "name": "minecraft:cherry_fence", - "id": -532 - }, - { - "name": "minecraft:cherry_fence_gate", - "id": -533 - }, - { - "name": "minecraft:cherry_hanging_sign", - "id": -534 - }, - { - "name": "minecraft:cherry_leaves", - "id": -548 - }, - { - "name": "minecraft:cherry_log", - "id": -536 - }, - { - "name": "minecraft:cherry_planks", - "id": -537 - }, - { - "name": "minecraft:cherry_pressure_plate", - "id": -538 - }, - { - "name": "minecraft:cherry_sapling", - "id": -547 - }, - { - "name": "minecraft:cherry_sign", - "id": 659 - }, - { - "name": "minecraft:cherry_slab", - "id": -539 - }, - { - "name": "minecraft:cherry_stairs", - "id": -541 - }, - { - "name": "minecraft:cherry_standing_sign", - "id": -542 - }, - { - "name": "minecraft:cherry_trapdoor", - "id": -543 - }, - { - "name": "minecraft:cherry_wall_sign", - "id": -544 - }, - { - "name": "minecraft:cherry_wood", - "id": -546 - }, - { - "name": "minecraft:chest", - "id": 54 - }, - { - "name": "minecraft:chest_boat", - "id": 653 - }, - { - "name": "minecraft:chest_minecart", - "id": 392 - }, - { - "name": "minecraft:chicken", - "id": 276 - }, - { - "name": "minecraft:chicken_spawn_egg", - "id": 438 - }, - { - "name": "minecraft:chiseled_bookshelf", - "id": -526 - }, - { - "name": "minecraft:chiseled_copper", - "id": -760 - }, - { - "name": "minecraft:chiseled_deepslate", - "id": -395 - }, - { - "name": "minecraft:chiseled_nether_bricks", - "id": -302 - }, - { - "name": "minecraft:chiseled_polished_blackstone", - "id": -279 - }, - { - "name": "minecraft:chiseled_tuff", - "id": -753 - }, - { - "name": "minecraft:chiseled_tuff_bricks", - "id": -759 - }, - { - "name": "minecraft:chorus_flower", - "id": 200 - }, - { - "name": "minecraft:chorus_fruit", - "id": 566 - }, - { - "name": "minecraft:chorus_plant", - "id": 240 - }, - { - "name": "minecraft:clay", - "id": 82 - }, - { - "name": "minecraft:clay_ball", - "id": 387 - }, - { - "name": "minecraft:client_request_placeholder_block", - "id": -465 - }, - { - "name": "minecraft:clock", - "id": 396 - }, - { - "name": "minecraft:coal", - "id": 305 - }, - { - "name": "minecraft:coal_block", - "id": 173 - }, - { - "name": "minecraft:coal_ore", - "id": 16 - }, - { - "name": "minecraft:coast_armor_trim_smithing_template", - "id": 688 - }, - { - "name": "minecraft:cobbled_deepslate", - "id": -379 - }, - { - "name": "minecraft:cobbled_deepslate_double_slab", - "id": -396 - }, - { - "name": "minecraft:cobbled_deepslate_slab", - "id": -380 - }, - { - "name": "minecraft:cobbled_deepslate_stairs", - "id": -381 - }, - { - "name": "minecraft:cobbled_deepslate_wall", - "id": -382 - }, - { - "name": "minecraft:cobblestone", - "id": 4 - }, - { - "name": "minecraft:cobblestone_wall", - "id": 139 - }, - { - "name": "minecraft:cocoa", - "id": 127 - }, - { - "name": "minecraft:cocoa_beans", - "id": 415 - }, - { - "name": "minecraft:cod", - "id": 265 - }, - { - "name": "minecraft:cod_bucket", - "id": 367 - }, - { - "name": "minecraft:cod_spawn_egg", - "id": 483 - }, - { - "name": "minecraft:colored_torch_bp", - "id": 204 - }, - { - "name": "minecraft:colored_torch_rg", - "id": 202 - }, - { - "name": "minecraft:command_block", - "id": 137 - }, - { - "name": "minecraft:command_block_minecart", - "id": 571 - }, - { - "name": "minecraft:comparator", - "id": 530 - }, - { - "name": "minecraft:compass", - "id": 394 - }, - { - "name": "minecraft:composter", - "id": -213 - }, - { - "name": "minecraft:compound", - "id": 602 - }, - { - "name": "minecraft:concrete", - "id": 711 - }, - { - "name": "minecraft:concrete_powder", - "id": 712 - }, - { - "name": "minecraft:conduit", - "id": -157 - }, - { - "name": "minecraft:cooked_beef", - "id": 275 - }, - { - "name": "minecraft:cooked_chicken", - "id": 277 - }, - { - "name": "minecraft:cooked_cod", - "id": 269 - }, - { - "name": "minecraft:cooked_mutton", - "id": 559 - }, - { - "name": "minecraft:cooked_porkchop", - "id": 264 - }, - { - "name": "minecraft:cooked_rabbit", - "id": 290 - }, - { - "name": "minecraft:cooked_salmon", - "id": 270 - }, - { - "name": "minecraft:cookie", - "id": 272 - }, - { - "name": "minecraft:copper_block", - "id": -340 - }, - { - "name": "minecraft:copper_bulb", - "id": -776 - }, - { - "name": "minecraft:copper_door", - "id": -784 - }, - { - "name": "minecraft:copper_grate", - "id": -768 - }, - { - "name": "minecraft:copper_ingot", - "id": 512 - }, - { - "name": "minecraft:copper_ore", - "id": -311 - }, - { - "name": "minecraft:copper_trapdoor", - "id": -792 - }, - { - "name": "minecraft:coral", - "id": 709 - }, - { - "name": "minecraft:coral_block", - "id": -132 - }, - { - "name": "minecraft:coral_fan", - "id": -133 - }, - { - "name": "minecraft:coral_fan_dead", - "id": -134 - }, - { - "name": "minecraft:coral_fan_hang", - "id": -135 - }, - { - "name": "minecraft:coral_fan_hang2", - "id": -136 - }, - { - "name": "minecraft:coral_fan_hang3", - "id": -137 - }, - { - "name": "minecraft:cow_spawn_egg", - "id": 439 - }, - { - "name": "minecraft:cracked_deepslate_bricks", - "id": -410 - }, - { - "name": "minecraft:cracked_deepslate_tiles", - "id": -409 - }, - { - "name": "minecraft:cracked_nether_bricks", - "id": -303 - }, - { - "name": "minecraft:cracked_polished_blackstone_bricks", - "id": -280 - }, - { - "name": "minecraft:crafter", - "id": -313 - }, - { - "name": "minecraft:crafting_table", - "id": 58 - }, - { - "name": "minecraft:creeper_banner_pattern", - "id": 590 - }, - { - "name": "minecraft:creeper_spawn_egg", - "id": 444 - }, - { - "name": "minecraft:crimson_button", - "id": -260 - }, - { - "name": "minecraft:crimson_door", - "id": 624 - }, - { - "name": "minecraft:crimson_double_slab", - "id": -266 - }, - { - "name": "minecraft:crimson_fence", - "id": -256 - }, - { - "name": "minecraft:crimson_fence_gate", - "id": -258 - }, - { - "name": "minecraft:crimson_fungus", - "id": -228 - }, - { - "name": "minecraft:crimson_hanging_sign", - "id": -506 - }, - { - "name": "minecraft:crimson_hyphae", - "id": -299 - }, - { - "name": "minecraft:crimson_nylium", - "id": -232 - }, - { - "name": "minecraft:crimson_planks", - "id": -242 - }, - { - "name": "minecraft:crimson_pressure_plate", - "id": -262 - }, - { - "name": "minecraft:crimson_roots", - "id": -223 - }, - { - "name": "minecraft:crimson_sign", - "id": 622 - }, - { - "name": "minecraft:crimson_slab", - "id": -264 - }, - { - "name": "minecraft:crimson_stairs", - "id": -254 - }, - { - "name": "minecraft:crimson_standing_sign", - "id": -250 - }, - { - "name": "minecraft:crimson_stem", - "id": -225 - }, - { - "name": "minecraft:crimson_trapdoor", - "id": -246 - }, - { - "name": "minecraft:crimson_wall_sign", - "id": -252 - }, - { - "name": "minecraft:crossbow", - "id": 583 - }, - { - "name": "minecraft:crying_obsidian", - "id": -289 - }, - { - "name": "minecraft:cut_copper", - "id": -347 - }, - { - "name": "minecraft:cut_copper_slab", - "id": -361 - }, - { - "name": "minecraft:cut_copper_stairs", - "id": -354 - }, - { - "name": "minecraft:cyan_candle", - "id": -422 - }, - { - "name": "minecraft:cyan_candle_cake", - "id": -439 - }, - { - "name": "minecraft:cyan_carpet", - "id": -605 - }, - { - "name": "minecraft:cyan_concrete", - "id": -636 - }, - { - "name": "minecraft:cyan_concrete_powder", - "id": -717 - }, - { - "name": "minecraft:cyan_dye", - "id": 404 - }, - { - "name": "minecraft:cyan_glazed_terracotta", - "id": 229 - }, - { - "name": "minecraft:cyan_shulker_box", - "id": -621 - }, - { - "name": "minecraft:cyan_stained_glass", - "id": -681 - }, - { - "name": "minecraft:cyan_stained_glass_pane", - "id": -651 - }, - { - "name": "minecraft:cyan_terracotta", - "id": -732 - }, - { - "name": "minecraft:cyan_wool", - "id": -561 - }, - { - "name": "minecraft:danger_pottery_sherd", - "id": 670 - }, - { - "name": "minecraft:dark_oak_boat", - "id": 383 - }, - { - "name": "minecraft:dark_oak_button", - "id": -142 - }, - { - "name": "minecraft:dark_oak_chest_boat", - "id": 651 - }, - { - "name": "minecraft:dark_oak_door", - "id": 565 - }, - { - "name": "minecraft:dark_oak_fence", - "id": -577 - }, - { - "name": "minecraft:dark_oak_fence_gate", - "id": 186 - }, - { - "name": "minecraft:dark_oak_hanging_sign", - "id": -505 - }, - { - "name": "minecraft:dark_oak_log", - "id": -572 - }, - { - "name": "minecraft:dark_oak_planks", - "id": -743 - }, - { - "name": "minecraft:dark_oak_pressure_plate", - "id": -152 - }, - { - "name": "minecraft:dark_oak_sign", - "id": 588 - }, - { - "name": "minecraft:dark_oak_stairs", - "id": 164 - }, - { - "name": "minecraft:dark_oak_trapdoor", - "id": -147 - }, - { - "name": "minecraft:dark_prismarine_stairs", - "id": -3 - }, - { - "name": "minecraft:darkoak_standing_sign", - "id": -192 - }, - { - "name": "minecraft:darkoak_wall_sign", - "id": -193 - }, - { - "name": "minecraft:daylight_detector", - "id": 151 - }, - { - "name": "minecraft:daylight_detector_inverted", - "id": 178 - }, - { - "name": "minecraft:dead_brain_coral", - "id": -586 - }, - { - "name": "minecraft:dead_bubble_coral", - "id": -587 - }, - { - "name": "minecraft:dead_fire_coral", - "id": -588 - }, - { - "name": "minecraft:dead_horn_coral", - "id": -589 - }, - { - "name": "minecraft:dead_tube_coral", - "id": -585 - }, - { - "name": "minecraft:deadbush", - "id": 32 - }, - { - "name": "minecraft:decorated_pot", - "id": -551 - }, - { - "name": "minecraft:deepslate", - "id": -378 - }, - { - "name": "minecraft:deepslate_brick_double_slab", - "id": -399 - }, - { - "name": "minecraft:deepslate_brick_slab", - "id": -392 - }, - { - "name": "minecraft:deepslate_brick_stairs", - "id": -393 - }, - { - "name": "minecraft:deepslate_brick_wall", - "id": -394 - }, - { - "name": "minecraft:deepslate_bricks", - "id": -391 - }, - { - "name": "minecraft:deepslate_coal_ore", - "id": -406 - }, - { - "name": "minecraft:deepslate_copper_ore", - "id": -408 - }, - { - "name": "minecraft:deepslate_diamond_ore", - "id": -405 - }, - { - "name": "minecraft:deepslate_emerald_ore", - "id": -407 - }, - { - "name": "minecraft:deepslate_gold_ore", - "id": -402 - }, - { - "name": "minecraft:deepslate_iron_ore", - "id": -401 - }, - { - "name": "minecraft:deepslate_lapis_ore", - "id": -400 - }, - { - "name": "minecraft:deepslate_redstone_ore", - "id": -403 - }, - { - "name": "minecraft:deepslate_tile_double_slab", - "id": -398 - }, - { - "name": "minecraft:deepslate_tile_slab", - "id": -388 - }, - { - "name": "minecraft:deepslate_tile_stairs", - "id": -389 - }, - { - "name": "minecraft:deepslate_tile_wall", - "id": -390 - }, - { - "name": "minecraft:deepslate_tiles", - "id": -387 - }, - { - "name": "minecraft:deny", - "id": 211 - }, - { - "name": "minecraft:detector_rail", - "id": 28 - }, - { - "name": "minecraft:diamond", - "id": 307 - }, - { - "name": "minecraft:diamond_axe", - "id": 322 - }, - { - "name": "minecraft:diamond_block", - "id": 57 - }, - { - "name": "minecraft:diamond_boots", - "id": 353 - }, - { - "name": "minecraft:diamond_chestplate", - "id": 351 - }, - { - "name": "minecraft:diamond_helmet", - "id": 350 - }, - { - "name": "minecraft:diamond_hoe", - "id": 335 - }, - { - "name": "minecraft:diamond_horse_armor", - "id": 541 - }, - { - "name": "minecraft:diamond_leggings", - "id": 352 - }, - { - "name": "minecraft:diamond_ore", - "id": 56 - }, - { - "name": "minecraft:diamond_pickaxe", - "id": 321 - }, - { - "name": "minecraft:diamond_shovel", - "id": 320 - }, - { - "name": "minecraft:diamond_sword", - "id": 319 - }, - { - "name": "minecraft:diorite", - "id": -592 - }, - { - "name": "minecraft:diorite_stairs", - "id": -170 - }, - { - "name": "minecraft:dirt", - "id": 3 - }, - { - "name": "minecraft:dirt_with_roots", - "id": -318 - }, - { - "name": "minecraft:disc_fragment_5", - "id": 645 - }, - { - "name": "minecraft:dispenser", - "id": 23 - }, - { - "name": "minecraft:dolphin_spawn_egg", - "id": 487 - }, - { - "name": "minecraft:donkey_spawn_egg", - "id": 468 - }, - { - "name": "minecraft:double_cut_copper_slab", - "id": -368 - }, - { - "name": "minecraft:double_plant", - "id": 175 - }, - { - "name": "minecraft:double_stone_block_slab", - "id": 43 - }, - { - "name": "minecraft:double_stone_block_slab2", - "id": 181 - }, - { - "name": "minecraft:double_stone_block_slab3", - "id": -167 - }, - { - "name": "minecraft:double_stone_block_slab4", - "id": -168 - }, - { - "name": "minecraft:double_wooden_slab", - "id": 157 - }, - { - "name": "minecraft:dragon_breath", - "id": 568 - }, - { - "name": "minecraft:dragon_egg", - "id": 122 - }, - { - "name": "minecraft:dried_kelp", - "id": 271 - }, - { - "name": "minecraft:dried_kelp_block", - "id": -139 - }, - { - "name": "minecraft:dripstone_block", - "id": -317 - }, - { - "name": "minecraft:dropper", - "id": 125 - }, - { - "name": "minecraft:drowned_spawn_egg", - "id": 486 - }, - { - "name": "minecraft:dune_armor_trim_smithing_template", - "id": 687 - }, - { - "name": "minecraft:dye", - "id": 717 - }, - { - "name": "minecraft:echo_shard", - "id": 655 - }, - { - "name": "minecraft:egg", - "id": 393 - }, - { - "name": "minecraft:elder_guardian_spawn_egg", - "id": 474 - }, - { - "name": "minecraft:element_0", - "id": 36 - }, - { - "name": "minecraft:element_1", - "id": -12 - }, - { - "name": "minecraft:element_10", - "id": -21 - }, - { - "name": "minecraft:element_100", - "id": -111 - }, - { - "name": "minecraft:element_101", - "id": -112 - }, - { - "name": "minecraft:element_102", - "id": -113 - }, - { - "name": "minecraft:element_103", - "id": -114 - }, - { - "name": "minecraft:element_104", - "id": -115 - }, - { - "name": "minecraft:element_105", - "id": -116 - }, - { - "name": "minecraft:element_106", - "id": -117 - }, - { - "name": "minecraft:element_107", - "id": -118 - }, - { - "name": "minecraft:element_108", - "id": -119 - }, - { - "name": "minecraft:element_109", - "id": -120 - }, - { - "name": "minecraft:element_11", - "id": -22 - }, - { - "name": "minecraft:element_110", - "id": -121 - }, - { - "name": "minecraft:element_111", - "id": -122 - }, - { - "name": "minecraft:element_112", - "id": -123 - }, - { - "name": "minecraft:element_113", - "id": -124 - }, - { - "name": "minecraft:element_114", - "id": -125 - }, - { - "name": "minecraft:element_115", - "id": -126 - }, - { - "name": "minecraft:element_116", - "id": -127 - }, - { - "name": "minecraft:element_117", - "id": -128 - }, - { - "name": "minecraft:element_118", - "id": -129 - }, - { - "name": "minecraft:element_12", - "id": -23 - }, - { - "name": "minecraft:element_13", - "id": -24 - }, - { - "name": "minecraft:element_14", - "id": -25 - }, - { - "name": "minecraft:element_15", - "id": -26 - }, - { - "name": "minecraft:element_16", - "id": -27 - }, - { - "name": "minecraft:element_17", - "id": -28 - }, - { - "name": "minecraft:element_18", - "id": -29 - }, - { - "name": "minecraft:element_19", - "id": -30 - }, - { - "name": "minecraft:element_2", - "id": -13 - }, - { - "name": "minecraft:element_20", - "id": -31 - }, - { - "name": "minecraft:element_21", - "id": -32 - }, - { - "name": "minecraft:element_22", - "id": -33 - }, - { - "name": "minecraft:element_23", - "id": -34 - }, - { - "name": "minecraft:element_24", - "id": -35 - }, - { - "name": "minecraft:element_25", - "id": -36 - }, - { - "name": "minecraft:element_26", - "id": -37 - }, - { - "name": "minecraft:element_27", - "id": -38 - }, - { - "name": "minecraft:element_28", - "id": -39 - }, - { - "name": "minecraft:element_29", - "id": -40 - }, - { - "name": "minecraft:element_3", - "id": -14 - }, - { - "name": "minecraft:element_30", - "id": -41 - }, - { - "name": "minecraft:element_31", - "id": -42 - }, - { - "name": "minecraft:element_32", - "id": -43 - }, - { - "name": "minecraft:element_33", - "id": -44 - }, - { - "name": "minecraft:element_34", - "id": -45 - }, - { - "name": "minecraft:element_35", - "id": -46 - }, - { - "name": "minecraft:element_36", - "id": -47 - }, - { - "name": "minecraft:element_37", - "id": -48 - }, - { - "name": "minecraft:element_38", - "id": -49 - }, - { - "name": "minecraft:element_39", - "id": -50 - }, - { - "name": "minecraft:element_4", - "id": -15 - }, - { - "name": "minecraft:element_40", - "id": -51 - }, - { - "name": "minecraft:element_41", - "id": -52 - }, - { - "name": "minecraft:element_42", - "id": -53 - }, - { - "name": "minecraft:element_43", - "id": -54 - }, - { - "name": "minecraft:element_44", - "id": -55 - }, - { - "name": "minecraft:element_45", - "id": -56 - }, - { - "name": "minecraft:element_46", - "id": -57 - }, - { - "name": "minecraft:element_47", - "id": -58 - }, - { - "name": "minecraft:element_48", - "id": -59 - }, - { - "name": "minecraft:element_49", - "id": -60 - }, - { - "name": "minecraft:element_5", - "id": -16 - }, - { - "name": "minecraft:element_50", - "id": -61 - }, - { - "name": "minecraft:element_51", - "id": -62 - }, - { - "name": "minecraft:element_52", - "id": -63 - }, - { - "name": "minecraft:element_53", - "id": -64 - }, - { - "name": "minecraft:element_54", - "id": -65 - }, - { - "name": "minecraft:element_55", - "id": -66 - }, - { - "name": "minecraft:element_56", - "id": -67 - }, - { - "name": "minecraft:element_57", - "id": -68 - }, - { - "name": "minecraft:element_58", - "id": -69 - }, - { - "name": "minecraft:element_59", - "id": -70 - }, - { - "name": "minecraft:element_6", - "id": -17 - }, - { - "name": "minecraft:element_60", - "id": -71 - }, - { - "name": "minecraft:element_61", - "id": -72 - }, - { - "name": "minecraft:element_62", - "id": -73 - }, - { - "name": "minecraft:element_63", - "id": -74 - }, - { - "name": "minecraft:element_64", - "id": -75 - }, - { - "name": "minecraft:element_65", - "id": -76 - }, - { - "name": "minecraft:element_66", - "id": -77 - }, - { - "name": "minecraft:element_67", - "id": -78 - }, - { - "name": "minecraft:element_68", - "id": -79 - }, - { - "name": "minecraft:element_69", - "id": -80 - }, - { - "name": "minecraft:element_7", - "id": -18 - }, - { - "name": "minecraft:element_70", - "id": -81 - }, - { - "name": "minecraft:element_71", - "id": -82 - }, - { - "name": "minecraft:element_72", - "id": -83 - }, - { - "name": "minecraft:element_73", - "id": -84 - }, - { - "name": "minecraft:element_74", - "id": -85 - }, - { - "name": "minecraft:element_75", - "id": -86 - }, - { - "name": "minecraft:element_76", - "id": -87 - }, - { - "name": "minecraft:element_77", - "id": -88 - }, - { - "name": "minecraft:element_78", - "id": -89 - }, - { - "name": "minecraft:element_79", - "id": -90 - }, - { - "name": "minecraft:element_8", - "id": -19 - }, - { - "name": "minecraft:element_80", - "id": -91 - }, - { - "name": "minecraft:element_81", - "id": -92 - }, - { - "name": "minecraft:element_82", - "id": -93 - }, - { - "name": "minecraft:element_83", - "id": -94 - }, - { - "name": "minecraft:element_84", - "id": -95 - }, - { - "name": "minecraft:element_85", - "id": -96 - }, - { - "name": "minecraft:element_86", - "id": -97 - }, - { - "name": "minecraft:element_87", - "id": -98 - }, - { - "name": "minecraft:element_88", - "id": -99 - }, - { - "name": "minecraft:element_89", - "id": -100 - }, - { - "name": "minecraft:element_9", - "id": -20 - }, - { - "name": "minecraft:element_90", - "id": -101 - }, - { - "name": "minecraft:element_91", - "id": -102 - }, - { - "name": "minecraft:element_92", - "id": -103 - }, - { - "name": "minecraft:element_93", - "id": -104 - }, - { - "name": "minecraft:element_94", - "id": -105 - }, - { - "name": "minecraft:element_95", - "id": -106 - }, - { - "name": "minecraft:element_96", - "id": -107 - }, - { - "name": "minecraft:element_97", - "id": -108 - }, - { - "name": "minecraft:element_98", - "id": -109 - }, - { - "name": "minecraft:element_99", - "id": -110 - }, - { - "name": "minecraft:elytra", - "id": 572 - }, - { - "name": "minecraft:emerald", - "id": 520 - }, - { - "name": "minecraft:emerald_block", - "id": 133 - }, - { - "name": "minecraft:emerald_ore", - "id": 129 - }, - { - "name": "minecraft:empty_map", - "id": 523 - }, - { - "name": "minecraft:enchanted_book", - "id": 529 - }, - { - "name": "minecraft:enchanted_golden_apple", - "id": 260 - }, - { - "name": "minecraft:enchanting_table", - "id": 116 - }, - { - "name": "minecraft:end_brick_stairs", - "id": -178 - }, - { - "name": "minecraft:end_bricks", - "id": 206 - }, - { - "name": "minecraft:end_crystal", - "id": 720 - }, - { - "name": "minecraft:end_gateway", - "id": 209 - }, - { - "name": "minecraft:end_portal", - "id": 119 - }, - { - "name": "minecraft:end_portal_frame", - "id": 120 - }, - { - "name": "minecraft:end_rod", - "id": 208 - }, - { - "name": "minecraft:end_stone", - "id": 121 - }, - { - "name": "minecraft:ender_chest", - "id": 130 - }, - { - "name": "minecraft:ender_dragon_spawn_egg", - "id": 509 - }, - { - "name": "minecraft:ender_eye", - "id": 436 - }, - { - "name": "minecraft:ender_pearl", - "id": 425 - }, - { - "name": "minecraft:enderman_spawn_egg", - "id": 445 - }, - { - "name": "minecraft:endermite_spawn_egg", - "id": 463 - }, - { - "name": "minecraft:evoker_spawn_egg", - "id": 478 - }, - { - "name": "minecraft:experience_bottle", - "id": 516 - }, - { - "name": "minecraft:explorer_pottery_sherd", - "id": 671 - }, - { - "name": "minecraft:exposed_chiseled_copper", - "id": -761 - }, - { - "name": "minecraft:exposed_copper", - "id": -341 - }, - { - "name": "minecraft:exposed_copper_bulb", - "id": -777 - }, - { - "name": "minecraft:exposed_copper_door", - "id": -785 - }, - { - "name": "minecraft:exposed_copper_grate", - "id": -769 - }, - { - "name": "minecraft:exposed_copper_trapdoor", - "id": -793 - }, - { - "name": "minecraft:exposed_cut_copper", - "id": -348 - }, - { - "name": "minecraft:exposed_cut_copper_slab", - "id": -362 - }, - { - "name": "minecraft:exposed_cut_copper_stairs", - "id": -355 - }, - { - "name": "minecraft:exposed_double_cut_copper_slab", - "id": -369 - }, - { - "name": "minecraft:eye_armor_trim_smithing_template", - "id": 691 - }, - { - "name": "minecraft:farmland", - "id": 60 - }, - { - "name": "minecraft:feather", - "id": 330 - }, - { - "name": "minecraft:fence", - "id": 707 - }, - { - "name": "minecraft:fence_gate", - "id": 107 - }, - { - "name": "minecraft:fermented_spider_eye", - "id": 431 - }, - { - "name": "minecraft:field_masoned_banner_pattern", - "id": 593 - }, - { - "name": "minecraft:filled_map", - "id": 423 - }, - { - "name": "minecraft:fire", - "id": 51 - }, - { - "name": "minecraft:fire_charge", - "id": 517 - }, - { - "name": "minecraft:fire_coral", - "id": -583 - }, - { - "name": "minecraft:firework_rocket", - "id": 527 - }, - { - "name": "minecraft:firework_star", - "id": 528 - }, - { - "name": "minecraft:fishing_rod", - "id": 395 - }, - { - "name": "minecraft:fletching_table", - "id": -201 - }, - { - "name": "minecraft:flint", - "id": 359 - }, - { - "name": "minecraft:flint_and_steel", - "id": 302 - }, - { - "name": "minecraft:flower_banner_pattern", - "id": 589 - }, - { - "name": "minecraft:flower_pot", - "id": 522 - }, - { - "name": "minecraft:flowering_azalea", - "id": -338 - }, - { - "name": "minecraft:flowing_lava", - "id": 10 - }, - { - "name": "minecraft:flowing_water", - "id": 8 - }, - { - "name": "minecraft:fox_spawn_egg", - "id": 493 - }, - { - "name": "minecraft:frame", - "id": 521 - }, - { - "name": "minecraft:friend_pottery_sherd", - "id": 672 - }, - { - "name": "minecraft:frog_spawn", - "id": -468 - }, - { - "name": "minecraft:frog_spawn_egg", - "id": 636 - }, - { - "name": "minecraft:frosted_ice", - "id": 207 - }, - { - "name": "minecraft:furnace", - "id": 61 - }, - { - "name": "minecraft:ghast_spawn_egg", - "id": 457 - }, - { - "name": "minecraft:ghast_tear", - "id": 427 - }, - { - "name": "minecraft:gilded_blackstone", - "id": -281 - }, - { - "name": "minecraft:glass", - "id": 20 - }, - { - "name": "minecraft:glass_bottle", - "id": 430 - }, - { - "name": "minecraft:glass_pane", - "id": 102 - }, - { - "name": "minecraft:glistering_melon_slice", - "id": 437 - }, - { - "name": "minecraft:globe_banner_pattern", - "id": 596 - }, - { - "name": "minecraft:glow_berries", - "id": 721 - }, - { - "name": "minecraft:glow_frame", - "id": 631 - }, - { - "name": "minecraft:glow_ink_sac", - "id": 511 - }, - { - "name": "minecraft:glow_lichen", - "id": -411 - }, - { - "name": "minecraft:glow_squid_spawn_egg", - "id": 506 - }, - { - "name": "minecraft:glow_stick", - "id": 609 - }, - { - "name": "minecraft:glowingobsidian", - "id": 246 - }, - { - "name": "minecraft:glowstone", - "id": 89 - }, - { - "name": "minecraft:glowstone_dust", - "id": 397 - }, - { - "name": "minecraft:goat_horn", - "id": 635 - }, - { - "name": "minecraft:goat_spawn_egg", - "id": 505 - }, - { - "name": "minecraft:gold_block", - "id": 41 - }, - { - "name": "minecraft:gold_ingot", - "id": 309 - }, - { - "name": "minecraft:gold_nugget", - "id": 428 - }, - { - "name": "minecraft:gold_ore", - "id": 14 - }, - { - "name": "minecraft:golden_apple", - "id": 259 - }, - { - "name": "minecraft:golden_axe", - "id": 328 - }, - { - "name": "minecraft:golden_boots", - "id": 357 - }, - { - "name": "minecraft:golden_carrot", - "id": 284 - }, - { - "name": "minecraft:golden_chestplate", - "id": 355 - }, - { - "name": "minecraft:golden_helmet", - "id": 354 - }, - { - "name": "minecraft:golden_hoe", - "id": 336 - }, - { - "name": "minecraft:golden_horse_armor", - "id": 540 - }, - { - "name": "minecraft:golden_leggings", - "id": 356 - }, - { - "name": "minecraft:golden_pickaxe", - "id": 327 - }, - { - "name": "minecraft:golden_rail", - "id": 27 - }, - { - "name": "minecraft:golden_shovel", - "id": 326 - }, - { - "name": "minecraft:golden_sword", - "id": 325 - }, - { - "name": "minecraft:granite", - "id": -590 - }, - { - "name": "minecraft:granite_stairs", - "id": -169 - }, - { - "name": "minecraft:grass", - "id": 2 - }, - { - "name": "minecraft:grass_path", - "id": 198 - }, - { - "name": "minecraft:gravel", - "id": 13 - }, - { - "name": "minecraft:gray_candle", - "id": -420 - }, - { - "name": "minecraft:gray_candle_cake", - "id": -437 - }, - { - "name": "minecraft:gray_carpet", - "id": -603 - }, - { - "name": "minecraft:gray_concrete", - "id": -634 - }, - { - "name": "minecraft:gray_concrete_powder", - "id": -715 - }, - { - "name": "minecraft:gray_dye", - "id": 406 - }, - { - "name": "minecraft:gray_glazed_terracotta", - "id": 227 - }, - { - "name": "minecraft:gray_shulker_box", - "id": -619 - }, - { - "name": "minecraft:gray_stained_glass", - "id": -679 - }, - { - "name": "minecraft:gray_stained_glass_pane", - "id": -649 - }, - { - "name": "minecraft:gray_terracotta", - "id": -730 - }, - { - "name": "minecraft:gray_wool", - "id": -553 - }, - { - "name": "minecraft:green_candle", - "id": -426 - }, - { - "name": "minecraft:green_candle_cake", - "id": -443 - }, - { - "name": "minecraft:green_carpet", - "id": -609 - }, - { - "name": "minecraft:green_concrete", - "id": -640 - }, - { - "name": "minecraft:green_concrete_powder", - "id": -721 - }, - { - "name": "minecraft:green_dye", - "id": 400 - }, - { - "name": "minecraft:green_glazed_terracotta", - "id": 233 - }, - { - "name": "minecraft:green_shulker_box", - "id": -625 - }, - { - "name": "minecraft:green_stained_glass", - "id": -685 - }, - { - "name": "minecraft:green_stained_glass_pane", - "id": -655 - }, - { - "name": "minecraft:green_terracotta", - "id": -736 - }, - { - "name": "minecraft:green_wool", - "id": -560 - }, - { - "name": "minecraft:grindstone", - "id": -195 - }, - { - "name": "minecraft:guardian_spawn_egg", - "id": 464 - }, - { - "name": "minecraft:gunpowder", - "id": 331 - }, - { - "name": "minecraft:hanging_roots", - "id": -319 - }, - { - "name": "minecraft:hard_glass", - "id": 253 - }, - { - "name": "minecraft:hard_glass_pane", - "id": 190 - }, - { - "name": "minecraft:hard_stained_glass", - "id": 254 - }, - { - "name": "minecraft:hard_stained_glass_pane", - "id": 191 - }, - { - "name": "minecraft:hardened_clay", - "id": 172 - }, - { - "name": "minecraft:hay_block", - "id": 170 - }, - { - "name": "minecraft:heart_of_the_sea", - "id": 579 - }, - { - "name": "minecraft:heart_pottery_sherd", - "id": 673 - }, - { - "name": "minecraft:heartbreak_pottery_sherd", - "id": 674 - }, - { - "name": "minecraft:heavy_weighted_pressure_plate", - "id": 148 - }, - { - "name": "minecraft:hoglin_spawn_egg", - "id": 499 - }, - { - "name": "minecraft:honey_block", - "id": -220 - }, - { - "name": "minecraft:honey_bottle", - "id": 600 - }, - { - "name": "minecraft:honeycomb", - "id": 599 - }, - { - "name": "minecraft:honeycomb_block", - "id": -221 - }, - { - "name": "minecraft:hopper", - "id": 535 - }, - { - "name": "minecraft:hopper_minecart", - "id": 534 - }, - { - "name": "minecraft:horn_coral", - "id": -584 - }, - { - "name": "minecraft:horse_spawn_egg", - "id": 461 - }, - { - "name": "minecraft:host_armor_trim_smithing_template", - "id": 701 - }, - { - "name": "minecraft:howl_pottery_sherd", - "id": 675 - }, - { - "name": "minecraft:husk_spawn_egg", - "id": 466 - }, - { - "name": "minecraft:ice", - "id": 79 - }, - { - "name": "minecraft:ice_bomb", - "id": 603 - }, - { - "name": "minecraft:infested_deepslate", - "id": -454 - }, - { - "name": "minecraft:info_update", - "id": 248 - }, - { - "name": "minecraft:info_update2", - "id": 249 - }, - { - "name": "minecraft:ink_sac", - "id": 416 - }, - { - "name": "minecraft:invisible_bedrock", - "id": 95 - }, - { - "name": "minecraft:iron_axe", - "id": 301 - }, - { - "name": "minecraft:iron_bars", - "id": 101 - }, - { - "name": "minecraft:iron_block", - "id": 42 - }, - { - "name": "minecraft:iron_boots", - "id": 349 - }, - { - "name": "minecraft:iron_chestplate", - "id": 347 - }, - { - "name": "minecraft:iron_door", - "id": 375 - }, - { - "name": "minecraft:iron_golem_spawn_egg", - "id": 507 - }, - { - "name": "minecraft:iron_helmet", - "id": 346 - }, - { - "name": "minecraft:iron_hoe", - "id": 334 - }, - { - "name": "minecraft:iron_horse_armor", - "id": 539 - }, - { - "name": "minecraft:iron_ingot", - "id": 308 - }, - { - "name": "minecraft:iron_leggings", - "id": 348 - }, - { - "name": "minecraft:iron_nugget", - "id": 577 - }, - { - "name": "minecraft:iron_ore", - "id": 15 - }, - { - "name": "minecraft:iron_pickaxe", - "id": 300 - }, - { - "name": "minecraft:iron_shovel", - "id": 299 - }, - { - "name": "minecraft:iron_sword", - "id": 310 - }, - { - "name": "minecraft:iron_trapdoor", - "id": 167 - }, - { - "name": "minecraft:item.acacia_door", - "id": 196 - }, - { - "name": "minecraft:item.bed", - "id": 26 - }, - { - "name": "minecraft:item.beetroot", - "id": 244 - }, - { - "name": "minecraft:item.birch_door", - "id": 194 - }, - { - "name": "minecraft:item.brewing_stand", - "id": 117 - }, - { - "name": "minecraft:item.cake", - "id": 92 - }, - { - "name": "minecraft:item.camera", - "id": 242 - }, - { - "name": "minecraft:item.campfire", - "id": -209 - }, - { - "name": "minecraft:item.cauldron", - "id": 118 - }, - { - "name": "minecraft:item.chain", - "id": -286 - }, - { - "name": "minecraft:item.crimson_door", - "id": -244 - }, - { - "name": "minecraft:item.dark_oak_door", - "id": 197 - }, - { - "name": "minecraft:item.flower_pot", - "id": 140 - }, - { - "name": "minecraft:item.frame", - "id": 199 - }, - { - "name": "minecraft:item.glow_frame", - "id": -339 - }, - { - "name": "minecraft:item.hopper", - "id": 154 - }, - { - "name": "minecraft:item.iron_door", - "id": 71 - }, - { - "name": "minecraft:item.jungle_door", - "id": 195 - }, - { - "name": "minecraft:item.kelp", - "id": -138 - }, - { - "name": "minecraft:item.mangrove_door", - "id": -493 - }, - { - "name": "minecraft:item.nether_sprouts", - "id": -238 - }, - { - "name": "minecraft:item.nether_wart", - "id": 115 - }, - { - "name": "minecraft:item.reeds", - "id": 83 - }, - { - "name": "minecraft:item.skull", - "id": 144 - }, - { - "name": "minecraft:item.soul_campfire", - "id": -290 - }, - { - "name": "minecraft:item.spruce_door", - "id": 193 - }, - { - "name": "minecraft:item.warped_door", - "id": -245 - }, - { - "name": "minecraft:item.wheat", - "id": 59 - }, - { - "name": "minecraft:item.wooden_door", - "id": 64 - }, - { - "name": "minecraft:jigsaw", - "id": -211 - }, - { - "name": "minecraft:jukebox", - "id": 84 - }, - { - "name": "minecraft:jungle_boat", - "id": 380 - }, - { - "name": "minecraft:jungle_button", - "id": -143 - }, - { - "name": "minecraft:jungle_chest_boat", - "id": 648 - }, - { - "name": "minecraft:jungle_door", - "id": 563 - }, - { - "name": "minecraft:jungle_fence", - "id": -578 - }, - { - "name": "minecraft:jungle_fence_gate", - "id": 185 - }, - { - "name": "minecraft:jungle_hanging_sign", - "id": -503 - }, - { - "name": "minecraft:jungle_log", - "id": -571 - }, - { - "name": "minecraft:jungle_planks", - "id": -741 - }, - { - "name": "minecraft:jungle_pressure_plate", - "id": -153 - }, - { - "name": "minecraft:jungle_sign", - "id": 586 - }, - { - "name": "minecraft:jungle_stairs", - "id": 136 - }, - { - "name": "minecraft:jungle_standing_sign", - "id": -188 - }, - { - "name": "minecraft:jungle_trapdoor", - "id": -148 - }, - { - "name": "minecraft:jungle_wall_sign", - "id": -189 - }, - { - "name": "minecraft:kelp", - "id": 385 - }, - { - "name": "minecraft:ladder", - "id": 65 - }, - { - "name": "minecraft:lantern", - "id": -208 - }, - { - "name": "minecraft:lapis_block", - "id": 22 - }, - { - "name": "minecraft:lapis_lazuli", - "id": 417 - }, - { - "name": "minecraft:lapis_ore", - "id": 21 - }, - { - "name": "minecraft:large_amethyst_bud", - "id": -330 - }, - { - "name": "minecraft:lava", - "id": 11 - }, - { - "name": "minecraft:lava_bucket", - "id": 366 - }, - { - "name": "minecraft:lead", - "id": 555 - }, - { - "name": "minecraft:leather", - "id": 384 - }, - { - "name": "minecraft:leather_boots", - "id": 341 - }, - { - "name": "minecraft:leather_chestplate", - "id": 339 - }, - { - "name": "minecraft:leather_helmet", - "id": 338 - }, - { - "name": "minecraft:leather_horse_armor", - "id": 538 - }, - { - "name": "minecraft:leather_leggings", - "id": 340 - }, - { - "name": "minecraft:leaves", - "id": 18 - }, - { - "name": "minecraft:leaves2", - "id": 161 - }, - { - "name": "minecraft:lectern", - "id": -194 - }, - { - "name": "minecraft:lever", - "id": 69 - }, - { - "name": "minecraft:light_block", - "id": -215 - }, - { - "name": "minecraft:light_blue_candle", - "id": -416 - }, - { - "name": "minecraft:light_blue_candle_cake", - "id": -433 - }, - { - "name": "minecraft:light_blue_carpet", - "id": -599 - }, - { - "name": "minecraft:light_blue_concrete", - "id": -630 - }, - { - "name": "minecraft:light_blue_concrete_powder", - "id": -711 - }, - { - "name": "minecraft:light_blue_dye", - "id": 410 - }, - { - "name": "minecraft:light_blue_glazed_terracotta", - "id": 223 - }, - { - "name": "minecraft:light_blue_shulker_box", - "id": -615 - }, - { - "name": "minecraft:light_blue_stained_glass", - "id": -675 - }, - { - "name": "minecraft:light_blue_stained_glass_pane", - "id": -645 - }, - { - "name": "minecraft:light_blue_terracotta", - "id": -726 - }, - { - "name": "minecraft:light_blue_wool", - "id": -562 - }, - { - "name": "minecraft:light_gray_candle", - "id": -421 - }, - { - "name": "minecraft:light_gray_candle_cake", - "id": -438 - }, - { - "name": "minecraft:light_gray_carpet", - "id": -604 - }, - { - "name": "minecraft:light_gray_concrete", - "id": -635 - }, - { - "name": "minecraft:light_gray_concrete_powder", - "id": -716 - }, - { - "name": "minecraft:light_gray_dye", - "id": 405 - }, - { - "name": "minecraft:light_gray_shulker_box", - "id": -620 - }, - { - "name": "minecraft:light_gray_stained_glass", - "id": -680 - }, - { - "name": "minecraft:light_gray_stained_glass_pane", - "id": -650 - }, - { - "name": "minecraft:light_gray_terracotta", - "id": -731 - }, - { - "name": "minecraft:light_gray_wool", - "id": -552 - }, - { - "name": "minecraft:light_weighted_pressure_plate", - "id": 147 - }, - { - "name": "minecraft:lightning_rod", - "id": -312 - }, - { - "name": "minecraft:lime_candle", - "id": -418 - }, - { - "name": "minecraft:lime_candle_cake", - "id": -435 - }, - { - "name": "minecraft:lime_carpet", - "id": -601 - }, - { - "name": "minecraft:lime_concrete", - "id": -632 - }, - { - "name": "minecraft:lime_concrete_powder", - "id": -713 - }, - { - "name": "minecraft:lime_dye", - "id": 408 - }, - { - "name": "minecraft:lime_glazed_terracotta", - "id": 225 - }, - { - "name": "minecraft:lime_shulker_box", - "id": -617 - }, - { - "name": "minecraft:lime_stained_glass", - "id": -677 - }, - { - "name": "minecraft:lime_stained_glass_pane", - "id": -647 - }, - { - "name": "minecraft:lime_terracotta", - "id": -728 - }, - { - "name": "minecraft:lime_wool", - "id": -559 - }, - { - "name": "minecraft:lingering_potion", - "id": 570 - }, - { - "name": "minecraft:lit_blast_furnace", - "id": -214 - }, - { - "name": "minecraft:lit_deepslate_redstone_ore", - "id": -404 - }, - { - "name": "minecraft:lit_furnace", - "id": 62 - }, - { - "name": "minecraft:lit_pumpkin", - "id": 91 - }, - { - "name": "minecraft:lit_redstone_lamp", - "id": 124 - }, - { - "name": "minecraft:lit_redstone_ore", - "id": 74 - }, - { - "name": "minecraft:lit_smoker", - "id": -199 - }, - { - "name": "minecraft:llama_spawn_egg", - "id": 476 - }, - { - "name": "minecraft:lodestone", - "id": -222 - }, - { - "name": "minecraft:lodestone_compass", - "id": 610 - }, - { - "name": "minecraft:log", - "id": 706 - }, - { - "name": "minecraft:log2", - "id": 710 - }, - { - "name": "minecraft:loom", - "id": -204 - }, - { - "name": "minecraft:magenta_candle", - "id": -415 - }, - { - "name": "minecraft:magenta_candle_cake", - "id": -432 - }, - { - "name": "minecraft:magenta_carpet", - "id": -598 - }, - { - "name": "minecraft:magenta_concrete", - "id": -629 - }, - { - "name": "minecraft:magenta_concrete_powder", - "id": -710 - }, - { - "name": "minecraft:magenta_dye", - "id": 411 - }, - { - "name": "minecraft:magenta_glazed_terracotta", - "id": 222 - }, - { - "name": "minecraft:magenta_shulker_box", - "id": -614 - }, - { - "name": "minecraft:magenta_stained_glass", - "id": -674 - }, - { - "name": "minecraft:magenta_stained_glass_pane", - "id": -644 - }, - { - "name": "minecraft:magenta_terracotta", - "id": -725 - }, - { - "name": "minecraft:magenta_wool", - "id": -565 - }, - { - "name": "minecraft:magma", - "id": 213 - }, - { - "name": "minecraft:magma_cream", - "id": 433 - }, - { - "name": "minecraft:magma_cube_spawn_egg", - "id": 458 - }, - { - "name": "minecraft:mangrove_boat", - "id": 643 - }, - { - "name": "minecraft:mangrove_button", - "id": -487 - }, - { - "name": "minecraft:mangrove_chest_boat", - "id": 652 - }, - { - "name": "minecraft:mangrove_door", - "id": 641 - }, - { - "name": "minecraft:mangrove_double_slab", - "id": -499 - }, - { - "name": "minecraft:mangrove_fence", - "id": -491 - }, - { - "name": "minecraft:mangrove_fence_gate", - "id": -492 - }, - { - "name": "minecraft:mangrove_hanging_sign", - "id": -508 - }, - { - "name": "minecraft:mangrove_leaves", - "id": -472 - }, - { - "name": "minecraft:mangrove_log", - "id": -484 - }, - { - "name": "minecraft:mangrove_planks", - "id": -486 - }, - { - "name": "minecraft:mangrove_pressure_plate", - "id": -490 - }, - { - "name": "minecraft:mangrove_propagule", - "id": -474 - }, - { - "name": "minecraft:mangrove_roots", - "id": -482 - }, - { - "name": "minecraft:mangrove_sign", - "id": 642 - }, - { - "name": "minecraft:mangrove_slab", - "id": -489 - }, - { - "name": "minecraft:mangrove_stairs", - "id": -488 - }, - { - "name": "minecraft:mangrove_standing_sign", - "id": -494 - }, - { - "name": "minecraft:mangrove_trapdoor", - "id": -496 - }, - { - "name": "minecraft:mangrove_wall_sign", - "id": -495 - }, - { - "name": "minecraft:mangrove_wood", - "id": -497 - }, - { - "name": "minecraft:medicine", - "id": 607 - }, - { - "name": "minecraft:medium_amethyst_bud", - "id": -331 - }, - { - "name": "minecraft:melon_block", - "id": 103 - }, - { - "name": "minecraft:melon_seeds", - "id": 294 - }, - { - "name": "minecraft:melon_slice", - "id": 273 - }, - { - "name": "minecraft:melon_stem", - "id": 105 - }, - { - "name": "minecraft:milk_bucket", - "id": 364 - }, - { - "name": "minecraft:minecart", - "id": 373 - }, - { - "name": "minecraft:miner_pottery_sherd", - "id": 676 - }, - { - "name": "minecraft:mob_spawner", - "id": 52 - }, - { - "name": "minecraft:mojang_banner_pattern", - "id": 592 - }, - { - "name": "minecraft:monster_egg", - "id": 97 - }, - { - "name": "minecraft:mooshroom_spawn_egg", - "id": 443 - }, - { - "name": "minecraft:moss_block", - "id": -320 - }, - { - "name": "minecraft:moss_carpet", - "id": -335 - }, - { - "name": "minecraft:mossy_cobblestone", - "id": 48 - }, - { - "name": "minecraft:mossy_cobblestone_stairs", - "id": -179 - }, - { - "name": "minecraft:mossy_stone_brick_stairs", - "id": -175 - }, - { - "name": "minecraft:mourner_pottery_sherd", - "id": 677 - }, - { - "name": "minecraft:moving_block", - "id": 250 - }, - { - "name": "minecraft:mud", - "id": -473 - }, - { - "name": "minecraft:mud_brick_double_slab", - "id": -479 - }, - { - "name": "minecraft:mud_brick_slab", - "id": -478 - }, - { - "name": "minecraft:mud_brick_stairs", - "id": -480 - }, - { - "name": "minecraft:mud_brick_wall", - "id": -481 - }, - { - "name": "minecraft:mud_bricks", - "id": -475 - }, - { - "name": "minecraft:muddy_mangrove_roots", - "id": -483 - }, - { - "name": "minecraft:mule_spawn_egg", - "id": 469 - }, - { - "name": "minecraft:mushroom_stew", - "id": 261 - }, - { - "name": "minecraft:music_disc_11", - "id": 552 - }, - { - "name": "minecraft:music_disc_13", - "id": 542 - }, - { - "name": "minecraft:music_disc_5", - "id": 644 - }, - { - "name": "minecraft:music_disc_blocks", - "id": 544 - }, - { - "name": "minecraft:music_disc_cat", - "id": 543 - }, - { - "name": "minecraft:music_disc_chirp", - "id": 545 - }, - { - "name": "minecraft:music_disc_far", - "id": 546 - }, - { - "name": "minecraft:music_disc_mall", - "id": 547 - }, - { - "name": "minecraft:music_disc_mellohi", - "id": 548 - }, - { - "name": "minecraft:music_disc_otherside", - "id": 634 - }, - { - "name": "minecraft:music_disc_pigstep", - "id": 628 - }, - { - "name": "minecraft:music_disc_relic", - "id": 702 - }, - { - "name": "minecraft:music_disc_stal", - "id": 549 - }, - { - "name": "minecraft:music_disc_strad", - "id": 550 - }, - { - "name": "minecraft:music_disc_wait", - "id": 553 - }, - { - "name": "minecraft:music_disc_ward", - "id": 551 - }, - { - "name": "minecraft:mutton", - "id": 558 - }, - { - "name": "minecraft:mycelium", - "id": 110 - }, - { - "name": "minecraft:name_tag", - "id": 556 - }, - { - "name": "minecraft:nautilus_shell", - "id": 578 - }, - { - "name": "minecraft:nether_brick", - "id": 112 - }, - { - "name": "minecraft:nether_brick_fence", - "id": 113 - }, - { - "name": "minecraft:nether_brick_stairs", - "id": 114 - }, - { - "name": "minecraft:nether_gold_ore", - "id": -288 - }, - { - "name": "minecraft:nether_sprouts", - "id": 629 - }, - { - "name": "minecraft:nether_star", - "id": 526 - }, - { - "name": "minecraft:nether_wart", - "id": 295 - }, - { - "name": "minecraft:nether_wart_block", - "id": 214 - }, - { - "name": "minecraft:netherbrick", - "id": 531 - }, - { - "name": "minecraft:netherite_axe", - "id": 614 - }, - { - "name": "minecraft:netherite_block", - "id": -270 - }, - { - "name": "minecraft:netherite_boots", - "id": 620 - }, - { - "name": "minecraft:netherite_chestplate", - "id": 618 - }, - { - "name": "minecraft:netherite_helmet", - "id": 617 - }, - { - "name": "minecraft:netherite_hoe", - "id": 615 - }, - { - "name": "minecraft:netherite_ingot", - "id": 616 - }, - { - "name": "minecraft:netherite_leggings", - "id": 619 - }, - { - "name": "minecraft:netherite_pickaxe", - "id": 613 - }, - { - "name": "minecraft:netherite_scrap", - "id": 621 - }, - { - "name": "minecraft:netherite_shovel", - "id": 612 - }, - { - "name": "minecraft:netherite_sword", - "id": 611 - }, - { - "name": "minecraft:netherite_upgrade_smithing_template", - "id": 685 - }, - { - "name": "minecraft:netherrack", - "id": 87 - }, - { - "name": "minecraft:netherreactor", - "id": 247 - }, - { - "name": "minecraft:normal_stone_stairs", - "id": -180 - }, - { - "name": "minecraft:noteblock", - "id": 25 - }, - { - "name": "minecraft:npc_spawn_egg", - "id": 473 - }, - { - "name": "minecraft:oak_boat", - "id": 378 - }, - { - "name": "minecraft:oak_chest_boat", - "id": 646 - }, - { - "name": "minecraft:oak_fence", - "id": 85 - }, - { - "name": "minecraft:oak_hanging_sign", - "id": -500 - }, - { - "name": "minecraft:oak_log", - "id": 17 - }, - { - "name": "minecraft:oak_planks", - "id": 5 - }, - { - "name": "minecraft:oak_sign", - "id": 361 - }, - { - "name": "minecraft:oak_stairs", - "id": 53 - }, - { - "name": "minecraft:observer", - "id": 251 - }, - { - "name": "minecraft:obsidian", - "id": 49 - }, - { - "name": "minecraft:ocelot_spawn_egg", - "id": 454 - }, - { - "name": "minecraft:ochre_froglight", - "id": -471 - }, - { - "name": "minecraft:orange_candle", - "id": -414 - }, - { - "name": "minecraft:orange_candle_cake", - "id": -431 - }, - { - "name": "minecraft:orange_carpet", - "id": -597 - }, - { - "name": "minecraft:orange_concrete", - "id": -628 - }, - { - "name": "minecraft:orange_concrete_powder", - "id": -709 - }, - { - "name": "minecraft:orange_dye", - "id": 412 - }, - { - "name": "minecraft:orange_glazed_terracotta", - "id": 221 - }, - { - "name": "minecraft:orange_shulker_box", - "id": -613 - }, - { - "name": "minecraft:orange_stained_glass", - "id": -673 - }, - { - "name": "minecraft:orange_stained_glass_pane", - "id": -643 - }, - { - "name": "minecraft:orange_terracotta", - "id": -724 - }, - { - "name": "minecraft:orange_wool", - "id": -557 - }, - { - "name": "minecraft:oxidized_chiseled_copper", - "id": -763 - }, - { - "name": "minecraft:oxidized_copper", - "id": -343 - }, - { - "name": "minecraft:oxidized_copper_bulb", - "id": -779 - }, - { - "name": "minecraft:oxidized_copper_door", - "id": -787 - }, - { - "name": "minecraft:oxidized_copper_grate", - "id": -771 - }, - { - "name": "minecraft:oxidized_copper_trapdoor", - "id": -795 - }, - { - "name": "minecraft:oxidized_cut_copper", - "id": -350 - }, - { - "name": "minecraft:oxidized_cut_copper_slab", - "id": -364 - }, - { - "name": "minecraft:oxidized_cut_copper_stairs", - "id": -357 - }, - { - "name": "minecraft:oxidized_double_cut_copper_slab", - "id": -371 - }, - { - "name": "minecraft:packed_ice", - "id": 174 - }, - { - "name": "minecraft:packed_mud", - "id": -477 - }, - { - "name": "minecraft:painting", - "id": 360 - }, - { - "name": "minecraft:panda_spawn_egg", - "id": 492 - }, - { - "name": "minecraft:paper", - "id": 389 - }, - { - "name": "minecraft:parrot_spawn_egg", - "id": 481 - }, - { - "name": "minecraft:pearlescent_froglight", - "id": -469 - }, - { - "name": "minecraft:phantom_membrane", - "id": 582 - }, - { - "name": "minecraft:phantom_spawn_egg", - "id": 489 - }, - { - "name": "minecraft:pig_spawn_egg", - "id": 440 - }, - { - "name": "minecraft:piglin_banner_pattern", - "id": 595 - }, - { - "name": "minecraft:piglin_brute_spawn_egg", - "id": 502 - }, - { - "name": "minecraft:piglin_spawn_egg", - "id": 500 - }, - { - "name": "minecraft:pillager_spawn_egg", - "id": 494 - }, - { - "name": "minecraft:pink_candle", - "id": -419 - }, - { - "name": "minecraft:pink_candle_cake", - "id": -436 - }, - { - "name": "minecraft:pink_carpet", - "id": -602 - }, - { - "name": "minecraft:pink_concrete", - "id": -633 - }, - { - "name": "minecraft:pink_concrete_powder", - "id": -714 - }, - { - "name": "minecraft:pink_dye", - "id": 407 - }, - { - "name": "minecraft:pink_glazed_terracotta", - "id": 226 - }, - { - "name": "minecraft:pink_petals", - "id": -549 - }, - { - "name": "minecraft:pink_shulker_box", - "id": -618 - }, - { - "name": "minecraft:pink_stained_glass", - "id": -678 - }, - { - "name": "minecraft:pink_stained_glass_pane", - "id": -648 - }, - { - "name": "minecraft:pink_terracotta", - "id": -729 - }, - { - "name": "minecraft:pink_wool", - "id": -566 - }, - { - "name": "minecraft:piston", - "id": 33 - }, - { - "name": "minecraft:piston_arm_collision", - "id": 34 - }, - { - "name": "minecraft:pitcher_crop", - "id": -574 - }, - { - "name": "minecraft:pitcher_plant", - "id": -612 - }, - { - "name": "minecraft:pitcher_pod", - "id": 298 - }, - { - "name": "minecraft:planks", - "id": 708 - }, - { - "name": "minecraft:plenty_pottery_sherd", - "id": 678 - }, - { - "name": "minecraft:podzol", - "id": 243 - }, - { - "name": "minecraft:pointed_dripstone", - "id": -308 - }, - { - "name": "minecraft:poisonous_potato", - "id": 283 - }, - { - "name": "minecraft:polar_bear_spawn_egg", - "id": 475 - }, - { - "name": "minecraft:polished_andesite", - "id": -595 - }, - { - "name": "minecraft:polished_andesite_stairs", - "id": -174 - }, - { - "name": "minecraft:polished_basalt", - "id": -235 - }, - { - "name": "minecraft:polished_blackstone", - "id": -291 - }, - { - "name": "minecraft:polished_blackstone_brick_double_slab", - "id": -285 - }, - { - "name": "minecraft:polished_blackstone_brick_slab", - "id": -284 - }, - { - "name": "minecraft:polished_blackstone_brick_stairs", - "id": -275 - }, - { - "name": "minecraft:polished_blackstone_brick_wall", - "id": -278 - }, - { - "name": "minecraft:polished_blackstone_bricks", - "id": -274 - }, - { - "name": "minecraft:polished_blackstone_button", - "id": -296 - }, - { - "name": "minecraft:polished_blackstone_double_slab", - "id": -294 - }, - { - "name": "minecraft:polished_blackstone_pressure_plate", - "id": -295 - }, - { - "name": "minecraft:polished_blackstone_slab", - "id": -293 - }, - { - "name": "minecraft:polished_blackstone_stairs", - "id": -292 - }, - { - "name": "minecraft:polished_blackstone_wall", - "id": -297 - }, - { - "name": "minecraft:polished_deepslate", - "id": -383 - }, - { - "name": "minecraft:polished_deepslate_double_slab", - "id": -397 - }, - { - "name": "minecraft:polished_deepslate_slab", - "id": -384 - }, - { - "name": "minecraft:polished_deepslate_stairs", - "id": -385 - }, - { - "name": "minecraft:polished_deepslate_wall", - "id": -386 - }, - { - "name": "minecraft:polished_diorite", - "id": -593 - }, - { - "name": "minecraft:polished_diorite_stairs", - "id": -173 - }, - { - "name": "minecraft:polished_granite", - "id": -591 - }, - { - "name": "minecraft:polished_granite_stairs", - "id": -172 - }, - { - "name": "minecraft:polished_tuff", - "id": -748 - }, - { - "name": "minecraft:polished_tuff_double_slab", - "id": -750 - }, - { - "name": "minecraft:polished_tuff_slab", - "id": -749 - }, - { - "name": "minecraft:polished_tuff_stairs", - "id": -751 - }, - { - "name": "minecraft:polished_tuff_wall", - "id": -752 - }, - { - "name": "minecraft:popped_chorus_fruit", - "id": 567 - }, - { - "name": "minecraft:porkchop", - "id": 263 - }, - { - "name": "minecraft:portal", - "id": 90 - }, - { - "name": "minecraft:potato", - "id": 281 - }, - { - "name": "minecraft:potatoes", - "id": 142 - }, - { - "name": "minecraft:potion", - "id": 429 - }, - { - "name": "minecraft:powder_snow", - "id": -306 - }, - { - "name": "minecraft:powder_snow_bucket", - "id": 371 - }, - { - "name": "minecraft:powered_comparator", - "id": 150 - }, - { - "name": "minecraft:powered_repeater", - "id": 94 - }, - { - "name": "minecraft:prismarine", - "id": 168 - }, - { - "name": "minecraft:prismarine_bricks_stairs", - "id": -4 - }, - { - "name": "minecraft:prismarine_crystals", - "id": 557 - }, - { - "name": "minecraft:prismarine_shard", - "id": 573 - }, - { - "name": "minecraft:prismarine_stairs", - "id": -2 - }, - { - "name": "minecraft:prize_pottery_sherd", - "id": 679 - }, - { - "name": "minecraft:pufferfish", - "id": 268 - }, - { - "name": "minecraft:pufferfish_bucket", - "id": 370 - }, - { - "name": "minecraft:pufferfish_spawn_egg", - "id": 484 - }, - { - "name": "minecraft:pumpkin", - "id": 86 - }, - { - "name": "minecraft:pumpkin_pie", - "id": 285 - }, - { - "name": "minecraft:pumpkin_seeds", - "id": 293 - }, - { - "name": "minecraft:pumpkin_stem", - "id": 104 - }, - { - "name": "minecraft:purple_candle", - "id": -423 - }, - { - "name": "minecraft:purple_candle_cake", - "id": -440 - }, - { - "name": "minecraft:purple_carpet", - "id": -606 - }, - { - "name": "minecraft:purple_concrete", - "id": -637 - }, - { - "name": "minecraft:purple_concrete_powder", - "id": -718 - }, - { - "name": "minecraft:purple_dye", - "id": 403 - }, - { - "name": "minecraft:purple_glazed_terracotta", - "id": 219 - }, - { - "name": "minecraft:purple_shulker_box", - "id": -622 - }, - { - "name": "minecraft:purple_stained_glass", - "id": -682 - }, - { - "name": "minecraft:purple_stained_glass_pane", - "id": -652 - }, - { - "name": "minecraft:purple_terracotta", - "id": -733 - }, - { - "name": "minecraft:purple_wool", - "id": -564 - }, - { - "name": "minecraft:purpur_block", - "id": 201 - }, - { - "name": "minecraft:purpur_stairs", - "id": 203 - }, - { - "name": "minecraft:quartz", - "id": 532 - }, - { - "name": "minecraft:quartz_block", - "id": 155 - }, - { - "name": "minecraft:quartz_bricks", - "id": -304 - }, - { - "name": "minecraft:quartz_ore", - "id": 153 - }, - { - "name": "minecraft:quartz_stairs", - "id": 156 - }, - { - "name": "minecraft:rabbit", - "id": 289 - }, - { - "name": "minecraft:rabbit_foot", - "id": 536 - }, - { - "name": "minecraft:rabbit_hide", - "id": 537 - }, - { - "name": "minecraft:rabbit_spawn_egg", - "id": 462 - }, - { - "name": "minecraft:rabbit_stew", - "id": 291 - }, - { - "name": "minecraft:rail", - "id": 66 - }, - { - "name": "minecraft:raiser_armor_trim_smithing_template", - "id": 699 - }, - { - "name": "minecraft:rapid_fertilizer", - "id": 605 - }, - { - "name": "minecraft:ravager_spawn_egg", - "id": 496 - }, - { - "name": "minecraft:raw_copper", - "id": 515 - }, - { - "name": "minecraft:raw_copper_block", - "id": -452 - }, - { - "name": "minecraft:raw_gold", - "id": 514 - }, - { - "name": "minecraft:raw_gold_block", - "id": -453 - }, - { - "name": "minecraft:raw_iron", - "id": 513 - }, - { - "name": "minecraft:raw_iron_block", - "id": -451 - }, - { - "name": "minecraft:recovery_compass", - "id": 654 - }, - { - "name": "minecraft:red_candle", - "id": -427 - }, - { - "name": "minecraft:red_candle_cake", - "id": -444 - }, - { - "name": "minecraft:red_carpet", - "id": -610 - }, - { - "name": "minecraft:red_concrete", - "id": -641 - }, - { - "name": "minecraft:red_concrete_powder", - "id": -722 - }, - { - "name": "minecraft:red_dye", - "id": 399 - }, - { - "name": "minecraft:red_flower", - "id": 38 - }, - { - "name": "minecraft:red_glazed_terracotta", - "id": 234 - }, - { - "name": "minecraft:red_mushroom", - "id": 40 - }, - { - "name": "minecraft:red_mushroom_block", - "id": 100 - }, - { - "name": "minecraft:red_nether_brick", - "id": 215 - }, - { - "name": "minecraft:red_nether_brick_stairs", - "id": -184 - }, - { - "name": "minecraft:red_sandstone", - "id": 179 - }, - { - "name": "minecraft:red_sandstone_stairs", - "id": 180 - }, - { - "name": "minecraft:red_shulker_box", - "id": -626 - }, - { - "name": "minecraft:red_stained_glass", - "id": -686 - }, - { - "name": "minecraft:red_stained_glass_pane", - "id": -656 - }, - { - "name": "minecraft:red_terracotta", - "id": -737 - }, - { - "name": "minecraft:red_wool", - "id": -556 - }, - { - "name": "minecraft:redstone", - "id": 376 - }, - { - "name": "minecraft:redstone_block", - "id": 152 - }, - { - "name": "minecraft:redstone_lamp", - "id": 123 - }, - { - "name": "minecraft:redstone_ore", - "id": 73 - }, - { - "name": "minecraft:redstone_torch", - "id": 76 - }, - { - "name": "minecraft:redstone_wire", - "id": 55 - }, - { - "name": "minecraft:reinforced_deepslate", - "id": -466 - }, - { - "name": "minecraft:repeater", - "id": 422 - }, - { - "name": "minecraft:repeating_command_block", - "id": 188 - }, - { - "name": "minecraft:reserved6", - "id": 255 - }, - { - "name": "minecraft:respawn_anchor", - "id": -272 - }, - { - "name": "minecraft:rib_armor_trim_smithing_template", - "id": 695 - }, - { - "name": "minecraft:rotten_flesh", - "id": 278 - }, - { - "name": "minecraft:saddle", - "id": 374 - }, - { - "name": "minecraft:salmon", - "id": 266 - }, - { - "name": "minecraft:salmon_bucket", - "id": 368 - }, - { - "name": "minecraft:salmon_spawn_egg", - "id": 485 - }, - { - "name": "minecraft:sand", - "id": 12 - }, - { - "name": "minecraft:sandstone", - "id": 24 - }, - { - "name": "minecraft:sandstone_stairs", - "id": 128 - }, - { - "name": "minecraft:sapling", - "id": 6 - }, - { - "name": "minecraft:scaffolding", - "id": -165 - }, - { - "name": "minecraft:sculk", - "id": -458 - }, - { - "name": "minecraft:sculk_catalyst", - "id": -460 - }, - { - "name": "minecraft:sculk_sensor", - "id": -307 - }, - { - "name": "minecraft:sculk_shrieker", - "id": -461 - }, - { - "name": "minecraft:sculk_vein", - "id": -459 - }, - { - "name": "minecraft:scute", - "id": 580 - }, - { - "name": "minecraft:sea_lantern", - "id": 169 - }, - { - "name": "minecraft:sea_pickle", - "id": -156 - }, - { - "name": "minecraft:seagrass", - "id": -130 - }, - { - "name": "minecraft:sentry_armor_trim_smithing_template", - "id": 686 - }, - { - "name": "minecraft:shaper_armor_trim_smithing_template", - "id": 700 - }, - { - "name": "minecraft:sheaf_pottery_sherd", - "id": 680 - }, - { - "name": "minecraft:shears", - "id": 424 - }, - { - "name": "minecraft:sheep_spawn_egg", - "id": 441 - }, - { - "name": "minecraft:shelter_pottery_sherd", - "id": 681 - }, - { - "name": "minecraft:shield", - "id": 358 - }, - { - "name": "minecraft:shroomlight", - "id": -230 - }, - { - "name": "minecraft:shulker_box", - "id": 715 - }, - { - "name": "minecraft:shulker_shell", - "id": 574 - }, - { - "name": "minecraft:shulker_spawn_egg", - "id": 472 - }, - { - "name": "minecraft:silence_armor_trim_smithing_template", - "id": 697 - }, - { - "name": "minecraft:silver_glazed_terracotta", - "id": 228 - }, - { - "name": "minecraft:silverfish_spawn_egg", - "id": 446 - }, - { - "name": "minecraft:skeleton_horse_spawn_egg", - "id": 470 - }, - { - "name": "minecraft:skeleton_spawn_egg", - "id": 447 - }, - { - "name": "minecraft:skull", - "id": 524 - }, - { - "name": "minecraft:skull_banner_pattern", - "id": 591 - }, - { - "name": "minecraft:skull_pottery_sherd", - "id": 682 - }, - { - "name": "minecraft:slime", - "id": 165 - }, - { - "name": "minecraft:slime_ball", - "id": 391 - }, - { - "name": "minecraft:slime_spawn_egg", - "id": 448 - }, - { - "name": "minecraft:small_amethyst_bud", - "id": -332 - }, - { - "name": "minecraft:small_dripleaf_block", - "id": -336 - }, - { - "name": "minecraft:smithing_table", - "id": -202 - }, - { - "name": "minecraft:smoker", - "id": -198 - }, - { - "name": "minecraft:smooth_basalt", - "id": -377 - }, - { - "name": "minecraft:smooth_quartz_stairs", - "id": -185 - }, - { - "name": "minecraft:smooth_red_sandstone_stairs", - "id": -176 - }, - { - "name": "minecraft:smooth_sandstone_stairs", - "id": -177 - }, - { - "name": "minecraft:smooth_stone", - "id": -183 - }, - { - "name": "minecraft:sniffer_egg", - "id": -596 - }, - { - "name": "minecraft:sniffer_spawn_egg", - "id": 503 - }, - { - "name": "minecraft:snort_pottery_sherd", - "id": 683 - }, - { - "name": "minecraft:snout_armor_trim_smithing_template", - "id": 694 - }, - { - "name": "minecraft:snow", - "id": 80 - }, - { - "name": "minecraft:snow_golem_spawn_egg", - "id": 508 - }, - { - "name": "minecraft:snow_layer", - "id": 78 - }, - { - "name": "minecraft:snowball", - "id": 377 - }, - { - "name": "minecraft:soul_campfire", - "id": 630 - }, - { - "name": "minecraft:soul_fire", - "id": -237 - }, - { - "name": "minecraft:soul_lantern", - "id": -269 - }, - { - "name": "minecraft:soul_sand", - "id": 88 - }, - { - "name": "minecraft:soul_soil", - "id": -236 - }, - { - "name": "minecraft:soul_torch", - "id": -268 - }, - { - "name": "minecraft:sparkler", - "id": 608 - }, - { - "name": "minecraft:spawn_egg", - "id": 719 - }, - { - "name": "minecraft:spider_eye", - "id": 279 - }, - { - "name": "minecraft:spider_spawn_egg", - "id": 449 - }, - { - "name": "minecraft:spire_armor_trim_smithing_template", - "id": 696 - }, - { - "name": "minecraft:splash_potion", - "id": 569 - }, - { - "name": "minecraft:sponge", - "id": 19 - }, - { - "name": "minecraft:spore_blossom", - "id": -321 - }, - { - "name": "minecraft:spruce_boat", - "id": 381 - }, - { - "name": "minecraft:spruce_button", - "id": -144 - }, - { - "name": "minecraft:spruce_chest_boat", - "id": 649 - }, - { - "name": "minecraft:spruce_door", - "id": 561 - }, - { - "name": "minecraft:spruce_fence", - "id": -579 - }, - { - "name": "minecraft:spruce_fence_gate", - "id": 183 - }, - { - "name": "minecraft:spruce_hanging_sign", - "id": -501 - }, - { - "name": "minecraft:spruce_log", - "id": -569 - }, - { - "name": "minecraft:spruce_planks", - "id": -739 - }, - { - "name": "minecraft:spruce_pressure_plate", - "id": -154 - }, - { - "name": "minecraft:spruce_sign", - "id": 584 - }, - { - "name": "minecraft:spruce_stairs", - "id": 134 - }, - { - "name": "minecraft:spruce_standing_sign", - "id": -181 - }, - { - "name": "minecraft:spruce_trapdoor", - "id": -149 - }, - { - "name": "minecraft:spruce_wall_sign", - "id": -182 - }, - { - "name": "minecraft:spyglass", - "id": 633 - }, - { - "name": "minecraft:squid_spawn_egg", - "id": 453 - }, - { - "name": "minecraft:stained_glass", - "id": 713 - }, - { - "name": "minecraft:stained_glass_pane", - "id": 714 - }, - { - "name": "minecraft:stained_hardened_clay", - "id": 703 - }, - { - "name": "minecraft:standing_banner", - "id": 176 - }, - { - "name": "minecraft:standing_sign", - "id": 63 - }, - { - "name": "minecraft:stick", - "id": 323 - }, - { - "name": "minecraft:sticky_piston", - "id": 29 - }, - { - "name": "minecraft:sticky_piston_arm_collision", - "id": -217 - }, - { - "name": "minecraft:stone", - "id": 1 - }, - { - "name": "minecraft:stone_axe", - "id": 318 - }, - { - "name": "minecraft:stone_block_slab", - "id": 44 - }, - { - "name": "minecraft:stone_block_slab2", - "id": 182 - }, - { - "name": "minecraft:stone_block_slab3", - "id": -162 - }, - { - "name": "minecraft:stone_block_slab4", - "id": -166 - }, - { - "name": "minecraft:stone_brick_stairs", - "id": 109 - }, - { - "name": "minecraft:stone_button", - "id": 77 - }, - { - "name": "minecraft:stone_hoe", - "id": 333 - }, - { - "name": "minecraft:stone_pickaxe", - "id": 317 - }, - { - "name": "minecraft:stone_pressure_plate", - "id": 70 - }, - { - "name": "minecraft:stone_shovel", - "id": 316 - }, - { - "name": "minecraft:stone_stairs", - "id": 67 - }, - { - "name": "minecraft:stone_sword", - "id": 315 - }, - { - "name": "minecraft:stonebrick", - "id": 98 - }, - { - "name": "minecraft:stonecutter", - "id": 245 - }, - { - "name": "minecraft:stonecutter_block", - "id": -197 - }, - { - "name": "minecraft:stray_spawn_egg", - "id": 465 - }, - { - "name": "minecraft:strider_spawn_egg", - "id": 498 - }, - { - "name": "minecraft:string", - "id": 329 - }, - { - "name": "minecraft:stripped_acacia_log", - "id": -8 - }, - { - "name": "minecraft:stripped_bamboo_block", - "id": -528 - }, - { - "name": "minecraft:stripped_birch_log", - "id": -6 - }, - { - "name": "minecraft:stripped_cherry_log", - "id": -535 - }, - { - "name": "minecraft:stripped_cherry_wood", - "id": -545 - }, - { - "name": "minecraft:stripped_crimson_hyphae", - "id": -300 - }, - { - "name": "minecraft:stripped_crimson_stem", - "id": -240 - }, - { - "name": "minecraft:stripped_dark_oak_log", - "id": -9 - }, - { - "name": "minecraft:stripped_jungle_log", - "id": -7 - }, - { - "name": "minecraft:stripped_mangrove_log", - "id": -485 - }, - { - "name": "minecraft:stripped_mangrove_wood", - "id": -498 - }, - { - "name": "minecraft:stripped_oak_log", - "id": -10 - }, - { - "name": "minecraft:stripped_spruce_log", - "id": -5 - }, - { - "name": "minecraft:stripped_warped_hyphae", - "id": -301 - }, - { - "name": "minecraft:stripped_warped_stem", - "id": -241 - }, - { - "name": "minecraft:structure_block", - "id": 252 - }, - { - "name": "minecraft:structure_void", - "id": 217 - }, - { - "name": "minecraft:sugar", - "id": 419 - }, - { - "name": "minecraft:sugar_cane", - "id": 388 - }, - { - "name": "minecraft:suspicious_gravel", - "id": -573 - }, - { - "name": "minecraft:suspicious_sand", - "id": -529 - }, - { - "name": "minecraft:suspicious_stew", - "id": 598 - }, - { - "name": "minecraft:sweet_berries", - "id": 288 - }, - { - "name": "minecraft:sweet_berry_bush", - "id": -207 - }, - { - "name": "minecraft:tadpole_bucket", - "id": 638 - }, - { - "name": "minecraft:tadpole_spawn_egg", - "id": 637 - }, - { - "name": "minecraft:tallgrass", - "id": 31 - }, - { - "name": "minecraft:target", - "id": -239 - }, - { - "name": "minecraft:tide_armor_trim_smithing_template", - "id": 693 - }, - { - "name": "minecraft:tinted_glass", - "id": -334 - }, - { - "name": "minecraft:tnt", - "id": 46 - }, - { - "name": "minecraft:tnt_minecart", - "id": 533 - }, - { - "name": "minecraft:torch", - "id": 50 - }, - { - "name": "minecraft:torchflower", - "id": -568 - }, - { - "name": "minecraft:torchflower_crop", - "id": -567 - }, - { - "name": "minecraft:torchflower_seeds", - "id": 297 - }, - { - "name": "minecraft:totem_of_undying", - "id": 576 - }, - { - "name": "minecraft:trader_llama_spawn_egg", - "id": 656 - }, - { - "name": "minecraft:trapdoor", - "id": 96 - }, - { - "name": "minecraft:trapped_chest", - "id": 146 - }, - { - "name": "minecraft:trident", - "id": 554 - }, - { - "name": "minecraft:trip_wire", - "id": 132 - }, - { - "name": "minecraft:tripwire_hook", - "id": 131 - }, - { - "name": "minecraft:tropical_fish", - "id": 267 - }, - { - "name": "minecraft:tropical_fish_bucket", - "id": 369 - }, - { - "name": "minecraft:tropical_fish_spawn_egg", - "id": 482 - }, - { - "name": "minecraft:tube_coral", - "id": -131 - }, - { - "name": "minecraft:tuff", - "id": -333 - }, - { - "name": "minecraft:tuff_brick_double_slab", - "id": -756 - }, - { - "name": "minecraft:tuff_brick_slab", - "id": -755 - }, - { - "name": "minecraft:tuff_brick_stairs", - "id": -757 - }, - { - "name": "minecraft:tuff_brick_wall", - "id": -758 - }, - { - "name": "minecraft:tuff_bricks", - "id": -754 - }, - { - "name": "minecraft:tuff_double_slab", - "id": -745 - }, - { - "name": "minecraft:tuff_slab", - "id": -744 - }, - { - "name": "minecraft:tuff_stairs", - "id": -746 - }, - { - "name": "minecraft:tuff_wall", - "id": -747 - }, - { - "name": "minecraft:turtle_egg", - "id": -159 - }, - { - "name": "minecraft:turtle_helmet", - "id": 581 - }, - { - "name": "minecraft:turtle_spawn_egg", - "id": 488 - }, - { - "name": "minecraft:twisting_vines", - "id": -287 - }, - { - "name": "minecraft:underwater_torch", - "id": 239 - }, - { - "name": "minecraft:undyed_shulker_box", - "id": 205 - }, - { - "name": "minecraft:unknown", - "id": -305 - }, - { - "name": "minecraft:unlit_redstone_torch", - "id": 75 - }, - { - "name": "minecraft:unpowered_comparator", - "id": 149 - }, - { - "name": "minecraft:unpowered_repeater", - "id": 93 - }, - { - "name": "minecraft:verdant_froglight", - "id": -470 - }, - { - "name": "minecraft:vex_armor_trim_smithing_template", - "id": 692 - }, - { - "name": "minecraft:vex_spawn_egg", - "id": 479 - }, - { - "name": "minecraft:villager_spawn_egg", - "id": 452 - }, - { - "name": "minecraft:vindicator_spawn_egg", - "id": 477 - }, - { - "name": "minecraft:vine", - "id": 106 - }, - { - "name": "minecraft:wall_banner", - "id": 177 - }, - { - "name": "minecraft:wall_sign", - "id": 68 - }, - { - "name": "minecraft:wandering_trader_spawn_egg", - "id": 495 - }, - { - "name": "minecraft:ward_armor_trim_smithing_template", - "id": 690 - }, - { - "name": "minecraft:warden_spawn_egg", - "id": 640 - }, - { - "name": "minecraft:warped_button", - "id": -261 - }, - { - "name": "minecraft:warped_door", - "id": 625 - }, - { - "name": "minecraft:warped_double_slab", - "id": -267 - }, - { - "name": "minecraft:warped_fence", - "id": -257 - }, - { - "name": "minecraft:warped_fence_gate", - "id": -259 - }, - { - "name": "minecraft:warped_fungus", - "id": -229 - }, - { - "name": "minecraft:warped_fungus_on_a_stick", - "id": 626 - }, - { - "name": "minecraft:warped_hanging_sign", - "id": -507 - }, - { - "name": "minecraft:warped_hyphae", - "id": -298 - }, - { - "name": "minecraft:warped_nylium", - "id": -233 - }, - { - "name": "minecraft:warped_planks", - "id": -243 - }, - { - "name": "minecraft:warped_pressure_plate", - "id": -263 - }, - { - "name": "minecraft:warped_roots", - "id": -224 - }, - { - "name": "minecraft:warped_sign", - "id": 623 - }, - { - "name": "minecraft:warped_slab", - "id": -265 - }, - { - "name": "minecraft:warped_stairs", - "id": -255 - }, - { - "name": "minecraft:warped_standing_sign", - "id": -251 - }, - { - "name": "minecraft:warped_stem", - "id": -226 - }, - { - "name": "minecraft:warped_trapdoor", - "id": -247 - }, - { - "name": "minecraft:warped_wall_sign", - "id": -253 - }, - { - "name": "minecraft:warped_wart_block", - "id": -227 - }, - { - "name": "minecraft:water", - "id": 9 - }, - { - "name": "minecraft:water_bucket", - "id": 365 - }, - { - "name": "minecraft:waterlily", - "id": 111 - }, - { - "name": "minecraft:waxed_chiseled_copper", - "id": -764 - }, - { - "name": "minecraft:waxed_copper", - "id": -344 - }, - { - "name": "minecraft:waxed_copper_bulb", - "id": -780 - }, - { - "name": "minecraft:waxed_copper_door", - "id": -788 - }, - { - "name": "minecraft:waxed_copper_grate", - "id": -772 - }, - { - "name": "minecraft:waxed_copper_trapdoor", - "id": -796 - }, - { - "name": "minecraft:waxed_cut_copper", - "id": -351 - }, - { - "name": "minecraft:waxed_cut_copper_slab", - "id": -365 - }, - { - "name": "minecraft:waxed_cut_copper_stairs", - "id": -358 - }, - { - "name": "minecraft:waxed_double_cut_copper_slab", - "id": -372 - }, - { - "name": "minecraft:waxed_exposed_chiseled_copper", - "id": -765 - }, - { - "name": "minecraft:waxed_exposed_copper", - "id": -345 - }, - { - "name": "minecraft:waxed_exposed_copper_bulb", - "id": -781 - }, - { - "name": "minecraft:waxed_exposed_copper_door", - "id": -789 - }, - { - "name": "minecraft:waxed_exposed_copper_grate", - "id": -773 - }, - { - "name": "minecraft:waxed_exposed_copper_trapdoor", - "id": -797 - }, - { - "name": "minecraft:waxed_exposed_cut_copper", - "id": -352 - }, - { - "name": "minecraft:waxed_exposed_cut_copper_slab", - "id": -366 - }, - { - "name": "minecraft:waxed_exposed_cut_copper_stairs", - "id": -359 - }, - { - "name": "minecraft:waxed_exposed_double_cut_copper_slab", - "id": -373 - }, - { - "name": "minecraft:waxed_oxidized_chiseled_copper", - "id": -766 - }, - { - "name": "minecraft:waxed_oxidized_copper", - "id": -446 - }, - { - "name": "minecraft:waxed_oxidized_copper_bulb", - "id": -783 - }, - { - "name": "minecraft:waxed_oxidized_copper_door", - "id": -791 - }, - { - "name": "minecraft:waxed_oxidized_copper_grate", - "id": -775 - }, - { - "name": "minecraft:waxed_oxidized_copper_trapdoor", - "id": -799 - }, - { - "name": "minecraft:waxed_oxidized_cut_copper", - "id": -447 - }, - { - "name": "minecraft:waxed_oxidized_cut_copper_slab", - "id": -449 - }, - { - "name": "minecraft:waxed_oxidized_cut_copper_stairs", - "id": -448 - }, - { - "name": "minecraft:waxed_oxidized_double_cut_copper_slab", - "id": -450 - }, - { - "name": "minecraft:waxed_weathered_chiseled_copper", - "id": -767 - }, - { - "name": "minecraft:waxed_weathered_copper", - "id": -346 - }, - { - "name": "minecraft:waxed_weathered_copper_bulb", - "id": -782 - }, - { - "name": "minecraft:waxed_weathered_copper_door", - "id": -790 - }, - { - "name": "minecraft:waxed_weathered_copper_grate", - "id": -774 - }, - { - "name": "minecraft:waxed_weathered_copper_trapdoor", - "id": -798 - }, - { - "name": "minecraft:waxed_weathered_cut_copper", - "id": -353 - }, - { - "name": "minecraft:waxed_weathered_cut_copper_slab", - "id": -367 - }, - { - "name": "minecraft:waxed_weathered_cut_copper_stairs", - "id": -360 - }, - { - "name": "minecraft:waxed_weathered_double_cut_copper_slab", - "id": -374 - }, - { - "name": "minecraft:wayfinder_armor_trim_smithing_template", - "id": 698 - }, - { - "name": "minecraft:weathered_chiseled_copper", - "id": -762 - }, - { - "name": "minecraft:weathered_copper", - "id": -342 - }, - { - "name": "minecraft:weathered_copper_bulb", - "id": -778 - }, - { - "name": "minecraft:weathered_copper_door", - "id": -786 - }, - { - "name": "minecraft:weathered_copper_grate", - "id": -770 - }, - { - "name": "minecraft:weathered_copper_trapdoor", - "id": -794 - }, - { - "name": "minecraft:weathered_cut_copper", - "id": -349 - }, - { - "name": "minecraft:weathered_cut_copper_slab", - "id": -363 - }, - { - "name": "minecraft:weathered_cut_copper_stairs", - "id": -356 - }, - { - "name": "minecraft:weathered_double_cut_copper_slab", - "id": -370 - }, - { - "name": "minecraft:web", - "id": 30 - }, - { - "name": "minecraft:weeping_vines", - "id": -231 - }, - { - "name": "minecraft:wheat", - "id": 337 - }, - { - "name": "minecraft:wheat_seeds", - "id": 292 - }, - { - "name": "minecraft:white_candle", - "id": -413 - }, - { - "name": "minecraft:white_candle_cake", - "id": -430 - }, - { - "name": "minecraft:white_carpet", - "id": 171 - }, - { - "name": "minecraft:white_concrete", - "id": 236 - }, - { - "name": "minecraft:white_concrete_powder", - "id": 237 - }, - { - "name": "minecraft:white_dye", - "id": 413 - }, - { - "name": "minecraft:white_glazed_terracotta", - "id": 220 - }, - { - "name": "minecraft:white_shulker_box", - "id": 218 - }, - { - "name": "minecraft:white_stained_glass", - "id": 241 - }, - { - "name": "minecraft:white_stained_glass_pane", - "id": 160 - }, - { - "name": "minecraft:white_terracotta", - "id": 159 - }, - { - "name": "minecraft:white_wool", - "id": 35 - }, - { - "name": "minecraft:wild_armor_trim_smithing_template", - "id": 689 - }, - { - "name": "minecraft:witch_spawn_egg", - "id": 455 - }, - { - "name": "minecraft:wither_rose", - "id": -216 - }, - { - "name": "minecraft:wither_skeleton_spawn_egg", - "id": 467 - }, - { - "name": "minecraft:wither_spawn_egg", - "id": 510 - }, - { - "name": "minecraft:wolf_spawn_egg", - "id": 442 - }, - { - "name": "minecraft:wood", - "id": -212 - }, - { - "name": "minecraft:wooden_axe", - "id": 314 - }, - { - "name": "minecraft:wooden_button", - "id": 143 - }, - { - "name": "minecraft:wooden_door", - "id": 362 - }, - { - "name": "minecraft:wooden_hoe", - "id": 332 - }, - { - "name": "minecraft:wooden_pickaxe", - "id": 313 - }, - { - "name": "minecraft:wooden_pressure_plate", - "id": 72 - }, - { - "name": "minecraft:wooden_shovel", - "id": 312 - }, - { - "name": "minecraft:wooden_slab", - "id": 158 - }, - { - "name": "minecraft:wooden_sword", - "id": 311 - }, - { - "name": "minecraft:wool", - "id": 704 - }, - { - "name": "minecraft:writable_book", - "id": 518 - }, - { - "name": "minecraft:written_book", - "id": 519 - }, - { - "name": "minecraft:yellow_candle", - "id": -417 - }, - { - "name": "minecraft:yellow_candle_cake", - "id": -434 - }, - { - "name": "minecraft:yellow_carpet", - "id": -600 - }, - { - "name": "minecraft:yellow_concrete", - "id": -631 - }, - { - "name": "minecraft:yellow_concrete_powder", - "id": -712 - }, - { - "name": "minecraft:yellow_dye", - "id": 409 - }, - { - "name": "minecraft:yellow_flower", - "id": 37 - }, - { - "name": "minecraft:yellow_glazed_terracotta", - "id": 224 - }, - { - "name": "minecraft:yellow_shulker_box", - "id": -616 - }, - { - "name": "minecraft:yellow_stained_glass", - "id": -676 - }, - { - "name": "minecraft:yellow_stained_glass_pane", - "id": -646 - }, - { - "name": "minecraft:yellow_terracotta", - "id": -727 - }, - { - "name": "minecraft:yellow_wool", - "id": -558 - }, - { - "name": "minecraft:zoglin_spawn_egg", - "id": 501 - }, - { - "name": "minecraft:zombie_horse_spawn_egg", - "id": 471 - }, - { - "name": "minecraft:zombie_pigman_spawn_egg", - "id": 451 - }, - { - "name": "minecraft:zombie_spawn_egg", - "id": 450 - }, - { - "name": "minecraft:zombie_villager_spawn_egg", - "id": 480 - } -] \ No newline at end of file diff --git a/core/src/main/resources/bedrock/runtime_item_states.1_20_60.json b/core/src/main/resources/bedrock/runtime_item_states.1_20_60.json deleted file mode 100644 index f8b3199e3..000000000 --- a/core/src/main/resources/bedrock/runtime_item_states.1_20_60.json +++ /dev/null @@ -1,5998 +0,0 @@ -[ - { - "name": "minecraft:acacia_boat", - "id": 382 - }, - { - "name": "minecraft:acacia_button", - "id": -140 - }, - { - "name": "minecraft:acacia_chest_boat", - "id": 651 - }, - { - "name": "minecraft:acacia_door", - "id": 565 - }, - { - "name": "minecraft:acacia_fence", - "id": -575 - }, - { - "name": "minecraft:acacia_fence_gate", - "id": 187 - }, - { - "name": "minecraft:acacia_hanging_sign", - "id": -504 - }, - { - "name": "minecraft:acacia_log", - "id": 162 - }, - { - "name": "minecraft:acacia_planks", - "id": -742 - }, - { - "name": "minecraft:acacia_pressure_plate", - "id": -150 - }, - { - "name": "minecraft:acacia_sign", - "id": 588 - }, - { - "name": "minecraft:acacia_stairs", - "id": 163 - }, - { - "name": "minecraft:acacia_standing_sign", - "id": -190 - }, - { - "name": "minecraft:acacia_trapdoor", - "id": -145 - }, - { - "name": "minecraft:acacia_wall_sign", - "id": -191 - }, - { - "name": "minecraft:activator_rail", - "id": 126 - }, - { - "name": "minecraft:agent_spawn_egg", - "id": 490 - }, - { - "name": "minecraft:air", - "id": -158 - }, - { - "name": "minecraft:allay_spawn_egg", - "id": 640 - }, - { - "name": "minecraft:allow", - "id": 210 - }, - { - "name": "minecraft:amethyst_block", - "id": -327 - }, - { - "name": "minecraft:amethyst_cluster", - "id": -329 - }, - { - "name": "minecraft:amethyst_shard", - "id": 633 - }, - { - "name": "minecraft:ancient_debris", - "id": -271 - }, - { - "name": "minecraft:andesite", - "id": -594 - }, - { - "name": "minecraft:andesite_stairs", - "id": -171 - }, - { - "name": "minecraft:angler_pottery_sherd", - "id": 665 - }, - { - "name": "minecraft:anvil", - "id": 145 - }, - { - "name": "minecraft:apple", - "id": 257 - }, - { - "name": "minecraft:archer_pottery_sherd", - "id": 666 - }, - { - "name": "minecraft:armadillo_scute", - "id": 707 - }, - { - "name": "minecraft:armadillo_spawn_egg", - "id": 706 - }, - { - "name": "minecraft:armor_stand", - "id": 561 - }, - { - "name": "minecraft:arms_up_pottery_sherd", - "id": 667 - }, - { - "name": "minecraft:arrow", - "id": 304 - }, - { - "name": "minecraft:axolotl_bucket", - "id": 372 - }, - { - "name": "minecraft:axolotl_spawn_egg", - "id": 505 - }, - { - "name": "minecraft:azalea", - "id": -337 - }, - { - "name": "minecraft:azalea_leaves", - "id": -324 - }, - { - "name": "minecraft:azalea_leaves_flowered", - "id": -325 - }, - { - "name": "minecraft:baked_potato", - "id": 282 - }, - { - "name": "minecraft:balloon", - "id": 607 - }, - { - "name": "minecraft:bamboo", - "id": -163 - }, - { - "name": "minecraft:bamboo_block", - "id": -527 - }, - { - "name": "minecraft:bamboo_button", - "id": -511 - }, - { - "name": "minecraft:bamboo_chest_raft", - "id": 663 - }, - { - "name": "minecraft:bamboo_door", - "id": -517 - }, - { - "name": "minecraft:bamboo_double_slab", - "id": -521 - }, - { - "name": "minecraft:bamboo_fence", - "id": -515 - }, - { - "name": "minecraft:bamboo_fence_gate", - "id": -516 - }, - { - "name": "minecraft:bamboo_hanging_sign", - "id": -522 - }, - { - "name": "minecraft:bamboo_mosaic", - "id": -509 - }, - { - "name": "minecraft:bamboo_mosaic_double_slab", - "id": -525 - }, - { - "name": "minecraft:bamboo_mosaic_slab", - "id": -524 - }, - { - "name": "minecraft:bamboo_mosaic_stairs", - "id": -523 - }, - { - "name": "minecraft:bamboo_planks", - "id": -510 - }, - { - "name": "minecraft:bamboo_pressure_plate", - "id": -514 - }, - { - "name": "minecraft:bamboo_raft", - "id": 662 - }, - { - "name": "minecraft:bamboo_sapling", - "id": -164 - }, - { - "name": "minecraft:bamboo_sign", - "id": 661 - }, - { - "name": "minecraft:bamboo_slab", - "id": -513 - }, - { - "name": "minecraft:bamboo_stairs", - "id": -512 - }, - { - "name": "minecraft:bamboo_standing_sign", - "id": -518 - }, - { - "name": "minecraft:bamboo_trapdoor", - "id": -520 - }, - { - "name": "minecraft:bamboo_wall_sign", - "id": -519 - }, - { - "name": "minecraft:banner", - "id": 576 - }, - { - "name": "minecraft:banner_pattern", - "id": 725 - }, - { - "name": "minecraft:barrel", - "id": -203 - }, - { - "name": "minecraft:barrier", - "id": -161 - }, - { - "name": "minecraft:basalt", - "id": -234 - }, - { - "name": "minecraft:bat_spawn_egg", - "id": 456 - }, - { - "name": "minecraft:beacon", - "id": 138 - }, - { - "name": "minecraft:bed", - "id": 421 - }, - { - "name": "minecraft:bedrock", - "id": 7 - }, - { - "name": "minecraft:bee_nest", - "id": -218 - }, - { - "name": "minecraft:bee_spawn_egg", - "id": 497 - }, - { - "name": "minecraft:beef", - "id": 274 - }, - { - "name": "minecraft:beehive", - "id": -219 - }, - { - "name": "minecraft:beetroot", - "id": 286 - }, - { - "name": "minecraft:beetroot_seeds", - "id": 296 - }, - { - "name": "minecraft:beetroot_soup", - "id": 287 - }, - { - "name": "minecraft:bell", - "id": -206 - }, - { - "name": "minecraft:big_dripleaf", - "id": -323 - }, - { - "name": "minecraft:birch_boat", - "id": 379 - }, - { - "name": "minecraft:birch_button", - "id": -141 - }, - { - "name": "minecraft:birch_chest_boat", - "id": 648 - }, - { - "name": "minecraft:birch_door", - "id": 563 - }, - { - "name": "minecraft:birch_fence", - "id": -576 - }, - { - "name": "minecraft:birch_fence_gate", - "id": 184 - }, - { - "name": "minecraft:birch_hanging_sign", - "id": -502 - }, - { - "name": "minecraft:birch_log", - "id": -570 - }, - { - "name": "minecraft:birch_planks", - "id": -740 - }, - { - "name": "minecraft:birch_pressure_plate", - "id": -151 - }, - { - "name": "minecraft:birch_sign", - "id": 586 - }, - { - "name": "minecraft:birch_stairs", - "id": 135 - }, - { - "name": "minecraft:birch_standing_sign", - "id": -186 - }, - { - "name": "minecraft:birch_trapdoor", - "id": -146 - }, - { - "name": "minecraft:birch_wall_sign", - "id": -187 - }, - { - "name": "minecraft:black_candle", - "id": -428 - }, - { - "name": "minecraft:black_candle_cake", - "id": -445 - }, - { - "name": "minecraft:black_carpet", - "id": -611 - }, - { - "name": "minecraft:black_concrete", - "id": -642 - }, - { - "name": "minecraft:black_concrete_powder", - "id": -723 - }, - { - "name": "minecraft:black_dye", - "id": 398 - }, - { - "name": "minecraft:black_glazed_terracotta", - "id": 235 - }, - { - "name": "minecraft:black_shulker_box", - "id": -627 - }, - { - "name": "minecraft:black_stained_glass", - "id": -687 - }, - { - "name": "minecraft:black_stained_glass_pane", - "id": -657 - }, - { - "name": "minecraft:black_terracotta", - "id": -738 - }, - { - "name": "minecraft:black_wool", - "id": -554 - }, - { - "name": "minecraft:blackstone", - "id": -273 - }, - { - "name": "minecraft:blackstone_double_slab", - "id": -283 - }, - { - "name": "minecraft:blackstone_slab", - "id": -282 - }, - { - "name": "minecraft:blackstone_stairs", - "id": -276 - }, - { - "name": "minecraft:blackstone_wall", - "id": -277 - }, - { - "name": "minecraft:blade_pottery_sherd", - "id": 668 - }, - { - "name": "minecraft:blast_furnace", - "id": -196 - }, - { - "name": "minecraft:blaze_powder", - "id": 432 - }, - { - "name": "minecraft:blaze_rod", - "id": 426 - }, - { - "name": "minecraft:blaze_spawn_egg", - "id": 459 - }, - { - "name": "minecraft:bleach", - "id": 605 - }, - { - "name": "minecraft:blue_candle", - "id": -424 - }, - { - "name": "minecraft:blue_candle_cake", - "id": -441 - }, - { - "name": "minecraft:blue_carpet", - "id": -607 - }, - { - "name": "minecraft:blue_concrete", - "id": -638 - }, - { - "name": "minecraft:blue_concrete_powder", - "id": -719 - }, - { - "name": "minecraft:blue_dye", - "id": 402 - }, - { - "name": "minecraft:blue_glazed_terracotta", - "id": 231 - }, - { - "name": "minecraft:blue_ice", - "id": -11 - }, - { - "name": "minecraft:blue_shulker_box", - "id": -623 - }, - { - "name": "minecraft:blue_stained_glass", - "id": -683 - }, - { - "name": "minecraft:blue_stained_glass_pane", - "id": -653 - }, - { - "name": "minecraft:blue_terracotta", - "id": -734 - }, - { - "name": "minecraft:blue_wool", - "id": -563 - }, - { - "name": "minecraft:boat", - "id": 723 - }, - { - "name": "minecraft:bone", - "id": 418 - }, - { - "name": "minecraft:bone_block", - "id": 216 - }, - { - "name": "minecraft:bone_meal", - "id": 414 - }, - { - "name": "minecraft:book", - "id": 390 - }, - { - "name": "minecraft:bookshelf", - "id": 47 - }, - { - "name": "minecraft:border_block", - "id": 212 - }, - { - "name": "minecraft:bordure_indented_banner_pattern", - "id": 595 - }, - { - "name": "minecraft:bow", - "id": 303 - }, - { - "name": "minecraft:bowl", - "id": 324 - }, - { - "name": "minecraft:brain_coral", - "id": -581 - }, - { - "name": "minecraft:bread", - "id": 262 - }, - { - "name": "minecraft:breeze_spawn_egg", - "id": 504 - }, - { - "name": "minecraft:brewer_pottery_sherd", - "id": 669 - }, - { - "name": "minecraft:brewing_stand", - "id": 434 - }, - { - "name": "minecraft:brick", - "id": 386 - }, - { - "name": "minecraft:brick_block", - "id": 45 - }, - { - "name": "minecraft:brick_stairs", - "id": 108 - }, - { - "name": "minecraft:brown_candle", - "id": -425 - }, - { - "name": "minecraft:brown_candle_cake", - "id": -442 - }, - { - "name": "minecraft:brown_carpet", - "id": -608 - }, - { - "name": "minecraft:brown_concrete", - "id": -639 - }, - { - "name": "minecraft:brown_concrete_powder", - "id": -720 - }, - { - "name": "minecraft:brown_dye", - "id": 401 - }, - { - "name": "minecraft:brown_glazed_terracotta", - "id": 232 - }, - { - "name": "minecraft:brown_mushroom", - "id": 39 - }, - { - "name": "minecraft:brown_mushroom_block", - "id": 99 - }, - { - "name": "minecraft:brown_shulker_box", - "id": -624 - }, - { - "name": "minecraft:brown_stained_glass", - "id": -684 - }, - { - "name": "minecraft:brown_stained_glass_pane", - "id": -654 - }, - { - "name": "minecraft:brown_terracotta", - "id": -735 - }, - { - "name": "minecraft:brown_wool", - "id": -555 - }, - { - "name": "minecraft:brush", - "id": 685 - }, - { - "name": "minecraft:bubble_column", - "id": -160 - }, - { - "name": "minecraft:bubble_coral", - "id": -582 - }, - { - "name": "minecraft:bucket", - "id": 363 - }, - { - "name": "minecraft:budding_amethyst", - "id": -328 - }, - { - "name": "minecraft:burn_pottery_sherd", - "id": 670 - }, - { - "name": "minecraft:cactus", - "id": 81 - }, - { - "name": "minecraft:cake", - "id": 420 - }, - { - "name": "minecraft:calcite", - "id": -326 - }, - { - "name": "minecraft:calibrated_sculk_sensor", - "id": -580 - }, - { - "name": "minecraft:camel_spawn_egg", - "id": 664 - }, - { - "name": "minecraft:camera", - "id": 602 - }, - { - "name": "minecraft:campfire", - "id": 598 - }, - { - "name": "minecraft:candle", - "id": -412 - }, - { - "name": "minecraft:candle_cake", - "id": -429 - }, - { - "name": "minecraft:carpet", - "id": 710 - }, - { - "name": "minecraft:carrot", - "id": 280 - }, - { - "name": "minecraft:carrot_on_a_stick", - "id": 526 - }, - { - "name": "minecraft:carrots", - "id": 141 - }, - { - "name": "minecraft:cartography_table", - "id": -200 - }, - { - "name": "minecraft:carved_pumpkin", - "id": -155 - }, - { - "name": "minecraft:cat_spawn_egg", - "id": 491 - }, - { - "name": "minecraft:cauldron", - "id": 435 - }, - { - "name": "minecraft:cave_spider_spawn_egg", - "id": 460 - }, - { - "name": "minecraft:cave_vines", - "id": -322 - }, - { - "name": "minecraft:cave_vines_body_with_berries", - "id": -375 - }, - { - "name": "minecraft:cave_vines_head_with_berries", - "id": -376 - }, - { - "name": "minecraft:chain", - "id": 628 - }, - { - "name": "minecraft:chain_command_block", - "id": 189 - }, - { - "name": "minecraft:chainmail_boots", - "id": 345 - }, - { - "name": "minecraft:chainmail_chestplate", - "id": 343 - }, - { - "name": "minecraft:chainmail_helmet", - "id": 342 - }, - { - "name": "minecraft:chainmail_leggings", - "id": 344 - }, - { - "name": "minecraft:charcoal", - "id": 306 - }, - { - "name": "minecraft:chemical_heat", - "id": 192 - }, - { - "name": "minecraft:chemistry_table", - "id": 238 - }, - { - "name": "minecraft:cherry_boat", - "id": 658 - }, - { - "name": "minecraft:cherry_button", - "id": -530 - }, - { - "name": "minecraft:cherry_chest_boat", - "id": 659 - }, - { - "name": "minecraft:cherry_door", - "id": -531 - }, - { - "name": "minecraft:cherry_double_slab", - "id": -540 - }, - { - "name": "minecraft:cherry_fence", - "id": -532 - }, - { - "name": "minecraft:cherry_fence_gate", - "id": -533 - }, - { - "name": "minecraft:cherry_hanging_sign", - "id": -534 - }, - { - "name": "minecraft:cherry_leaves", - "id": -548 - }, - { - "name": "minecraft:cherry_log", - "id": -536 - }, - { - "name": "minecraft:cherry_planks", - "id": -537 - }, - { - "name": "minecraft:cherry_pressure_plate", - "id": -538 - }, - { - "name": "minecraft:cherry_sapling", - "id": -547 - }, - { - "name": "minecraft:cherry_sign", - "id": 660 - }, - { - "name": "minecraft:cherry_slab", - "id": -539 - }, - { - "name": "minecraft:cherry_stairs", - "id": -541 - }, - { - "name": "minecraft:cherry_standing_sign", - "id": -542 - }, - { - "name": "minecraft:cherry_trapdoor", - "id": -543 - }, - { - "name": "minecraft:cherry_wall_sign", - "id": -544 - }, - { - "name": "minecraft:cherry_wood", - "id": -546 - }, - { - "name": "minecraft:chest", - "id": 54 - }, - { - "name": "minecraft:chest_boat", - "id": 654 - }, - { - "name": "minecraft:chest_minecart", - "id": 392 - }, - { - "name": "minecraft:chicken", - "id": 276 - }, - { - "name": "minecraft:chicken_spawn_egg", - "id": 438 - }, - { - "name": "minecraft:chiseled_bookshelf", - "id": -526 - }, - { - "name": "minecraft:chiseled_copper", - "id": -760 - }, - { - "name": "minecraft:chiseled_deepslate", - "id": -395 - }, - { - "name": "minecraft:chiseled_nether_bricks", - "id": -302 - }, - { - "name": "minecraft:chiseled_polished_blackstone", - "id": -279 - }, - { - "name": "minecraft:chiseled_tuff", - "id": -753 - }, - { - "name": "minecraft:chiseled_tuff_bricks", - "id": -759 - }, - { - "name": "minecraft:chorus_flower", - "id": 200 - }, - { - "name": "minecraft:chorus_fruit", - "id": 567 - }, - { - "name": "minecraft:chorus_plant", - "id": 240 - }, - { - "name": "minecraft:clay", - "id": 82 - }, - { - "name": "minecraft:clay_ball", - "id": 387 - }, - { - "name": "minecraft:client_request_placeholder_block", - "id": -465 - }, - { - "name": "minecraft:clock", - "id": 396 - }, - { - "name": "minecraft:coal", - "id": 305 - }, - { - "name": "minecraft:coal_block", - "id": 173 - }, - { - "name": "minecraft:coal_ore", - "id": 16 - }, - { - "name": "minecraft:coast_armor_trim_smithing_template", - "id": 689 - }, - { - "name": "minecraft:cobbled_deepslate", - "id": -379 - }, - { - "name": "minecraft:cobbled_deepslate_double_slab", - "id": -396 - }, - { - "name": "minecraft:cobbled_deepslate_slab", - "id": -380 - }, - { - "name": "minecraft:cobbled_deepslate_stairs", - "id": -381 - }, - { - "name": "minecraft:cobbled_deepslate_wall", - "id": -382 - }, - { - "name": "minecraft:cobblestone", - "id": 4 - }, - { - "name": "minecraft:cobblestone_wall", - "id": 139 - }, - { - "name": "minecraft:cocoa", - "id": 127 - }, - { - "name": "minecraft:cocoa_beans", - "id": 415 - }, - { - "name": "minecraft:cod", - "id": 265 - }, - { - "name": "minecraft:cod_bucket", - "id": 367 - }, - { - "name": "minecraft:cod_spawn_egg", - "id": 483 - }, - { - "name": "minecraft:colored_torch_bp", - "id": 204 - }, - { - "name": "minecraft:colored_torch_rg", - "id": 202 - }, - { - "name": "minecraft:command_block", - "id": 137 - }, - { - "name": "minecraft:command_block_minecart", - "id": 572 - }, - { - "name": "minecraft:comparator", - "id": 531 - }, - { - "name": "minecraft:compass", - "id": 394 - }, - { - "name": "minecraft:composter", - "id": -213 - }, - { - "name": "minecraft:compound", - "id": 603 - }, - { - "name": "minecraft:concrete", - "id": 716 - }, - { - "name": "minecraft:concrete_powder", - "id": 717 - }, - { - "name": "minecraft:conduit", - "id": -157 - }, - { - "name": "minecraft:cooked_beef", - "id": 275 - }, - { - "name": "minecraft:cooked_chicken", - "id": 277 - }, - { - "name": "minecraft:cooked_cod", - "id": 269 - }, - { - "name": "minecraft:cooked_mutton", - "id": 560 - }, - { - "name": "minecraft:cooked_porkchop", - "id": 264 - }, - { - "name": "minecraft:cooked_rabbit", - "id": 290 - }, - { - "name": "minecraft:cooked_salmon", - "id": 270 - }, - { - "name": "minecraft:cookie", - "id": 272 - }, - { - "name": "minecraft:copper_block", - "id": -340 - }, - { - "name": "minecraft:copper_bulb", - "id": -776 - }, - { - "name": "minecraft:copper_door", - "id": -784 - }, - { - "name": "minecraft:copper_grate", - "id": -768 - }, - { - "name": "minecraft:copper_ingot", - "id": 513 - }, - { - "name": "minecraft:copper_ore", - "id": -311 - }, - { - "name": "minecraft:copper_trapdoor", - "id": -792 - }, - { - "name": "minecraft:coral", - "id": 714 - }, - { - "name": "minecraft:coral_block", - "id": -132 - }, - { - "name": "minecraft:coral_fan", - "id": -133 - }, - { - "name": "minecraft:coral_fan_dead", - "id": -134 - }, - { - "name": "minecraft:coral_fan_hang", - "id": -135 - }, - { - "name": "minecraft:coral_fan_hang2", - "id": -136 - }, - { - "name": "minecraft:coral_fan_hang3", - "id": -137 - }, - { - "name": "minecraft:cow_spawn_egg", - "id": 439 - }, - { - "name": "minecraft:cracked_deepslate_bricks", - "id": -410 - }, - { - "name": "minecraft:cracked_deepslate_tiles", - "id": -409 - }, - { - "name": "minecraft:cracked_nether_bricks", - "id": -303 - }, - { - "name": "minecraft:cracked_polished_blackstone_bricks", - "id": -280 - }, - { - "name": "minecraft:crafter", - "id": -313 - }, - { - "name": "minecraft:crafting_table", - "id": 58 - }, - { - "name": "minecraft:creeper_banner_pattern", - "id": 591 - }, - { - "name": "minecraft:creeper_spawn_egg", - "id": 444 - }, - { - "name": "minecraft:crimson_button", - "id": -260 - }, - { - "name": "minecraft:crimson_door", - "id": 625 - }, - { - "name": "minecraft:crimson_double_slab", - "id": -266 - }, - { - "name": "minecraft:crimson_fence", - "id": -256 - }, - { - "name": "minecraft:crimson_fence_gate", - "id": -258 - }, - { - "name": "minecraft:crimson_fungus", - "id": -228 - }, - { - "name": "minecraft:crimson_hanging_sign", - "id": -506 - }, - { - "name": "minecraft:crimson_hyphae", - "id": -299 - }, - { - "name": "minecraft:crimson_nylium", - "id": -232 - }, - { - "name": "minecraft:crimson_planks", - "id": -242 - }, - { - "name": "minecraft:crimson_pressure_plate", - "id": -262 - }, - { - "name": "minecraft:crimson_roots", - "id": -223 - }, - { - "name": "minecraft:crimson_sign", - "id": 623 - }, - { - "name": "minecraft:crimson_slab", - "id": -264 - }, - { - "name": "minecraft:crimson_stairs", - "id": -254 - }, - { - "name": "minecraft:crimson_standing_sign", - "id": -250 - }, - { - "name": "minecraft:crimson_stem", - "id": -225 - }, - { - "name": "minecraft:crimson_trapdoor", - "id": -246 - }, - { - "name": "minecraft:crimson_wall_sign", - "id": -252 - }, - { - "name": "minecraft:crossbow", - "id": 584 - }, - { - "name": "minecraft:crying_obsidian", - "id": -289 - }, - { - "name": "minecraft:cut_copper", - "id": -347 - }, - { - "name": "minecraft:cut_copper_slab", - "id": -361 - }, - { - "name": "minecraft:cut_copper_stairs", - "id": -354 - }, - { - "name": "minecraft:cyan_candle", - "id": -422 - }, - { - "name": "minecraft:cyan_candle_cake", - "id": -439 - }, - { - "name": "minecraft:cyan_carpet", - "id": -605 - }, - { - "name": "minecraft:cyan_concrete", - "id": -636 - }, - { - "name": "minecraft:cyan_concrete_powder", - "id": -717 - }, - { - "name": "minecraft:cyan_dye", - "id": 404 - }, - { - "name": "minecraft:cyan_glazed_terracotta", - "id": 229 - }, - { - "name": "minecraft:cyan_shulker_box", - "id": -621 - }, - { - "name": "minecraft:cyan_stained_glass", - "id": -681 - }, - { - "name": "minecraft:cyan_stained_glass_pane", - "id": -651 - }, - { - "name": "minecraft:cyan_terracotta", - "id": -732 - }, - { - "name": "minecraft:cyan_wool", - "id": -561 - }, - { - "name": "minecraft:danger_pottery_sherd", - "id": 671 - }, - { - "name": "minecraft:dark_oak_boat", - "id": 383 - }, - { - "name": "minecraft:dark_oak_button", - "id": -142 - }, - { - "name": "minecraft:dark_oak_chest_boat", - "id": 652 - }, - { - "name": "minecraft:dark_oak_door", - "id": 566 - }, - { - "name": "minecraft:dark_oak_fence", - "id": -577 - }, - { - "name": "minecraft:dark_oak_fence_gate", - "id": 186 - }, - { - "name": "minecraft:dark_oak_hanging_sign", - "id": -505 - }, - { - "name": "minecraft:dark_oak_log", - "id": -572 - }, - { - "name": "minecraft:dark_oak_planks", - "id": -743 - }, - { - "name": "minecraft:dark_oak_pressure_plate", - "id": -152 - }, - { - "name": "minecraft:dark_oak_sign", - "id": 589 - }, - { - "name": "minecraft:dark_oak_stairs", - "id": 164 - }, - { - "name": "minecraft:dark_oak_trapdoor", - "id": -147 - }, - { - "name": "minecraft:dark_prismarine_stairs", - "id": -3 - }, - { - "name": "minecraft:darkoak_standing_sign", - "id": -192 - }, - { - "name": "minecraft:darkoak_wall_sign", - "id": -193 - }, - { - "name": "minecraft:daylight_detector", - "id": 151 - }, - { - "name": "minecraft:daylight_detector_inverted", - "id": 178 - }, - { - "name": "minecraft:dead_brain_coral", - "id": -586 - }, - { - "name": "minecraft:dead_bubble_coral", - "id": -587 - }, - { - "name": "minecraft:dead_fire_coral", - "id": -588 - }, - { - "name": "minecraft:dead_horn_coral", - "id": -589 - }, - { - "name": "minecraft:dead_tube_coral", - "id": -585 - }, - { - "name": "minecraft:deadbush", - "id": 32 - }, - { - "name": "minecraft:decorated_pot", - "id": -551 - }, - { - "name": "minecraft:deepslate", - "id": -378 - }, - { - "name": "minecraft:deepslate_brick_double_slab", - "id": -399 - }, - { - "name": "minecraft:deepslate_brick_slab", - "id": -392 - }, - { - "name": "minecraft:deepslate_brick_stairs", - "id": -393 - }, - { - "name": "minecraft:deepslate_brick_wall", - "id": -394 - }, - { - "name": "minecraft:deepslate_bricks", - "id": -391 - }, - { - "name": "minecraft:deepslate_coal_ore", - "id": -406 - }, - { - "name": "minecraft:deepslate_copper_ore", - "id": -408 - }, - { - "name": "minecraft:deepslate_diamond_ore", - "id": -405 - }, - { - "name": "minecraft:deepslate_emerald_ore", - "id": -407 - }, - { - "name": "minecraft:deepslate_gold_ore", - "id": -402 - }, - { - "name": "minecraft:deepslate_iron_ore", - "id": -401 - }, - { - "name": "minecraft:deepslate_lapis_ore", - "id": -400 - }, - { - "name": "minecraft:deepslate_redstone_ore", - "id": -403 - }, - { - "name": "minecraft:deepslate_tile_double_slab", - "id": -398 - }, - { - "name": "minecraft:deepslate_tile_slab", - "id": -388 - }, - { - "name": "minecraft:deepslate_tile_stairs", - "id": -389 - }, - { - "name": "minecraft:deepslate_tile_wall", - "id": -390 - }, - { - "name": "minecraft:deepslate_tiles", - "id": -387 - }, - { - "name": "minecraft:deny", - "id": 211 - }, - { - "name": "minecraft:detector_rail", - "id": 28 - }, - { - "name": "minecraft:diamond", - "id": 307 - }, - { - "name": "minecraft:diamond_axe", - "id": 322 - }, - { - "name": "minecraft:diamond_block", - "id": 57 - }, - { - "name": "minecraft:diamond_boots", - "id": 353 - }, - { - "name": "minecraft:diamond_chestplate", - "id": 351 - }, - { - "name": "minecraft:diamond_helmet", - "id": 350 - }, - { - "name": "minecraft:diamond_hoe", - "id": 335 - }, - { - "name": "minecraft:diamond_horse_armor", - "id": 542 - }, - { - "name": "minecraft:diamond_leggings", - "id": 352 - }, - { - "name": "minecraft:diamond_ore", - "id": 56 - }, - { - "name": "minecraft:diamond_pickaxe", - "id": 321 - }, - { - "name": "minecraft:diamond_shovel", - "id": 320 - }, - { - "name": "minecraft:diamond_sword", - "id": 319 - }, - { - "name": "minecraft:diorite", - "id": -592 - }, - { - "name": "minecraft:diorite_stairs", - "id": -170 - }, - { - "name": "minecraft:dirt", - "id": 3 - }, - { - "name": "minecraft:dirt_with_roots", - "id": -318 - }, - { - "name": "minecraft:disc_fragment_5", - "id": 646 - }, - { - "name": "minecraft:dispenser", - "id": 23 - }, - { - "name": "minecraft:dolphin_spawn_egg", - "id": 487 - }, - { - "name": "minecraft:donkey_spawn_egg", - "id": 468 - }, - { - "name": "minecraft:double_cut_copper_slab", - "id": -368 - }, - { - "name": "minecraft:double_plant", - "id": 175 - }, - { - "name": "minecraft:double_stone_block_slab", - "id": 43 - }, - { - "name": "minecraft:double_stone_block_slab2", - "id": 181 - }, - { - "name": "minecraft:double_stone_block_slab3", - "id": -167 - }, - { - "name": "minecraft:double_stone_block_slab4", - "id": -168 - }, - { - "name": "minecraft:double_wooden_slab", - "id": 157 - }, - { - "name": "minecraft:dragon_breath", - "id": 569 - }, - { - "name": "minecraft:dragon_egg", - "id": 122 - }, - { - "name": "minecraft:dried_kelp", - "id": 271 - }, - { - "name": "minecraft:dried_kelp_block", - "id": -139 - }, - { - "name": "minecraft:dripstone_block", - "id": -317 - }, - { - "name": "minecraft:dropper", - "id": 125 - }, - { - "name": "minecraft:drowned_spawn_egg", - "id": 486 - }, - { - "name": "minecraft:dune_armor_trim_smithing_template", - "id": 688 - }, - { - "name": "minecraft:dye", - "id": 724 - }, - { - "name": "minecraft:echo_shard", - "id": 656 - }, - { - "name": "minecraft:egg", - "id": 393 - }, - { - "name": "minecraft:elder_guardian_spawn_egg", - "id": 474 - }, - { - "name": "minecraft:element_0", - "id": 36 - }, - { - "name": "minecraft:element_1", - "id": -12 - }, - { - "name": "minecraft:element_10", - "id": -21 - }, - { - "name": "minecraft:element_100", - "id": -111 - }, - { - "name": "minecraft:element_101", - "id": -112 - }, - { - "name": "minecraft:element_102", - "id": -113 - }, - { - "name": "minecraft:element_103", - "id": -114 - }, - { - "name": "minecraft:element_104", - "id": -115 - }, - { - "name": "minecraft:element_105", - "id": -116 - }, - { - "name": "minecraft:element_106", - "id": -117 - }, - { - "name": "minecraft:element_107", - "id": -118 - }, - { - "name": "minecraft:element_108", - "id": -119 - }, - { - "name": "minecraft:element_109", - "id": -120 - }, - { - "name": "minecraft:element_11", - "id": -22 - }, - { - "name": "minecraft:element_110", - "id": -121 - }, - { - "name": "minecraft:element_111", - "id": -122 - }, - { - "name": "minecraft:element_112", - "id": -123 - }, - { - "name": "minecraft:element_113", - "id": -124 - }, - { - "name": "minecraft:element_114", - "id": -125 - }, - { - "name": "minecraft:element_115", - "id": -126 - }, - { - "name": "minecraft:element_116", - "id": -127 - }, - { - "name": "minecraft:element_117", - "id": -128 - }, - { - "name": "minecraft:element_118", - "id": -129 - }, - { - "name": "minecraft:element_12", - "id": -23 - }, - { - "name": "minecraft:element_13", - "id": -24 - }, - { - "name": "minecraft:element_14", - "id": -25 - }, - { - "name": "minecraft:element_15", - "id": -26 - }, - { - "name": "minecraft:element_16", - "id": -27 - }, - { - "name": "minecraft:element_17", - "id": -28 - }, - { - "name": "minecraft:element_18", - "id": -29 - }, - { - "name": "minecraft:element_19", - "id": -30 - }, - { - "name": "minecraft:element_2", - "id": -13 - }, - { - "name": "minecraft:element_20", - "id": -31 - }, - { - "name": "minecraft:element_21", - "id": -32 - }, - { - "name": "minecraft:element_22", - "id": -33 - }, - { - "name": "minecraft:element_23", - "id": -34 - }, - { - "name": "minecraft:element_24", - "id": -35 - }, - { - "name": "minecraft:element_25", - "id": -36 - }, - { - "name": "minecraft:element_26", - "id": -37 - }, - { - "name": "minecraft:element_27", - "id": -38 - }, - { - "name": "minecraft:element_28", - "id": -39 - }, - { - "name": "minecraft:element_29", - "id": -40 - }, - { - "name": "minecraft:element_3", - "id": -14 - }, - { - "name": "minecraft:element_30", - "id": -41 - }, - { - "name": "minecraft:element_31", - "id": -42 - }, - { - "name": "minecraft:element_32", - "id": -43 - }, - { - "name": "minecraft:element_33", - "id": -44 - }, - { - "name": "minecraft:element_34", - "id": -45 - }, - { - "name": "minecraft:element_35", - "id": -46 - }, - { - "name": "minecraft:element_36", - "id": -47 - }, - { - "name": "minecraft:element_37", - "id": -48 - }, - { - "name": "minecraft:element_38", - "id": -49 - }, - { - "name": "minecraft:element_39", - "id": -50 - }, - { - "name": "minecraft:element_4", - "id": -15 - }, - { - "name": "minecraft:element_40", - "id": -51 - }, - { - "name": "minecraft:element_41", - "id": -52 - }, - { - "name": "minecraft:element_42", - "id": -53 - }, - { - "name": "minecraft:element_43", - "id": -54 - }, - { - "name": "minecraft:element_44", - "id": -55 - }, - { - "name": "minecraft:element_45", - "id": -56 - }, - { - "name": "minecraft:element_46", - "id": -57 - }, - { - "name": "minecraft:element_47", - "id": -58 - }, - { - "name": "minecraft:element_48", - "id": -59 - }, - { - "name": "minecraft:element_49", - "id": -60 - }, - { - "name": "minecraft:element_5", - "id": -16 - }, - { - "name": "minecraft:element_50", - "id": -61 - }, - { - "name": "minecraft:element_51", - "id": -62 - }, - { - "name": "minecraft:element_52", - "id": -63 - }, - { - "name": "minecraft:element_53", - "id": -64 - }, - { - "name": "minecraft:element_54", - "id": -65 - }, - { - "name": "minecraft:element_55", - "id": -66 - }, - { - "name": "minecraft:element_56", - "id": -67 - }, - { - "name": "minecraft:element_57", - "id": -68 - }, - { - "name": "minecraft:element_58", - "id": -69 - }, - { - "name": "minecraft:element_59", - "id": -70 - }, - { - "name": "minecraft:element_6", - "id": -17 - }, - { - "name": "minecraft:element_60", - "id": -71 - }, - { - "name": "minecraft:element_61", - "id": -72 - }, - { - "name": "minecraft:element_62", - "id": -73 - }, - { - "name": "minecraft:element_63", - "id": -74 - }, - { - "name": "minecraft:element_64", - "id": -75 - }, - { - "name": "minecraft:element_65", - "id": -76 - }, - { - "name": "minecraft:element_66", - "id": -77 - }, - { - "name": "minecraft:element_67", - "id": -78 - }, - { - "name": "minecraft:element_68", - "id": -79 - }, - { - "name": "minecraft:element_69", - "id": -80 - }, - { - "name": "minecraft:element_7", - "id": -18 - }, - { - "name": "minecraft:element_70", - "id": -81 - }, - { - "name": "minecraft:element_71", - "id": -82 - }, - { - "name": "minecraft:element_72", - "id": -83 - }, - { - "name": "minecraft:element_73", - "id": -84 - }, - { - "name": "minecraft:element_74", - "id": -85 - }, - { - "name": "minecraft:element_75", - "id": -86 - }, - { - "name": "minecraft:element_76", - "id": -87 - }, - { - "name": "minecraft:element_77", - "id": -88 - }, - { - "name": "minecraft:element_78", - "id": -89 - }, - { - "name": "minecraft:element_79", - "id": -90 - }, - { - "name": "minecraft:element_8", - "id": -19 - }, - { - "name": "minecraft:element_80", - "id": -91 - }, - { - "name": "minecraft:element_81", - "id": -92 - }, - { - "name": "minecraft:element_82", - "id": -93 - }, - { - "name": "minecraft:element_83", - "id": -94 - }, - { - "name": "minecraft:element_84", - "id": -95 - }, - { - "name": "minecraft:element_85", - "id": -96 - }, - { - "name": "minecraft:element_86", - "id": -97 - }, - { - "name": "minecraft:element_87", - "id": -98 - }, - { - "name": "minecraft:element_88", - "id": -99 - }, - { - "name": "minecraft:element_89", - "id": -100 - }, - { - "name": "minecraft:element_9", - "id": -20 - }, - { - "name": "minecraft:element_90", - "id": -101 - }, - { - "name": "minecraft:element_91", - "id": -102 - }, - { - "name": "minecraft:element_92", - "id": -103 - }, - { - "name": "minecraft:element_93", - "id": -104 - }, - { - "name": "minecraft:element_94", - "id": -105 - }, - { - "name": "minecraft:element_95", - "id": -106 - }, - { - "name": "minecraft:element_96", - "id": -107 - }, - { - "name": "minecraft:element_97", - "id": -108 - }, - { - "name": "minecraft:element_98", - "id": -109 - }, - { - "name": "minecraft:element_99", - "id": -110 - }, - { - "name": "minecraft:elytra", - "id": 573 - }, - { - "name": "minecraft:emerald", - "id": 521 - }, - { - "name": "minecraft:emerald_block", - "id": 133 - }, - { - "name": "minecraft:emerald_ore", - "id": 129 - }, - { - "name": "minecraft:empty_map", - "id": 524 - }, - { - "name": "minecraft:enchanted_book", - "id": 530 - }, - { - "name": "minecraft:enchanted_golden_apple", - "id": 260 - }, - { - "name": "minecraft:enchanting_table", - "id": 116 - }, - { - "name": "minecraft:end_brick_stairs", - "id": -178 - }, - { - "name": "minecraft:end_bricks", - "id": 206 - }, - { - "name": "minecraft:end_crystal", - "id": 727 - }, - { - "name": "minecraft:end_gateway", - "id": 209 - }, - { - "name": "minecraft:end_portal", - "id": 119 - }, - { - "name": "minecraft:end_portal_frame", - "id": 120 - }, - { - "name": "minecraft:end_rod", - "id": 208 - }, - { - "name": "minecraft:end_stone", - "id": 121 - }, - { - "name": "minecraft:ender_chest", - "id": 130 - }, - { - "name": "minecraft:ender_dragon_spawn_egg", - "id": 510 - }, - { - "name": "minecraft:ender_eye", - "id": 436 - }, - { - "name": "minecraft:ender_pearl", - "id": 425 - }, - { - "name": "minecraft:enderman_spawn_egg", - "id": 445 - }, - { - "name": "minecraft:endermite_spawn_egg", - "id": 463 - }, - { - "name": "minecraft:evoker_spawn_egg", - "id": 478 - }, - { - "name": "minecraft:experience_bottle", - "id": 517 - }, - { - "name": "minecraft:explorer_pottery_sherd", - "id": 672 - }, - { - "name": "minecraft:exposed_chiseled_copper", - "id": -761 - }, - { - "name": "minecraft:exposed_copper", - "id": -341 - }, - { - "name": "minecraft:exposed_copper_bulb", - "id": -777 - }, - { - "name": "minecraft:exposed_copper_door", - "id": -785 - }, - { - "name": "minecraft:exposed_copper_grate", - "id": -769 - }, - { - "name": "minecraft:exposed_copper_trapdoor", - "id": -793 - }, - { - "name": "minecraft:exposed_cut_copper", - "id": -348 - }, - { - "name": "minecraft:exposed_cut_copper_slab", - "id": -362 - }, - { - "name": "minecraft:exposed_cut_copper_stairs", - "id": -355 - }, - { - "name": "minecraft:exposed_double_cut_copper_slab", - "id": -369 - }, - { - "name": "minecraft:eye_armor_trim_smithing_template", - "id": 692 - }, - { - "name": "minecraft:farmland", - "id": 60 - }, - { - "name": "minecraft:feather", - "id": 330 - }, - { - "name": "minecraft:fence", - "id": 712 - }, - { - "name": "minecraft:fence_gate", - "id": 107 - }, - { - "name": "minecraft:fermented_spider_eye", - "id": 431 - }, - { - "name": "minecraft:field_masoned_banner_pattern", - "id": 594 - }, - { - "name": "minecraft:filled_map", - "id": 423 - }, - { - "name": "minecraft:fire", - "id": 51 - }, - { - "name": "minecraft:fire_charge", - "id": 518 - }, - { - "name": "minecraft:fire_coral", - "id": -583 - }, - { - "name": "minecraft:firework_rocket", - "id": 528 - }, - { - "name": "minecraft:firework_star", - "id": 529 - }, - { - "name": "minecraft:fishing_rod", - "id": 395 - }, - { - "name": "minecraft:fletching_table", - "id": -201 - }, - { - "name": "minecraft:flint", - "id": 359 - }, - { - "name": "minecraft:flint_and_steel", - "id": 302 - }, - { - "name": "minecraft:flower_banner_pattern", - "id": 590 - }, - { - "name": "minecraft:flower_pot", - "id": 523 - }, - { - "name": "minecraft:flowering_azalea", - "id": -338 - }, - { - "name": "minecraft:flowing_lava", - "id": 10 - }, - { - "name": "minecraft:flowing_water", - "id": 8 - }, - { - "name": "minecraft:fox_spawn_egg", - "id": 493 - }, - { - "name": "minecraft:frame", - "id": 522 - }, - { - "name": "minecraft:friend_pottery_sherd", - "id": 673 - }, - { - "name": "minecraft:frog_spawn", - "id": -468 - }, - { - "name": "minecraft:frog_spawn_egg", - "id": 637 - }, - { - "name": "minecraft:frosted_ice", - "id": 207 - }, - { - "name": "minecraft:furnace", - "id": 61 - }, - { - "name": "minecraft:ghast_spawn_egg", - "id": 457 - }, - { - "name": "minecraft:ghast_tear", - "id": 427 - }, - { - "name": "minecraft:gilded_blackstone", - "id": -281 - }, - { - "name": "minecraft:glass", - "id": 20 - }, - { - "name": "minecraft:glass_bottle", - "id": 430 - }, - { - "name": "minecraft:glass_pane", - "id": 102 - }, - { - "name": "minecraft:glistering_melon_slice", - "id": 437 - }, - { - "name": "minecraft:globe_banner_pattern", - "id": 597 - }, - { - "name": "minecraft:glow_berries", - "id": 728 - }, - { - "name": "minecraft:glow_frame", - "id": 632 - }, - { - "name": "minecraft:glow_ink_sac", - "id": 512 - }, - { - "name": "minecraft:glow_lichen", - "id": -411 - }, - { - "name": "minecraft:glow_squid_spawn_egg", - "id": 507 - }, - { - "name": "minecraft:glow_stick", - "id": 610 - }, - { - "name": "minecraft:glowingobsidian", - "id": 246 - }, - { - "name": "minecraft:glowstone", - "id": 89 - }, - { - "name": "minecraft:glowstone_dust", - "id": 397 - }, - { - "name": "minecraft:goat_horn", - "id": 636 - }, - { - "name": "minecraft:goat_spawn_egg", - "id": 506 - }, - { - "name": "minecraft:gold_block", - "id": 41 - }, - { - "name": "minecraft:gold_ingot", - "id": 309 - }, - { - "name": "minecraft:gold_nugget", - "id": 428 - }, - { - "name": "minecraft:gold_ore", - "id": 14 - }, - { - "name": "minecraft:golden_apple", - "id": 259 - }, - { - "name": "minecraft:golden_axe", - "id": 328 - }, - { - "name": "minecraft:golden_boots", - "id": 357 - }, - { - "name": "minecraft:golden_carrot", - "id": 284 - }, - { - "name": "minecraft:golden_chestplate", - "id": 355 - }, - { - "name": "minecraft:golden_helmet", - "id": 354 - }, - { - "name": "minecraft:golden_hoe", - "id": 336 - }, - { - "name": "minecraft:golden_horse_armor", - "id": 541 - }, - { - "name": "minecraft:golden_leggings", - "id": 356 - }, - { - "name": "minecraft:golden_pickaxe", - "id": 327 - }, - { - "name": "minecraft:golden_rail", - "id": 27 - }, - { - "name": "minecraft:golden_shovel", - "id": 326 - }, - { - "name": "minecraft:golden_sword", - "id": 325 - }, - { - "name": "minecraft:granite", - "id": -590 - }, - { - "name": "minecraft:granite_stairs", - "id": -169 - }, - { - "name": "minecraft:grass", - "id": 2 - }, - { - "name": "minecraft:grass_path", - "id": 198 - }, - { - "name": "minecraft:gravel", - "id": 13 - }, - { - "name": "minecraft:gray_candle", - "id": -420 - }, - { - "name": "minecraft:gray_candle_cake", - "id": -437 - }, - { - "name": "minecraft:gray_carpet", - "id": -603 - }, - { - "name": "minecraft:gray_concrete", - "id": -634 - }, - { - "name": "minecraft:gray_concrete_powder", - "id": -715 - }, - { - "name": "minecraft:gray_dye", - "id": 406 - }, - { - "name": "minecraft:gray_glazed_terracotta", - "id": 227 - }, - { - "name": "minecraft:gray_shulker_box", - "id": -619 - }, - { - "name": "minecraft:gray_stained_glass", - "id": -679 - }, - { - "name": "minecraft:gray_stained_glass_pane", - "id": -649 - }, - { - "name": "minecraft:gray_terracotta", - "id": -730 - }, - { - "name": "minecraft:gray_wool", - "id": -553 - }, - { - "name": "minecraft:green_candle", - "id": -426 - }, - { - "name": "minecraft:green_candle_cake", - "id": -443 - }, - { - "name": "minecraft:green_carpet", - "id": -609 - }, - { - "name": "minecraft:green_concrete", - "id": -640 - }, - { - "name": "minecraft:green_concrete_powder", - "id": -721 - }, - { - "name": "minecraft:green_dye", - "id": 400 - }, - { - "name": "minecraft:green_glazed_terracotta", - "id": 233 - }, - { - "name": "minecraft:green_shulker_box", - "id": -625 - }, - { - "name": "minecraft:green_stained_glass", - "id": -685 - }, - { - "name": "minecraft:green_stained_glass_pane", - "id": -655 - }, - { - "name": "minecraft:green_terracotta", - "id": -736 - }, - { - "name": "minecraft:green_wool", - "id": -560 - }, - { - "name": "minecraft:grindstone", - "id": -195 - }, - { - "name": "minecraft:guardian_spawn_egg", - "id": 464 - }, - { - "name": "minecraft:gunpowder", - "id": 331 - }, - { - "name": "minecraft:hanging_roots", - "id": -319 - }, - { - "name": "minecraft:hard_black_stained_glass", - "id": -702 - }, - { - "name": "minecraft:hard_black_stained_glass_pane", - "id": -672 - }, - { - "name": "minecraft:hard_blue_stained_glass", - "id": -698 - }, - { - "name": "minecraft:hard_blue_stained_glass_pane", - "id": -668 - }, - { - "name": "minecraft:hard_brown_stained_glass", - "id": -699 - }, - { - "name": "minecraft:hard_brown_stained_glass_pane", - "id": -669 - }, - { - "name": "minecraft:hard_cyan_stained_glass", - "id": -696 - }, - { - "name": "minecraft:hard_cyan_stained_glass_pane", - "id": -666 - }, - { - "name": "minecraft:hard_glass", - "id": 253 - }, - { - "name": "minecraft:hard_glass_pane", - "id": 190 - }, - { - "name": "minecraft:hard_gray_stained_glass", - "id": -694 - }, - { - "name": "minecraft:hard_gray_stained_glass_pane", - "id": -664 - }, - { - "name": "minecraft:hard_green_stained_glass", - "id": -700 - }, - { - "name": "minecraft:hard_green_stained_glass_pane", - "id": -670 - }, - { - "name": "minecraft:hard_light_blue_stained_glass", - "id": -690 - }, - { - "name": "minecraft:hard_light_blue_stained_glass_pane", - "id": -660 - }, - { - "name": "minecraft:hard_light_gray_stained_glass", - "id": -695 - }, - { - "name": "minecraft:hard_light_gray_stained_glass_pane", - "id": -665 - }, - { - "name": "minecraft:hard_lime_stained_glass", - "id": -692 - }, - { - "name": "minecraft:hard_lime_stained_glass_pane", - "id": -662 - }, - { - "name": "minecraft:hard_magenta_stained_glass", - "id": -689 - }, - { - "name": "minecraft:hard_magenta_stained_glass_pane", - "id": -659 - }, - { - "name": "minecraft:hard_orange_stained_glass", - "id": -688 - }, - { - "name": "minecraft:hard_orange_stained_glass_pane", - "id": -658 - }, - { - "name": "minecraft:hard_pink_stained_glass", - "id": -693 - }, - { - "name": "minecraft:hard_pink_stained_glass_pane", - "id": -663 - }, - { - "name": "minecraft:hard_purple_stained_glass", - "id": -697 - }, - { - "name": "minecraft:hard_purple_stained_glass_pane", - "id": -667 - }, - { - "name": "minecraft:hard_red_stained_glass", - "id": -701 - }, - { - "name": "minecraft:hard_red_stained_glass_pane", - "id": -671 - }, - { - "name": "minecraft:hard_stained_glass", - "id": 721 - }, - { - "name": "minecraft:hard_stained_glass_pane", - "id": 722 - }, - { - "name": "minecraft:hard_white_stained_glass", - "id": 254 - }, - { - "name": "minecraft:hard_white_stained_glass_pane", - "id": 191 - }, - { - "name": "minecraft:hard_yellow_stained_glass", - "id": -691 - }, - { - "name": "minecraft:hard_yellow_stained_glass_pane", - "id": -661 - }, - { - "name": "minecraft:hardened_clay", - "id": 172 - }, - { - "name": "minecraft:hay_block", - "id": 170 - }, - { - "name": "minecraft:heart_of_the_sea", - "id": 580 - }, - { - "name": "minecraft:heart_pottery_sherd", - "id": 674 - }, - { - "name": "minecraft:heartbreak_pottery_sherd", - "id": 675 - }, - { - "name": "minecraft:heavy_weighted_pressure_plate", - "id": 148 - }, - { - "name": "minecraft:hoglin_spawn_egg", - "id": 499 - }, - { - "name": "minecraft:honey_block", - "id": -220 - }, - { - "name": "minecraft:honey_bottle", - "id": 601 - }, - { - "name": "minecraft:honeycomb", - "id": 600 - }, - { - "name": "minecraft:honeycomb_block", - "id": -221 - }, - { - "name": "minecraft:hopper", - "id": 536 - }, - { - "name": "minecraft:hopper_minecart", - "id": 535 - }, - { - "name": "minecraft:horn_coral", - "id": -584 - }, - { - "name": "minecraft:horse_spawn_egg", - "id": 461 - }, - { - "name": "minecraft:host_armor_trim_smithing_template", - "id": 702 - }, - { - "name": "minecraft:howl_pottery_sherd", - "id": 676 - }, - { - "name": "minecraft:husk_spawn_egg", - "id": 466 - }, - { - "name": "minecraft:ice", - "id": 79 - }, - { - "name": "minecraft:ice_bomb", - "id": 604 - }, - { - "name": "minecraft:infested_deepslate", - "id": -454 - }, - { - "name": "minecraft:info_update", - "id": 248 - }, - { - "name": "minecraft:info_update2", - "id": 249 - }, - { - "name": "minecraft:ink_sac", - "id": 416 - }, - { - "name": "minecraft:invisible_bedrock", - "id": 95 - }, - { - "name": "minecraft:iron_axe", - "id": 301 - }, - { - "name": "minecraft:iron_bars", - "id": 101 - }, - { - "name": "minecraft:iron_block", - "id": 42 - }, - { - "name": "minecraft:iron_boots", - "id": 349 - }, - { - "name": "minecraft:iron_chestplate", - "id": 347 - }, - { - "name": "minecraft:iron_door", - "id": 375 - }, - { - "name": "minecraft:iron_golem_spawn_egg", - "id": 508 - }, - { - "name": "minecraft:iron_helmet", - "id": 346 - }, - { - "name": "minecraft:iron_hoe", - "id": 334 - }, - { - "name": "minecraft:iron_horse_armor", - "id": 540 - }, - { - "name": "minecraft:iron_ingot", - "id": 308 - }, - { - "name": "minecraft:iron_leggings", - "id": 348 - }, - { - "name": "minecraft:iron_nugget", - "id": 578 - }, - { - "name": "minecraft:iron_ore", - "id": 15 - }, - { - "name": "minecraft:iron_pickaxe", - "id": 300 - }, - { - "name": "minecraft:iron_shovel", - "id": 299 - }, - { - "name": "minecraft:iron_sword", - "id": 310 - }, - { - "name": "minecraft:iron_trapdoor", - "id": 167 - }, - { - "name": "minecraft:item.acacia_door", - "id": 196 - }, - { - "name": "minecraft:item.bed", - "id": 26 - }, - { - "name": "minecraft:item.beetroot", - "id": 244 - }, - { - "name": "minecraft:item.birch_door", - "id": 194 - }, - { - "name": "minecraft:item.brewing_stand", - "id": 117 - }, - { - "name": "minecraft:item.cake", - "id": 92 - }, - { - "name": "minecraft:item.camera", - "id": 242 - }, - { - "name": "minecraft:item.campfire", - "id": -209 - }, - { - "name": "minecraft:item.cauldron", - "id": 118 - }, - { - "name": "minecraft:item.chain", - "id": -286 - }, - { - "name": "minecraft:item.crimson_door", - "id": -244 - }, - { - "name": "minecraft:item.dark_oak_door", - "id": 197 - }, - { - "name": "minecraft:item.flower_pot", - "id": 140 - }, - { - "name": "minecraft:item.frame", - "id": 199 - }, - { - "name": "minecraft:item.glow_frame", - "id": -339 - }, - { - "name": "minecraft:item.hopper", - "id": 154 - }, - { - "name": "minecraft:item.iron_door", - "id": 71 - }, - { - "name": "minecraft:item.jungle_door", - "id": 195 - }, - { - "name": "minecraft:item.kelp", - "id": -138 - }, - { - "name": "minecraft:item.mangrove_door", - "id": -493 - }, - { - "name": "minecraft:item.nether_sprouts", - "id": -238 - }, - { - "name": "minecraft:item.nether_wart", - "id": 115 - }, - { - "name": "minecraft:item.reeds", - "id": 83 - }, - { - "name": "minecraft:item.skull", - "id": 144 - }, - { - "name": "minecraft:item.soul_campfire", - "id": -290 - }, - { - "name": "minecraft:item.spruce_door", - "id": 193 - }, - { - "name": "minecraft:item.warped_door", - "id": -245 - }, - { - "name": "minecraft:item.wheat", - "id": 59 - }, - { - "name": "minecraft:item.wooden_door", - "id": 64 - }, - { - "name": "minecraft:jigsaw", - "id": -211 - }, - { - "name": "minecraft:jukebox", - "id": 84 - }, - { - "name": "minecraft:jungle_boat", - "id": 380 - }, - { - "name": "minecraft:jungle_button", - "id": -143 - }, - { - "name": "minecraft:jungle_chest_boat", - "id": 649 - }, - { - "name": "minecraft:jungle_door", - "id": 564 - }, - { - "name": "minecraft:jungle_fence", - "id": -578 - }, - { - "name": "minecraft:jungle_fence_gate", - "id": 185 - }, - { - "name": "minecraft:jungle_hanging_sign", - "id": -503 - }, - { - "name": "minecraft:jungle_log", - "id": -571 - }, - { - "name": "minecraft:jungle_planks", - "id": -741 - }, - { - "name": "minecraft:jungle_pressure_plate", - "id": -153 - }, - { - "name": "minecraft:jungle_sign", - "id": 587 - }, - { - "name": "minecraft:jungle_stairs", - "id": 136 - }, - { - "name": "minecraft:jungle_standing_sign", - "id": -188 - }, - { - "name": "minecraft:jungle_trapdoor", - "id": -148 - }, - { - "name": "minecraft:jungle_wall_sign", - "id": -189 - }, - { - "name": "minecraft:kelp", - "id": 385 - }, - { - "name": "minecraft:ladder", - "id": 65 - }, - { - "name": "minecraft:lantern", - "id": -208 - }, - { - "name": "minecraft:lapis_block", - "id": 22 - }, - { - "name": "minecraft:lapis_lazuli", - "id": 417 - }, - { - "name": "minecraft:lapis_ore", - "id": 21 - }, - { - "name": "minecraft:large_amethyst_bud", - "id": -330 - }, - { - "name": "minecraft:lava", - "id": 11 - }, - { - "name": "minecraft:lava_bucket", - "id": 366 - }, - { - "name": "minecraft:lead", - "id": 556 - }, - { - "name": "minecraft:leather", - "id": 384 - }, - { - "name": "minecraft:leather_boots", - "id": 341 - }, - { - "name": "minecraft:leather_chestplate", - "id": 339 - }, - { - "name": "minecraft:leather_helmet", - "id": 338 - }, - { - "name": "minecraft:leather_horse_armor", - "id": 539 - }, - { - "name": "minecraft:leather_leggings", - "id": 340 - }, - { - "name": "minecraft:leaves", - "id": 18 - }, - { - "name": "minecraft:leaves2", - "id": 161 - }, - { - "name": "minecraft:lectern", - "id": -194 - }, - { - "name": "minecraft:lever", - "id": 69 - }, - { - "name": "minecraft:light_block", - "id": -215 - }, - { - "name": "minecraft:light_blue_candle", - "id": -416 - }, - { - "name": "minecraft:light_blue_candle_cake", - "id": -433 - }, - { - "name": "minecraft:light_blue_carpet", - "id": -599 - }, - { - "name": "minecraft:light_blue_concrete", - "id": -630 - }, - { - "name": "minecraft:light_blue_concrete_powder", - "id": -711 - }, - { - "name": "minecraft:light_blue_dye", - "id": 410 - }, - { - "name": "minecraft:light_blue_glazed_terracotta", - "id": 223 - }, - { - "name": "minecraft:light_blue_shulker_box", - "id": -615 - }, - { - "name": "minecraft:light_blue_stained_glass", - "id": -675 - }, - { - "name": "minecraft:light_blue_stained_glass_pane", - "id": -645 - }, - { - "name": "minecraft:light_blue_terracotta", - "id": -726 - }, - { - "name": "minecraft:light_blue_wool", - "id": -562 - }, - { - "name": "minecraft:light_gray_candle", - "id": -421 - }, - { - "name": "minecraft:light_gray_candle_cake", - "id": -438 - }, - { - "name": "minecraft:light_gray_carpet", - "id": -604 - }, - { - "name": "minecraft:light_gray_concrete", - "id": -635 - }, - { - "name": "minecraft:light_gray_concrete_powder", - "id": -716 - }, - { - "name": "minecraft:light_gray_dye", - "id": 405 - }, - { - "name": "minecraft:light_gray_shulker_box", - "id": -620 - }, - { - "name": "minecraft:light_gray_stained_glass", - "id": -680 - }, - { - "name": "minecraft:light_gray_stained_glass_pane", - "id": -650 - }, - { - "name": "minecraft:light_gray_terracotta", - "id": -731 - }, - { - "name": "minecraft:light_gray_wool", - "id": -552 - }, - { - "name": "minecraft:light_weighted_pressure_plate", - "id": 147 - }, - { - "name": "minecraft:lightning_rod", - "id": -312 - }, - { - "name": "minecraft:lime_candle", - "id": -418 - }, - { - "name": "minecraft:lime_candle_cake", - "id": -435 - }, - { - "name": "minecraft:lime_carpet", - "id": -601 - }, - { - "name": "minecraft:lime_concrete", - "id": -632 - }, - { - "name": "minecraft:lime_concrete_powder", - "id": -713 - }, - { - "name": "minecraft:lime_dye", - "id": 408 - }, - { - "name": "minecraft:lime_glazed_terracotta", - "id": 225 - }, - { - "name": "minecraft:lime_shulker_box", - "id": -617 - }, - { - "name": "minecraft:lime_stained_glass", - "id": -677 - }, - { - "name": "minecraft:lime_stained_glass_pane", - "id": -647 - }, - { - "name": "minecraft:lime_terracotta", - "id": -728 - }, - { - "name": "minecraft:lime_wool", - "id": -559 - }, - { - "name": "minecraft:lingering_potion", - "id": 571 - }, - { - "name": "minecraft:lit_blast_furnace", - "id": -214 - }, - { - "name": "minecraft:lit_deepslate_redstone_ore", - "id": -404 - }, - { - "name": "minecraft:lit_furnace", - "id": 62 - }, - { - "name": "minecraft:lit_pumpkin", - "id": 91 - }, - { - "name": "minecraft:lit_redstone_lamp", - "id": 124 - }, - { - "name": "minecraft:lit_redstone_ore", - "id": 74 - }, - { - "name": "minecraft:lit_smoker", - "id": -199 - }, - { - "name": "minecraft:llama_spawn_egg", - "id": 476 - }, - { - "name": "minecraft:lodestone", - "id": -222 - }, - { - "name": "minecraft:lodestone_compass", - "id": 611 - }, - { - "name": "minecraft:log", - "id": 711 - }, - { - "name": "minecraft:log2", - "id": 715 - }, - { - "name": "minecraft:loom", - "id": -204 - }, - { - "name": "minecraft:magenta_candle", - "id": -415 - }, - { - "name": "minecraft:magenta_candle_cake", - "id": -432 - }, - { - "name": "minecraft:magenta_carpet", - "id": -598 - }, - { - "name": "minecraft:magenta_concrete", - "id": -629 - }, - { - "name": "minecraft:magenta_concrete_powder", - "id": -710 - }, - { - "name": "minecraft:magenta_dye", - "id": 411 - }, - { - "name": "minecraft:magenta_glazed_terracotta", - "id": 222 - }, - { - "name": "minecraft:magenta_shulker_box", - "id": -614 - }, - { - "name": "minecraft:magenta_stained_glass", - "id": -674 - }, - { - "name": "minecraft:magenta_stained_glass_pane", - "id": -644 - }, - { - "name": "minecraft:magenta_terracotta", - "id": -725 - }, - { - "name": "minecraft:magenta_wool", - "id": -565 - }, - { - "name": "minecraft:magma", - "id": 213 - }, - { - "name": "minecraft:magma_cream", - "id": 433 - }, - { - "name": "minecraft:magma_cube_spawn_egg", - "id": 458 - }, - { - "name": "minecraft:mangrove_boat", - "id": 644 - }, - { - "name": "minecraft:mangrove_button", - "id": -487 - }, - { - "name": "minecraft:mangrove_chest_boat", - "id": 653 - }, - { - "name": "minecraft:mangrove_door", - "id": 642 - }, - { - "name": "minecraft:mangrove_double_slab", - "id": -499 - }, - { - "name": "minecraft:mangrove_fence", - "id": -491 - }, - { - "name": "minecraft:mangrove_fence_gate", - "id": -492 - }, - { - "name": "minecraft:mangrove_hanging_sign", - "id": -508 - }, - { - "name": "minecraft:mangrove_leaves", - "id": -472 - }, - { - "name": "minecraft:mangrove_log", - "id": -484 - }, - { - "name": "minecraft:mangrove_planks", - "id": -486 - }, - { - "name": "minecraft:mangrove_pressure_plate", - "id": -490 - }, - { - "name": "minecraft:mangrove_propagule", - "id": -474 - }, - { - "name": "minecraft:mangrove_roots", - "id": -482 - }, - { - "name": "minecraft:mangrove_sign", - "id": 643 - }, - { - "name": "minecraft:mangrove_slab", - "id": -489 - }, - { - "name": "minecraft:mangrove_stairs", - "id": -488 - }, - { - "name": "minecraft:mangrove_standing_sign", - "id": -494 - }, - { - "name": "minecraft:mangrove_trapdoor", - "id": -496 - }, - { - "name": "minecraft:mangrove_wall_sign", - "id": -495 - }, - { - "name": "minecraft:mangrove_wood", - "id": -497 - }, - { - "name": "minecraft:medicine", - "id": 608 - }, - { - "name": "minecraft:medium_amethyst_bud", - "id": -331 - }, - { - "name": "minecraft:melon_block", - "id": 103 - }, - { - "name": "minecraft:melon_seeds", - "id": 294 - }, - { - "name": "minecraft:melon_slice", - "id": 273 - }, - { - "name": "minecraft:melon_stem", - "id": 105 - }, - { - "name": "minecraft:milk_bucket", - "id": 364 - }, - { - "name": "minecraft:minecart", - "id": 373 - }, - { - "name": "minecraft:miner_pottery_sherd", - "id": 677 - }, - { - "name": "minecraft:mob_spawner", - "id": 52 - }, - { - "name": "minecraft:mojang_banner_pattern", - "id": 593 - }, - { - "name": "minecraft:monster_egg", - "id": 97 - }, - { - "name": "minecraft:mooshroom_spawn_egg", - "id": 443 - }, - { - "name": "minecraft:moss_block", - "id": -320 - }, - { - "name": "minecraft:moss_carpet", - "id": -335 - }, - { - "name": "minecraft:mossy_cobblestone", - "id": 48 - }, - { - "name": "minecraft:mossy_cobblestone_stairs", - "id": -179 - }, - { - "name": "minecraft:mossy_stone_brick_stairs", - "id": -175 - }, - { - "name": "minecraft:mourner_pottery_sherd", - "id": 678 - }, - { - "name": "minecraft:moving_block", - "id": 250 - }, - { - "name": "minecraft:mud", - "id": -473 - }, - { - "name": "minecraft:mud_brick_double_slab", - "id": -479 - }, - { - "name": "minecraft:mud_brick_slab", - "id": -478 - }, - { - "name": "minecraft:mud_brick_stairs", - "id": -480 - }, - { - "name": "minecraft:mud_brick_wall", - "id": -481 - }, - { - "name": "minecraft:mud_bricks", - "id": -475 - }, - { - "name": "minecraft:muddy_mangrove_roots", - "id": -483 - }, - { - "name": "minecraft:mule_spawn_egg", - "id": 469 - }, - { - "name": "minecraft:mushroom_stew", - "id": 261 - }, - { - "name": "minecraft:music_disc_11", - "id": 553 - }, - { - "name": "minecraft:music_disc_13", - "id": 543 - }, - { - "name": "minecraft:music_disc_5", - "id": 645 - }, - { - "name": "minecraft:music_disc_blocks", - "id": 545 - }, - { - "name": "minecraft:music_disc_cat", - "id": 544 - }, - { - "name": "minecraft:music_disc_chirp", - "id": 546 - }, - { - "name": "minecraft:music_disc_far", - "id": 547 - }, - { - "name": "minecraft:music_disc_mall", - "id": 548 - }, - { - "name": "minecraft:music_disc_mellohi", - "id": 549 - }, - { - "name": "minecraft:music_disc_otherside", - "id": 635 - }, - { - "name": "minecraft:music_disc_pigstep", - "id": 629 - }, - { - "name": "minecraft:music_disc_relic", - "id": 703 - }, - { - "name": "minecraft:music_disc_stal", - "id": 550 - }, - { - "name": "minecraft:music_disc_strad", - "id": 551 - }, - { - "name": "minecraft:music_disc_wait", - "id": 554 - }, - { - "name": "minecraft:music_disc_ward", - "id": 552 - }, - { - "name": "minecraft:mutton", - "id": 559 - }, - { - "name": "minecraft:mycelium", - "id": 110 - }, - { - "name": "minecraft:name_tag", - "id": 557 - }, - { - "name": "minecraft:nautilus_shell", - "id": 579 - }, - { - "name": "minecraft:nether_brick", - "id": 112 - }, - { - "name": "minecraft:nether_brick_fence", - "id": 113 - }, - { - "name": "minecraft:nether_brick_stairs", - "id": 114 - }, - { - "name": "minecraft:nether_gold_ore", - "id": -288 - }, - { - "name": "minecraft:nether_sprouts", - "id": 630 - }, - { - "name": "minecraft:nether_star", - "id": 527 - }, - { - "name": "minecraft:nether_wart", - "id": 295 - }, - { - "name": "minecraft:nether_wart_block", - "id": 214 - }, - { - "name": "minecraft:netherbrick", - "id": 532 - }, - { - "name": "minecraft:netherite_axe", - "id": 615 - }, - { - "name": "minecraft:netherite_block", - "id": -270 - }, - { - "name": "minecraft:netherite_boots", - "id": 621 - }, - { - "name": "minecraft:netherite_chestplate", - "id": 619 - }, - { - "name": "minecraft:netherite_helmet", - "id": 618 - }, - { - "name": "minecraft:netherite_hoe", - "id": 616 - }, - { - "name": "minecraft:netherite_ingot", - "id": 617 - }, - { - "name": "minecraft:netherite_leggings", - "id": 620 - }, - { - "name": "minecraft:netherite_pickaxe", - "id": 614 - }, - { - "name": "minecraft:netherite_scrap", - "id": 622 - }, - { - "name": "minecraft:netherite_shovel", - "id": 613 - }, - { - "name": "minecraft:netherite_sword", - "id": 612 - }, - { - "name": "minecraft:netherite_upgrade_smithing_template", - "id": 686 - }, - { - "name": "minecraft:netherrack", - "id": 87 - }, - { - "name": "minecraft:netherreactor", - "id": 247 - }, - { - "name": "minecraft:normal_stone_stairs", - "id": -180 - }, - { - "name": "minecraft:noteblock", - "id": 25 - }, - { - "name": "minecraft:npc_spawn_egg", - "id": 473 - }, - { - "name": "minecraft:oak_boat", - "id": 378 - }, - { - "name": "minecraft:oak_chest_boat", - "id": 647 - }, - { - "name": "minecraft:oak_fence", - "id": 85 - }, - { - "name": "minecraft:oak_hanging_sign", - "id": -500 - }, - { - "name": "minecraft:oak_log", - "id": 17 - }, - { - "name": "minecraft:oak_planks", - "id": 5 - }, - { - "name": "minecraft:oak_sign", - "id": 361 - }, - { - "name": "minecraft:oak_stairs", - "id": 53 - }, - { - "name": "minecraft:observer", - "id": 251 - }, - { - "name": "minecraft:obsidian", - "id": 49 - }, - { - "name": "minecraft:ocelot_spawn_egg", - "id": 454 - }, - { - "name": "minecraft:ochre_froglight", - "id": -471 - }, - { - "name": "minecraft:orange_candle", - "id": -414 - }, - { - "name": "minecraft:orange_candle_cake", - "id": -431 - }, - { - "name": "minecraft:orange_carpet", - "id": -597 - }, - { - "name": "minecraft:orange_concrete", - "id": -628 - }, - { - "name": "minecraft:orange_concrete_powder", - "id": -709 - }, - { - "name": "minecraft:orange_dye", - "id": 412 - }, - { - "name": "minecraft:orange_glazed_terracotta", - "id": 221 - }, - { - "name": "minecraft:orange_shulker_box", - "id": -613 - }, - { - "name": "minecraft:orange_stained_glass", - "id": -673 - }, - { - "name": "minecraft:orange_stained_glass_pane", - "id": -643 - }, - { - "name": "minecraft:orange_terracotta", - "id": -724 - }, - { - "name": "minecraft:orange_wool", - "id": -557 - }, - { - "name": "minecraft:oxidized_chiseled_copper", - "id": -763 - }, - { - "name": "minecraft:oxidized_copper", - "id": -343 - }, - { - "name": "minecraft:oxidized_copper_bulb", - "id": -779 - }, - { - "name": "minecraft:oxidized_copper_door", - "id": -787 - }, - { - "name": "minecraft:oxidized_copper_grate", - "id": -771 - }, - { - "name": "minecraft:oxidized_copper_trapdoor", - "id": -795 - }, - { - "name": "minecraft:oxidized_cut_copper", - "id": -350 - }, - { - "name": "minecraft:oxidized_cut_copper_slab", - "id": -364 - }, - { - "name": "minecraft:oxidized_cut_copper_stairs", - "id": -357 - }, - { - "name": "minecraft:oxidized_double_cut_copper_slab", - "id": -371 - }, - { - "name": "minecraft:packed_ice", - "id": 174 - }, - { - "name": "minecraft:packed_mud", - "id": -477 - }, - { - "name": "minecraft:painting", - "id": 360 - }, - { - "name": "minecraft:panda_spawn_egg", - "id": 492 - }, - { - "name": "minecraft:paper", - "id": 389 - }, - { - "name": "minecraft:parrot_spawn_egg", - "id": 481 - }, - { - "name": "minecraft:pearlescent_froglight", - "id": -469 - }, - { - "name": "minecraft:phantom_membrane", - "id": 583 - }, - { - "name": "minecraft:phantom_spawn_egg", - "id": 489 - }, - { - "name": "minecraft:pig_spawn_egg", - "id": 440 - }, - { - "name": "minecraft:piglin_banner_pattern", - "id": 596 - }, - { - "name": "minecraft:piglin_brute_spawn_egg", - "id": 502 - }, - { - "name": "minecraft:piglin_spawn_egg", - "id": 500 - }, - { - "name": "minecraft:pillager_spawn_egg", - "id": 494 - }, - { - "name": "minecraft:pink_candle", - "id": -419 - }, - { - "name": "minecraft:pink_candle_cake", - "id": -436 - }, - { - "name": "minecraft:pink_carpet", - "id": -602 - }, - { - "name": "minecraft:pink_concrete", - "id": -633 - }, - { - "name": "minecraft:pink_concrete_powder", - "id": -714 - }, - { - "name": "minecraft:pink_dye", - "id": 407 - }, - { - "name": "minecraft:pink_glazed_terracotta", - "id": 226 - }, - { - "name": "minecraft:pink_petals", - "id": -549 - }, - { - "name": "minecraft:pink_shulker_box", - "id": -618 - }, - { - "name": "minecraft:pink_stained_glass", - "id": -678 - }, - { - "name": "minecraft:pink_stained_glass_pane", - "id": -648 - }, - { - "name": "minecraft:pink_terracotta", - "id": -729 - }, - { - "name": "minecraft:pink_wool", - "id": -566 - }, - { - "name": "minecraft:piston", - "id": 33 - }, - { - "name": "minecraft:piston_arm_collision", - "id": 34 - }, - { - "name": "minecraft:pitcher_crop", - "id": -574 - }, - { - "name": "minecraft:pitcher_plant", - "id": -612 - }, - { - "name": "minecraft:pitcher_pod", - "id": 298 - }, - { - "name": "minecraft:planks", - "id": 713 - }, - { - "name": "minecraft:plenty_pottery_sherd", - "id": 679 - }, - { - "name": "minecraft:podzol", - "id": 243 - }, - { - "name": "minecraft:pointed_dripstone", - "id": -308 - }, - { - "name": "minecraft:poisonous_potato", - "id": 283 - }, - { - "name": "minecraft:polar_bear_spawn_egg", - "id": 475 - }, - { - "name": "minecraft:polished_andesite", - "id": -595 - }, - { - "name": "minecraft:polished_andesite_stairs", - "id": -174 - }, - { - "name": "minecraft:polished_basalt", - "id": -235 - }, - { - "name": "minecraft:polished_blackstone", - "id": -291 - }, - { - "name": "minecraft:polished_blackstone_brick_double_slab", - "id": -285 - }, - { - "name": "minecraft:polished_blackstone_brick_slab", - "id": -284 - }, - { - "name": "minecraft:polished_blackstone_brick_stairs", - "id": -275 - }, - { - "name": "minecraft:polished_blackstone_brick_wall", - "id": -278 - }, - { - "name": "minecraft:polished_blackstone_bricks", - "id": -274 - }, - { - "name": "minecraft:polished_blackstone_button", - "id": -296 - }, - { - "name": "minecraft:polished_blackstone_double_slab", - "id": -294 - }, - { - "name": "minecraft:polished_blackstone_pressure_plate", - "id": -295 - }, - { - "name": "minecraft:polished_blackstone_slab", - "id": -293 - }, - { - "name": "minecraft:polished_blackstone_stairs", - "id": -292 - }, - { - "name": "minecraft:polished_blackstone_wall", - "id": -297 - }, - { - "name": "minecraft:polished_deepslate", - "id": -383 - }, - { - "name": "minecraft:polished_deepslate_double_slab", - "id": -397 - }, - { - "name": "minecraft:polished_deepslate_slab", - "id": -384 - }, - { - "name": "minecraft:polished_deepslate_stairs", - "id": -385 - }, - { - "name": "minecraft:polished_deepslate_wall", - "id": -386 - }, - { - "name": "minecraft:polished_diorite", - "id": -593 - }, - { - "name": "minecraft:polished_diorite_stairs", - "id": -173 - }, - { - "name": "minecraft:polished_granite", - "id": -591 - }, - { - "name": "minecraft:polished_granite_stairs", - "id": -172 - }, - { - "name": "minecraft:polished_tuff", - "id": -748 - }, - { - "name": "minecraft:polished_tuff_double_slab", - "id": -750 - }, - { - "name": "minecraft:polished_tuff_slab", - "id": -749 - }, - { - "name": "minecraft:polished_tuff_stairs", - "id": -751 - }, - { - "name": "minecraft:polished_tuff_wall", - "id": -752 - }, - { - "name": "minecraft:popped_chorus_fruit", - "id": 568 - }, - { - "name": "minecraft:porkchop", - "id": 263 - }, - { - "name": "minecraft:portal", - "id": 90 - }, - { - "name": "minecraft:potato", - "id": 281 - }, - { - "name": "minecraft:potatoes", - "id": 142 - }, - { - "name": "minecraft:potion", - "id": 429 - }, - { - "name": "minecraft:powder_snow", - "id": -306 - }, - { - "name": "minecraft:powder_snow_bucket", - "id": 371 - }, - { - "name": "minecraft:powered_comparator", - "id": 150 - }, - { - "name": "minecraft:powered_repeater", - "id": 94 - }, - { - "name": "minecraft:prismarine", - "id": 168 - }, - { - "name": "minecraft:prismarine_bricks_stairs", - "id": -4 - }, - { - "name": "minecraft:prismarine_crystals", - "id": 558 - }, - { - "name": "minecraft:prismarine_shard", - "id": 574 - }, - { - "name": "minecraft:prismarine_stairs", - "id": -2 - }, - { - "name": "minecraft:prize_pottery_sherd", - "id": 680 - }, - { - "name": "minecraft:pufferfish", - "id": 268 - }, - { - "name": "minecraft:pufferfish_bucket", - "id": 370 - }, - { - "name": "minecraft:pufferfish_spawn_egg", - "id": 484 - }, - { - "name": "minecraft:pumpkin", - "id": 86 - }, - { - "name": "minecraft:pumpkin_pie", - "id": 285 - }, - { - "name": "minecraft:pumpkin_seeds", - "id": 293 - }, - { - "name": "minecraft:pumpkin_stem", - "id": 104 - }, - { - "name": "minecraft:purple_candle", - "id": -423 - }, - { - "name": "minecraft:purple_candle_cake", - "id": -440 - }, - { - "name": "minecraft:purple_carpet", - "id": -606 - }, - { - "name": "minecraft:purple_concrete", - "id": -637 - }, - { - "name": "minecraft:purple_concrete_powder", - "id": -718 - }, - { - "name": "minecraft:purple_dye", - "id": 403 - }, - { - "name": "minecraft:purple_glazed_terracotta", - "id": 219 - }, - { - "name": "minecraft:purple_shulker_box", - "id": -622 - }, - { - "name": "minecraft:purple_stained_glass", - "id": -682 - }, - { - "name": "minecraft:purple_stained_glass_pane", - "id": -652 - }, - { - "name": "minecraft:purple_terracotta", - "id": -733 - }, - { - "name": "minecraft:purple_wool", - "id": -564 - }, - { - "name": "minecraft:purpur_block", - "id": 201 - }, - { - "name": "minecraft:purpur_stairs", - "id": 203 - }, - { - "name": "minecraft:quartz", - "id": 533 - }, - { - "name": "minecraft:quartz_block", - "id": 155 - }, - { - "name": "minecraft:quartz_bricks", - "id": -304 - }, - { - "name": "minecraft:quartz_ore", - "id": 153 - }, - { - "name": "minecraft:quartz_stairs", - "id": 156 - }, - { - "name": "minecraft:rabbit", - "id": 289 - }, - { - "name": "minecraft:rabbit_foot", - "id": 537 - }, - { - "name": "minecraft:rabbit_hide", - "id": 538 - }, - { - "name": "minecraft:rabbit_spawn_egg", - "id": 462 - }, - { - "name": "minecraft:rabbit_stew", - "id": 291 - }, - { - "name": "minecraft:rail", - "id": 66 - }, - { - "name": "minecraft:raiser_armor_trim_smithing_template", - "id": 700 - }, - { - "name": "minecraft:rapid_fertilizer", - "id": 606 - }, - { - "name": "minecraft:ravager_spawn_egg", - "id": 496 - }, - { - "name": "minecraft:raw_copper", - "id": 516 - }, - { - "name": "minecraft:raw_copper_block", - "id": -452 - }, - { - "name": "minecraft:raw_gold", - "id": 515 - }, - { - "name": "minecraft:raw_gold_block", - "id": -453 - }, - { - "name": "minecraft:raw_iron", - "id": 514 - }, - { - "name": "minecraft:raw_iron_block", - "id": -451 - }, - { - "name": "minecraft:recovery_compass", - "id": 655 - }, - { - "name": "minecraft:red_candle", - "id": -427 - }, - { - "name": "minecraft:red_candle_cake", - "id": -444 - }, - { - "name": "minecraft:red_carpet", - "id": -610 - }, - { - "name": "minecraft:red_concrete", - "id": -641 - }, - { - "name": "minecraft:red_concrete_powder", - "id": -722 - }, - { - "name": "minecraft:red_dye", - "id": 399 - }, - { - "name": "minecraft:red_flower", - "id": 38 - }, - { - "name": "minecraft:red_glazed_terracotta", - "id": 234 - }, - { - "name": "minecraft:red_mushroom", - "id": 40 - }, - { - "name": "minecraft:red_mushroom_block", - "id": 100 - }, - { - "name": "minecraft:red_nether_brick", - "id": 215 - }, - { - "name": "minecraft:red_nether_brick_stairs", - "id": -184 - }, - { - "name": "minecraft:red_sandstone", - "id": 179 - }, - { - "name": "minecraft:red_sandstone_stairs", - "id": 180 - }, - { - "name": "minecraft:red_shulker_box", - "id": -626 - }, - { - "name": "minecraft:red_stained_glass", - "id": -686 - }, - { - "name": "minecraft:red_stained_glass_pane", - "id": -656 - }, - { - "name": "minecraft:red_terracotta", - "id": -737 - }, - { - "name": "minecraft:red_wool", - "id": -556 - }, - { - "name": "minecraft:redstone", - "id": 376 - }, - { - "name": "minecraft:redstone_block", - "id": 152 - }, - { - "name": "minecraft:redstone_lamp", - "id": 123 - }, - { - "name": "minecraft:redstone_ore", - "id": 73 - }, - { - "name": "minecraft:redstone_torch", - "id": 76 - }, - { - "name": "minecraft:redstone_wire", - "id": 55 - }, - { - "name": "minecraft:reinforced_deepslate", - "id": -466 - }, - { - "name": "minecraft:repeater", - "id": 422 - }, - { - "name": "minecraft:repeating_command_block", - "id": 188 - }, - { - "name": "minecraft:reserved6", - "id": 255 - }, - { - "name": "minecraft:respawn_anchor", - "id": -272 - }, - { - "name": "minecraft:rib_armor_trim_smithing_template", - "id": 696 - }, - { - "name": "minecraft:rotten_flesh", - "id": 278 - }, - { - "name": "minecraft:saddle", - "id": 374 - }, - { - "name": "minecraft:salmon", - "id": 266 - }, - { - "name": "minecraft:salmon_bucket", - "id": 368 - }, - { - "name": "minecraft:salmon_spawn_egg", - "id": 485 - }, - { - "name": "minecraft:sand", - "id": 12 - }, - { - "name": "minecraft:sandstone", - "id": 24 - }, - { - "name": "minecraft:sandstone_stairs", - "id": 128 - }, - { - "name": "minecraft:sapling", - "id": 6 - }, - { - "name": "minecraft:scaffolding", - "id": -165 - }, - { - "name": "minecraft:sculk", - "id": -458 - }, - { - "name": "minecraft:sculk_catalyst", - "id": -460 - }, - { - "name": "minecraft:sculk_sensor", - "id": -307 - }, - { - "name": "minecraft:sculk_shrieker", - "id": -461 - }, - { - "name": "minecraft:sculk_vein", - "id": -459 - }, - { - "name": "minecraft:sea_lantern", - "id": 169 - }, - { - "name": "minecraft:sea_pickle", - "id": -156 - }, - { - "name": "minecraft:seagrass", - "id": -130 - }, - { - "name": "minecraft:sentry_armor_trim_smithing_template", - "id": 687 - }, - { - "name": "minecraft:shaper_armor_trim_smithing_template", - "id": 701 - }, - { - "name": "minecraft:sheaf_pottery_sherd", - "id": 681 - }, - { - "name": "minecraft:shears", - "id": 424 - }, - { - "name": "minecraft:sheep_spawn_egg", - "id": 441 - }, - { - "name": "minecraft:shelter_pottery_sherd", - "id": 682 - }, - { - "name": "minecraft:shield", - "id": 358 - }, - { - "name": "minecraft:shroomlight", - "id": -230 - }, - { - "name": "minecraft:shulker_box", - "id": 720 - }, - { - "name": "minecraft:shulker_shell", - "id": 575 - }, - { - "name": "minecraft:shulker_spawn_egg", - "id": 472 - }, - { - "name": "minecraft:silence_armor_trim_smithing_template", - "id": 698 - }, - { - "name": "minecraft:silver_glazed_terracotta", - "id": 228 - }, - { - "name": "minecraft:silverfish_spawn_egg", - "id": 446 - }, - { - "name": "minecraft:skeleton_horse_spawn_egg", - "id": 470 - }, - { - "name": "minecraft:skeleton_spawn_egg", - "id": 447 - }, - { - "name": "minecraft:skull", - "id": 525 - }, - { - "name": "minecraft:skull_banner_pattern", - "id": 592 - }, - { - "name": "minecraft:skull_pottery_sherd", - "id": 683 - }, - { - "name": "minecraft:slime", - "id": 165 - }, - { - "name": "minecraft:slime_ball", - "id": 391 - }, - { - "name": "minecraft:slime_spawn_egg", - "id": 448 - }, - { - "name": "minecraft:small_amethyst_bud", - "id": -332 - }, - { - "name": "minecraft:small_dripleaf_block", - "id": -336 - }, - { - "name": "minecraft:smithing_table", - "id": -202 - }, - { - "name": "minecraft:smoker", - "id": -198 - }, - { - "name": "minecraft:smooth_basalt", - "id": -377 - }, - { - "name": "minecraft:smooth_quartz_stairs", - "id": -185 - }, - { - "name": "minecraft:smooth_red_sandstone_stairs", - "id": -176 - }, - { - "name": "minecraft:smooth_sandstone_stairs", - "id": -177 - }, - { - "name": "minecraft:smooth_stone", - "id": -183 - }, - { - "name": "minecraft:sniffer_egg", - "id": -596 - }, - { - "name": "minecraft:sniffer_spawn_egg", - "id": 503 - }, - { - "name": "minecraft:snort_pottery_sherd", - "id": 684 - }, - { - "name": "minecraft:snout_armor_trim_smithing_template", - "id": 695 - }, - { - "name": "minecraft:snow", - "id": 80 - }, - { - "name": "minecraft:snow_golem_spawn_egg", - "id": 509 - }, - { - "name": "minecraft:snow_layer", - "id": 78 - }, - { - "name": "minecraft:snowball", - "id": 377 - }, - { - "name": "minecraft:soul_campfire", - "id": 631 - }, - { - "name": "minecraft:soul_fire", - "id": -237 - }, - { - "name": "minecraft:soul_lantern", - "id": -269 - }, - { - "name": "minecraft:soul_sand", - "id": 88 - }, - { - "name": "minecraft:soul_soil", - "id": -236 - }, - { - "name": "minecraft:soul_torch", - "id": -268 - }, - { - "name": "minecraft:sparkler", - "id": 609 - }, - { - "name": "minecraft:spawn_egg", - "id": 726 - }, - { - "name": "minecraft:spider_eye", - "id": 279 - }, - { - "name": "minecraft:spider_spawn_egg", - "id": 449 - }, - { - "name": "minecraft:spire_armor_trim_smithing_template", - "id": 697 - }, - { - "name": "minecraft:splash_potion", - "id": 570 - }, - { - "name": "minecraft:sponge", - "id": 19 - }, - { - "name": "minecraft:spore_blossom", - "id": -321 - }, - { - "name": "minecraft:spruce_boat", - "id": 381 - }, - { - "name": "minecraft:spruce_button", - "id": -144 - }, - { - "name": "minecraft:spruce_chest_boat", - "id": 650 - }, - { - "name": "minecraft:spruce_door", - "id": 562 - }, - { - "name": "minecraft:spruce_fence", - "id": -579 - }, - { - "name": "minecraft:spruce_fence_gate", - "id": 183 - }, - { - "name": "minecraft:spruce_hanging_sign", - "id": -501 - }, - { - "name": "minecraft:spruce_log", - "id": -569 - }, - { - "name": "minecraft:spruce_planks", - "id": -739 - }, - { - "name": "minecraft:spruce_pressure_plate", - "id": -154 - }, - { - "name": "minecraft:spruce_sign", - "id": 585 - }, - { - "name": "minecraft:spruce_stairs", - "id": 134 - }, - { - "name": "minecraft:spruce_standing_sign", - "id": -181 - }, - { - "name": "minecraft:spruce_trapdoor", - "id": -149 - }, - { - "name": "minecraft:spruce_wall_sign", - "id": -182 - }, - { - "name": "minecraft:spyglass", - "id": 634 - }, - { - "name": "minecraft:squid_spawn_egg", - "id": 453 - }, - { - "name": "minecraft:stained_glass", - "id": 718 - }, - { - "name": "minecraft:stained_glass_pane", - "id": 719 - }, - { - "name": "minecraft:stained_hardened_clay", - "id": 704 - }, - { - "name": "minecraft:standing_banner", - "id": 176 - }, - { - "name": "minecraft:standing_sign", - "id": 63 - }, - { - "name": "minecraft:stick", - "id": 323 - }, - { - "name": "minecraft:sticky_piston", - "id": 29 - }, - { - "name": "minecraft:sticky_piston_arm_collision", - "id": -217 - }, - { - "name": "minecraft:stone", - "id": 1 - }, - { - "name": "minecraft:stone_axe", - "id": 318 - }, - { - "name": "minecraft:stone_block_slab", - "id": 44 - }, - { - "name": "minecraft:stone_block_slab2", - "id": 182 - }, - { - "name": "minecraft:stone_block_slab3", - "id": -162 - }, - { - "name": "minecraft:stone_block_slab4", - "id": -166 - }, - { - "name": "minecraft:stone_brick_stairs", - "id": 109 - }, - { - "name": "minecraft:stone_button", - "id": 77 - }, - { - "name": "minecraft:stone_hoe", - "id": 333 - }, - { - "name": "minecraft:stone_pickaxe", - "id": 317 - }, - { - "name": "minecraft:stone_pressure_plate", - "id": 70 - }, - { - "name": "minecraft:stone_shovel", - "id": 316 - }, - { - "name": "minecraft:stone_stairs", - "id": 67 - }, - { - "name": "minecraft:stone_sword", - "id": 315 - }, - { - "name": "minecraft:stonebrick", - "id": 98 - }, - { - "name": "minecraft:stonecutter", - "id": 245 - }, - { - "name": "minecraft:stonecutter_block", - "id": -197 - }, - { - "name": "minecraft:stray_spawn_egg", - "id": 465 - }, - { - "name": "minecraft:strider_spawn_egg", - "id": 498 - }, - { - "name": "minecraft:string", - "id": 329 - }, - { - "name": "minecraft:stripped_acacia_log", - "id": -8 - }, - { - "name": "minecraft:stripped_bamboo_block", - "id": -528 - }, - { - "name": "minecraft:stripped_birch_log", - "id": -6 - }, - { - "name": "minecraft:stripped_cherry_log", - "id": -535 - }, - { - "name": "minecraft:stripped_cherry_wood", - "id": -545 - }, - { - "name": "minecraft:stripped_crimson_hyphae", - "id": -300 - }, - { - "name": "minecraft:stripped_crimson_stem", - "id": -240 - }, - { - "name": "minecraft:stripped_dark_oak_log", - "id": -9 - }, - { - "name": "minecraft:stripped_jungle_log", - "id": -7 - }, - { - "name": "minecraft:stripped_mangrove_log", - "id": -485 - }, - { - "name": "minecraft:stripped_mangrove_wood", - "id": -498 - }, - { - "name": "minecraft:stripped_oak_log", - "id": -10 - }, - { - "name": "minecraft:stripped_spruce_log", - "id": -5 - }, - { - "name": "minecraft:stripped_warped_hyphae", - "id": -301 - }, - { - "name": "minecraft:stripped_warped_stem", - "id": -241 - }, - { - "name": "minecraft:structure_block", - "id": 252 - }, - { - "name": "minecraft:structure_void", - "id": 217 - }, - { - "name": "minecraft:sugar", - "id": 419 - }, - { - "name": "minecraft:sugar_cane", - "id": 388 - }, - { - "name": "minecraft:suspicious_gravel", - "id": -573 - }, - { - "name": "minecraft:suspicious_sand", - "id": -529 - }, - { - "name": "minecraft:suspicious_stew", - "id": 599 - }, - { - "name": "minecraft:sweet_berries", - "id": 288 - }, - { - "name": "minecraft:sweet_berry_bush", - "id": -207 - }, - { - "name": "minecraft:tadpole_bucket", - "id": 639 - }, - { - "name": "minecraft:tadpole_spawn_egg", - "id": 638 - }, - { - "name": "minecraft:tallgrass", - "id": 31 - }, - { - "name": "minecraft:target", - "id": -239 - }, - { - "name": "minecraft:tide_armor_trim_smithing_template", - "id": 694 - }, - { - "name": "minecraft:tinted_glass", - "id": -334 - }, - { - "name": "minecraft:tnt", - "id": 46 - }, - { - "name": "minecraft:tnt_minecart", - "id": 534 - }, - { - "name": "minecraft:torch", - "id": 50 - }, - { - "name": "minecraft:torchflower", - "id": -568 - }, - { - "name": "minecraft:torchflower_crop", - "id": -567 - }, - { - "name": "minecraft:torchflower_seeds", - "id": 297 - }, - { - "name": "minecraft:totem_of_undying", - "id": 577 - }, - { - "name": "minecraft:trader_llama_spawn_egg", - "id": 657 - }, - { - "name": "minecraft:trapdoor", - "id": 96 - }, - { - "name": "minecraft:trapped_chest", - "id": 146 - }, - { - "name": "minecraft:trial_key", - "id": 705 - }, - { - "name": "minecraft:trial_spawner", - "id": -315 - }, - { - "name": "minecraft:trident", - "id": 555 - }, - { - "name": "minecraft:trip_wire", - "id": 132 - }, - { - "name": "minecraft:tripwire_hook", - "id": 131 - }, - { - "name": "minecraft:tropical_fish", - "id": 267 - }, - { - "name": "minecraft:tropical_fish_bucket", - "id": 369 - }, - { - "name": "minecraft:tropical_fish_spawn_egg", - "id": 482 - }, - { - "name": "minecraft:tube_coral", - "id": -131 - }, - { - "name": "minecraft:tuff", - "id": -333 - }, - { - "name": "minecraft:tuff_brick_double_slab", - "id": -756 - }, - { - "name": "minecraft:tuff_brick_slab", - "id": -755 - }, - { - "name": "minecraft:tuff_brick_stairs", - "id": -757 - }, - { - "name": "minecraft:tuff_brick_wall", - "id": -758 - }, - { - "name": "minecraft:tuff_bricks", - "id": -754 - }, - { - "name": "minecraft:tuff_double_slab", - "id": -745 - }, - { - "name": "minecraft:tuff_slab", - "id": -744 - }, - { - "name": "minecraft:tuff_stairs", - "id": -746 - }, - { - "name": "minecraft:tuff_wall", - "id": -747 - }, - { - "name": "minecraft:turtle_egg", - "id": -159 - }, - { - "name": "minecraft:turtle_helmet", - "id": 582 - }, - { - "name": "minecraft:turtle_scute", - "id": 581 - }, - { - "name": "minecraft:turtle_spawn_egg", - "id": 488 - }, - { - "name": "minecraft:twisting_vines", - "id": -287 - }, - { - "name": "minecraft:underwater_torch", - "id": 239 - }, - { - "name": "minecraft:undyed_shulker_box", - "id": 205 - }, - { - "name": "minecraft:unknown", - "id": -305 - }, - { - "name": "minecraft:unlit_redstone_torch", - "id": 75 - }, - { - "name": "minecraft:unpowered_comparator", - "id": 149 - }, - { - "name": "minecraft:unpowered_repeater", - "id": 93 - }, - { - "name": "minecraft:verdant_froglight", - "id": -470 - }, - { - "name": "minecraft:vex_armor_trim_smithing_template", - "id": 693 - }, - { - "name": "minecraft:vex_spawn_egg", - "id": 479 - }, - { - "name": "minecraft:villager_spawn_egg", - "id": 452 - }, - { - "name": "minecraft:vindicator_spawn_egg", - "id": 477 - }, - { - "name": "minecraft:vine", - "id": 106 - }, - { - "name": "minecraft:wall_banner", - "id": 177 - }, - { - "name": "minecraft:wall_sign", - "id": 68 - }, - { - "name": "minecraft:wandering_trader_spawn_egg", - "id": 495 - }, - { - "name": "minecraft:ward_armor_trim_smithing_template", - "id": 691 - }, - { - "name": "minecraft:warden_spawn_egg", - "id": 641 - }, - { - "name": "minecraft:warped_button", - "id": -261 - }, - { - "name": "minecraft:warped_door", - "id": 626 - }, - { - "name": "minecraft:warped_double_slab", - "id": -267 - }, - { - "name": "minecraft:warped_fence", - "id": -257 - }, - { - "name": "minecraft:warped_fence_gate", - "id": -259 - }, - { - "name": "minecraft:warped_fungus", - "id": -229 - }, - { - "name": "minecraft:warped_fungus_on_a_stick", - "id": 627 - }, - { - "name": "minecraft:warped_hanging_sign", - "id": -507 - }, - { - "name": "minecraft:warped_hyphae", - "id": -298 - }, - { - "name": "minecraft:warped_nylium", - "id": -233 - }, - { - "name": "minecraft:warped_planks", - "id": -243 - }, - { - "name": "minecraft:warped_pressure_plate", - "id": -263 - }, - { - "name": "minecraft:warped_roots", - "id": -224 - }, - { - "name": "minecraft:warped_sign", - "id": 624 - }, - { - "name": "minecraft:warped_slab", - "id": -265 - }, - { - "name": "minecraft:warped_stairs", - "id": -255 - }, - { - "name": "minecraft:warped_standing_sign", - "id": -251 - }, - { - "name": "minecraft:warped_stem", - "id": -226 - }, - { - "name": "minecraft:warped_trapdoor", - "id": -247 - }, - { - "name": "minecraft:warped_wall_sign", - "id": -253 - }, - { - "name": "minecraft:warped_wart_block", - "id": -227 - }, - { - "name": "minecraft:water", - "id": 9 - }, - { - "name": "minecraft:water_bucket", - "id": 365 - }, - { - "name": "minecraft:waterlily", - "id": 111 - }, - { - "name": "minecraft:waxed_chiseled_copper", - "id": -764 - }, - { - "name": "minecraft:waxed_copper", - "id": -344 - }, - { - "name": "minecraft:waxed_copper_bulb", - "id": -780 - }, - { - "name": "minecraft:waxed_copper_door", - "id": -788 - }, - { - "name": "minecraft:waxed_copper_grate", - "id": -772 - }, - { - "name": "minecraft:waxed_copper_trapdoor", - "id": -796 - }, - { - "name": "minecraft:waxed_cut_copper", - "id": -351 - }, - { - "name": "minecraft:waxed_cut_copper_slab", - "id": -365 - }, - { - "name": "minecraft:waxed_cut_copper_stairs", - "id": -358 - }, - { - "name": "minecraft:waxed_double_cut_copper_slab", - "id": -372 - }, - { - "name": "minecraft:waxed_exposed_chiseled_copper", - "id": -765 - }, - { - "name": "minecraft:waxed_exposed_copper", - "id": -345 - }, - { - "name": "minecraft:waxed_exposed_copper_bulb", - "id": -781 - }, - { - "name": "minecraft:waxed_exposed_copper_door", - "id": -789 - }, - { - "name": "minecraft:waxed_exposed_copper_grate", - "id": -773 - }, - { - "name": "minecraft:waxed_exposed_copper_trapdoor", - "id": -797 - }, - { - "name": "minecraft:waxed_exposed_cut_copper", - "id": -352 - }, - { - "name": "minecraft:waxed_exposed_cut_copper_slab", - "id": -366 - }, - { - "name": "minecraft:waxed_exposed_cut_copper_stairs", - "id": -359 - }, - { - "name": "minecraft:waxed_exposed_double_cut_copper_slab", - "id": -373 - }, - { - "name": "minecraft:waxed_oxidized_chiseled_copper", - "id": -766 - }, - { - "name": "minecraft:waxed_oxidized_copper", - "id": -446 - }, - { - "name": "minecraft:waxed_oxidized_copper_bulb", - "id": -783 - }, - { - "name": "minecraft:waxed_oxidized_copper_door", - "id": -791 - }, - { - "name": "minecraft:waxed_oxidized_copper_grate", - "id": -775 - }, - { - "name": "minecraft:waxed_oxidized_copper_trapdoor", - "id": -799 - }, - { - "name": "minecraft:waxed_oxidized_cut_copper", - "id": -447 - }, - { - "name": "minecraft:waxed_oxidized_cut_copper_slab", - "id": -449 - }, - { - "name": "minecraft:waxed_oxidized_cut_copper_stairs", - "id": -448 - }, - { - "name": "minecraft:waxed_oxidized_double_cut_copper_slab", - "id": -450 - }, - { - "name": "minecraft:waxed_weathered_chiseled_copper", - "id": -767 - }, - { - "name": "minecraft:waxed_weathered_copper", - "id": -346 - }, - { - "name": "minecraft:waxed_weathered_copper_bulb", - "id": -782 - }, - { - "name": "minecraft:waxed_weathered_copper_door", - "id": -790 - }, - { - "name": "minecraft:waxed_weathered_copper_grate", - "id": -774 - }, - { - "name": "minecraft:waxed_weathered_copper_trapdoor", - "id": -798 - }, - { - "name": "minecraft:waxed_weathered_cut_copper", - "id": -353 - }, - { - "name": "minecraft:waxed_weathered_cut_copper_slab", - "id": -367 - }, - { - "name": "minecraft:waxed_weathered_cut_copper_stairs", - "id": -360 - }, - { - "name": "minecraft:waxed_weathered_double_cut_copper_slab", - "id": -374 - }, - { - "name": "minecraft:wayfinder_armor_trim_smithing_template", - "id": 699 - }, - { - "name": "minecraft:weathered_chiseled_copper", - "id": -762 - }, - { - "name": "minecraft:weathered_copper", - "id": -342 - }, - { - "name": "minecraft:weathered_copper_bulb", - "id": -778 - }, - { - "name": "minecraft:weathered_copper_door", - "id": -786 - }, - { - "name": "minecraft:weathered_copper_grate", - "id": -770 - }, - { - "name": "minecraft:weathered_copper_trapdoor", - "id": -794 - }, - { - "name": "minecraft:weathered_cut_copper", - "id": -349 - }, - { - "name": "minecraft:weathered_cut_copper_slab", - "id": -363 - }, - { - "name": "minecraft:weathered_cut_copper_stairs", - "id": -356 - }, - { - "name": "minecraft:weathered_double_cut_copper_slab", - "id": -370 - }, - { - "name": "minecraft:web", - "id": 30 - }, - { - "name": "minecraft:weeping_vines", - "id": -231 - }, - { - "name": "minecraft:wheat", - "id": 337 - }, - { - "name": "minecraft:wheat_seeds", - "id": 292 - }, - { - "name": "minecraft:white_candle", - "id": -413 - }, - { - "name": "minecraft:white_candle_cake", - "id": -430 - }, - { - "name": "minecraft:white_carpet", - "id": 171 - }, - { - "name": "minecraft:white_concrete", - "id": 236 - }, - { - "name": "minecraft:white_concrete_powder", - "id": 237 - }, - { - "name": "minecraft:white_dye", - "id": 413 - }, - { - "name": "minecraft:white_glazed_terracotta", - "id": 220 - }, - { - "name": "minecraft:white_shulker_box", - "id": 218 - }, - { - "name": "minecraft:white_stained_glass", - "id": 241 - }, - { - "name": "minecraft:white_stained_glass_pane", - "id": 160 - }, - { - "name": "minecraft:white_terracotta", - "id": 159 - }, - { - "name": "minecraft:white_wool", - "id": 35 - }, - { - "name": "minecraft:wild_armor_trim_smithing_template", - "id": 690 - }, - { - "name": "minecraft:witch_spawn_egg", - "id": 455 - }, - { - "name": "minecraft:wither_rose", - "id": -216 - }, - { - "name": "minecraft:wither_skeleton_spawn_egg", - "id": 467 - }, - { - "name": "minecraft:wither_spawn_egg", - "id": 511 - }, - { - "name": "minecraft:wolf_armor", - "id": 708 - }, - { - "name": "minecraft:wolf_spawn_egg", - "id": 442 - }, - { - "name": "minecraft:wood", - "id": -212 - }, - { - "name": "minecraft:wooden_axe", - "id": 314 - }, - { - "name": "minecraft:wooden_button", - "id": 143 - }, - { - "name": "minecraft:wooden_door", - "id": 362 - }, - { - "name": "minecraft:wooden_hoe", - "id": 332 - }, - { - "name": "minecraft:wooden_pickaxe", - "id": 313 - }, - { - "name": "minecraft:wooden_pressure_plate", - "id": 72 - }, - { - "name": "minecraft:wooden_shovel", - "id": 312 - }, - { - "name": "minecraft:wooden_slab", - "id": 158 - }, - { - "name": "minecraft:wooden_sword", - "id": 311 - }, - { - "name": "minecraft:wool", - "id": 709 - }, - { - "name": "minecraft:writable_book", - "id": 519 - }, - { - "name": "minecraft:written_book", - "id": 520 - }, - { - "name": "minecraft:yellow_candle", - "id": -417 - }, - { - "name": "minecraft:yellow_candle_cake", - "id": -434 - }, - { - "name": "minecraft:yellow_carpet", - "id": -600 - }, - { - "name": "minecraft:yellow_concrete", - "id": -631 - }, - { - "name": "minecraft:yellow_concrete_powder", - "id": -712 - }, - { - "name": "minecraft:yellow_dye", - "id": 409 - }, - { - "name": "minecraft:yellow_flower", - "id": 37 - }, - { - "name": "minecraft:yellow_glazed_terracotta", - "id": 224 - }, - { - "name": "minecraft:yellow_shulker_box", - "id": -616 - }, - { - "name": "minecraft:yellow_stained_glass", - "id": -676 - }, - { - "name": "minecraft:yellow_stained_glass_pane", - "id": -646 - }, - { - "name": "minecraft:yellow_terracotta", - "id": -727 - }, - { - "name": "minecraft:yellow_wool", - "id": -558 - }, - { - "name": "minecraft:zoglin_spawn_egg", - "id": 501 - }, - { - "name": "minecraft:zombie_horse_spawn_egg", - "id": 471 - }, - { - "name": "minecraft:zombie_pigman_spawn_egg", - "id": 451 - }, - { - "name": "minecraft:zombie_spawn_egg", - "id": 450 - }, - { - "name": "minecraft:zombie_villager_spawn_egg", - "id": 480 - } -] \ No newline at end of file diff --git a/core/src/main/resources/bedrock/runtime_item_states.1_20_70.json b/core/src/main/resources/bedrock/runtime_item_states.1_21_0.json similarity index 95% rename from core/src/main/resources/bedrock/runtime_item_states.1_20_70.json rename to core/src/main/resources/bedrock/runtime_item_states.1_21_0.json index 887b89ba1..1430a5437 100644 --- a/core/src/main/resources/bedrock/runtime_item_states.1_20_70.json +++ b/core/src/main/resources/bedrock/runtime_item_states.1_21_0.json @@ -1,7 +1,7 @@ [ { "name": "minecraft:acacia_boat", - "id": 383 + "id": 387 }, { "name": "minecraft:acacia_button", @@ -9,11 +9,11 @@ }, { "name": "minecraft:acacia_chest_boat", - "id": 653 + "id": 661 }, { "name": "minecraft:acacia_door", - "id": 567 + "id": 572 }, { "name": "minecraft:acacia_double_slab", @@ -47,9 +47,13 @@ "name": "minecraft:acacia_pressure_plate", "id": -150 }, + { + "name": "minecraft:acacia_sapling", + "id": -828 + }, { "name": "minecraft:acacia_sign", - "id": 590 + "id": 595 }, { "name": "minecraft:acacia_slab", @@ -81,7 +85,7 @@ }, { "name": "minecraft:agent_spawn_egg", - "id": 492 + "id": 497 }, { "name": "minecraft:air", @@ -89,7 +93,11 @@ }, { "name": "minecraft:allay_spawn_egg", - "id": 642 + "id": 650 + }, + { + "name": "minecraft:allium", + "id": -831 }, { "name": "minecraft:allow", @@ -105,7 +113,7 @@ }, { "name": "minecraft:amethyst_shard", - "id": 635 + "id": 643 }, { "name": "minecraft:ancient_debris", @@ -121,7 +129,7 @@ }, { "name": "minecraft:angler_pottery_sherd", - "id": 667 + "id": 675 }, { "name": "minecraft:anvil", @@ -133,35 +141,35 @@ }, { "name": "minecraft:archer_pottery_sherd", - "id": 668 + "id": 676 }, { "name": "minecraft:armadillo_scute", - "id": 709 + "id": 721 }, { "name": "minecraft:armadillo_spawn_egg", - "id": 708 + "id": 720 }, { "name": "minecraft:armor_stand", - "id": 563 + "id": 568 }, { "name": "minecraft:arms_up_pottery_sherd", - "id": 669 + "id": 677 }, { "name": "minecraft:arrow", - "id": 304 + "id": 307 }, { "name": "minecraft:axolotl_bucket", - "id": 372 + "id": 376 }, { "name": "minecraft:axolotl_spawn_egg", - "id": 507 + "id": 512 }, { "name": "minecraft:azalea", @@ -175,13 +183,17 @@ "name": "minecraft:azalea_leaves_flowered", "id": -325 }, + { + "name": "minecraft:azure_bluet", + "id": -832 + }, { "name": "minecraft:baked_potato", - "id": 282 + "id": 285 }, { "name": "minecraft:balloon", - "id": 609 + "id": 617 }, { "name": "minecraft:bamboo", @@ -197,7 +209,7 @@ }, { "name": "minecraft:bamboo_chest_raft", - "id": 665 + "id": 673 }, { "name": "minecraft:bamboo_door", @@ -245,7 +257,7 @@ }, { "name": "minecraft:bamboo_raft", - "id": 664 + "id": 672 }, { "name": "minecraft:bamboo_sapling", @@ -253,7 +265,7 @@ }, { "name": "minecraft:bamboo_sign", - "id": 663 + "id": 671 }, { "name": "minecraft:bamboo_slab", @@ -277,11 +289,11 @@ }, { "name": "minecraft:banner", - "id": 578 + "id": 583 }, { "name": "minecraft:banner_pattern", - "id": 731 + "id": 756 }, { "name": "minecraft:barrel", @@ -297,7 +309,7 @@ }, { "name": "minecraft:bat_spawn_egg", - "id": 457 + "id": 462 }, { "name": "minecraft:beacon", @@ -305,7 +317,7 @@ }, { "name": "minecraft:bed", - "id": 422 + "id": 426 }, { "name": "minecraft:bedrock", @@ -317,11 +329,11 @@ }, { "name": "minecraft:bee_spawn_egg", - "id": 499 + "id": 504 }, { "name": "minecraft:beef", - "id": 274 + "id": 277 }, { "name": "minecraft:beehive", @@ -329,15 +341,15 @@ }, { "name": "minecraft:beetroot", - "id": 286 + "id": 289 }, { "name": "minecraft:beetroot_seeds", - "id": 296 + "id": 299 }, { "name": "minecraft:beetroot_soup", - "id": 287 + "id": 290 }, { "name": "minecraft:bell", @@ -349,7 +361,7 @@ }, { "name": "minecraft:birch_boat", - "id": 380 + "id": 384 }, { "name": "minecraft:birch_button", @@ -357,11 +369,11 @@ }, { "name": "minecraft:birch_chest_boat", - "id": 650 + "id": 658 }, { "name": "minecraft:birch_door", - "id": 565 + "id": 570 }, { "name": "minecraft:birch_double_slab", @@ -395,9 +407,13 @@ "name": "minecraft:birch_pressure_plate", "id": -151 }, + { + "name": "minecraft:birch_sapling", + "id": -826 + }, { "name": "minecraft:birch_sign", - "id": 588 + "id": 593 }, { "name": "minecraft:birch_slab", @@ -445,7 +461,7 @@ }, { "name": "minecraft:black_dye", - "id": 399 + "id": 403 }, { "name": "minecraft:black_glazed_terracotta", @@ -493,7 +509,7 @@ }, { "name": "minecraft:blade_pottery_sherd", - "id": 670 + "id": 678 }, { "name": "minecraft:blast_furnace", @@ -501,19 +517,19 @@ }, { "name": "minecraft:blaze_powder", - "id": 433 + "id": 438 }, { "name": "minecraft:blaze_rod", - "id": 427 + "id": 431 }, { "name": "minecraft:blaze_spawn_egg", - "id": 460 + "id": 465 }, { "name": "minecraft:bleach", - "id": 607 + "id": 615 }, { "name": "minecraft:blue_candle", @@ -537,7 +553,7 @@ }, { "name": "minecraft:blue_dye", - "id": 403 + "id": 407 }, { "name": "minecraft:blue_glazed_terracotta", @@ -547,6 +563,10 @@ "name": "minecraft:blue_ice", "id": -11 }, + { + "name": "minecraft:blue_orchid", + "id": -830 + }, { "name": "minecraft:blue_shulker_box", "id": -623 @@ -569,15 +589,19 @@ }, { "name": "minecraft:boat", - "id": 729 + "id": 754 }, { "name": "minecraft:bogged_spawn_egg", - "id": 467 + "id": 472 + }, + { + "name": "minecraft:bolt_armor_trim_smithing_template", + "id": 717 }, { "name": "minecraft:bone", - "id": 419 + "id": 423 }, { "name": "minecraft:bone_block", @@ -585,11 +609,11 @@ }, { "name": "minecraft:bone_meal", - "id": 415 + "id": 419 }, { "name": "minecraft:book", - "id": 391 + "id": 395 }, { "name": "minecraft:bookshelf", @@ -601,44 +625,60 @@ }, { "name": "minecraft:bordure_indented_banner_pattern", - "id": 597 + "id": 602 }, { "name": "minecraft:bow", - "id": 303 + "id": 306 }, { "name": "minecraft:bowl", - "id": 324 + "id": 328 }, { "name": "minecraft:brain_coral", "id": -581 }, + { + "name": "minecraft:brain_coral_block", + "id": -849 + }, + { + "name": "minecraft:brain_coral_fan", + "id": -840 + }, { "name": "minecraft:bread", - "id": 262 + "id": 265 + }, + { + "name": "minecraft:breeze_rod", + "id": 432 }, { "name": "minecraft:breeze_spawn_egg", - "id": 506 + "id": 511 }, { "name": "minecraft:brewer_pottery_sherd", - "id": 671 + "id": 679 }, { "name": "minecraft:brewing_stand", - "id": 435 + "id": 440 }, { "name": "minecraft:brick", - "id": 387 + "id": 391 }, { "name": "minecraft:brick_block", "id": 45 }, + { + "name": "minecraft:brick_slab", + "id": -874 + }, { "name": "minecraft:brick_stairs", "id": 108 @@ -665,7 +705,7 @@ }, { "name": "minecraft:brown_dye", - "id": 402 + "id": 406 }, { "name": "minecraft:brown_glazed_terracotta", @@ -701,7 +741,7 @@ }, { "name": "minecraft:brush", - "id": 687 + "id": 698 }, { "name": "minecraft:bubble_column", @@ -711,9 +751,17 @@ "name": "minecraft:bubble_coral", "id": -582 }, + { + "name": "minecraft:bubble_coral_block", + "id": -850 + }, + { + "name": "minecraft:bubble_coral_fan", + "id": -841 + }, { "name": "minecraft:bucket", - "id": 363 + "id": 367 }, { "name": "minecraft:budding_amethyst", @@ -721,7 +769,7 @@ }, { "name": "minecraft:burn_pottery_sherd", - "id": 672 + "id": 680 }, { "name": "minecraft:cactus", @@ -729,7 +777,7 @@ }, { "name": "minecraft:cake", - "id": 421 + "id": 425 }, { "name": "minecraft:calcite", @@ -741,15 +789,15 @@ }, { "name": "minecraft:camel_spawn_egg", - "id": 666 + "id": 674 }, { "name": "minecraft:camera", - "id": 604 + "id": 612 }, { "name": "minecraft:campfire", - "id": 600 + "id": 607 }, { "name": "minecraft:candle", @@ -761,15 +809,15 @@ }, { "name": "minecraft:carpet", - "id": 712 + "id": 726 }, { "name": "minecraft:carrot", - "id": 280 + "id": 283 }, { "name": "minecraft:carrot_on_a_stick", - "id": 528 + "id": 533 }, { "name": "minecraft:carrots", @@ -785,15 +833,15 @@ }, { "name": "minecraft:cat_spawn_egg", - "id": 493 + "id": 498 }, { "name": "minecraft:cauldron", - "id": 436 + "id": 441 }, { "name": "minecraft:cave_spider_spawn_egg", - "id": 461 + "id": 466 }, { "name": "minecraft:cave_vines", @@ -809,7 +857,7 @@ }, { "name": "minecraft:chain", - "id": 630 + "id": 638 }, { "name": "minecraft:chain_command_block", @@ -817,23 +865,23 @@ }, { "name": "minecraft:chainmail_boots", - "id": 345 + "id": 349 }, { "name": "minecraft:chainmail_chestplate", - "id": 343 + "id": 347 }, { "name": "minecraft:chainmail_helmet", - "id": 342 + "id": 346 }, { "name": "minecraft:chainmail_leggings", - "id": 344 + "id": 348 }, { "name": "minecraft:charcoal", - "id": 306 + "id": 309 }, { "name": "minecraft:chemical_heat", @@ -845,7 +893,7 @@ }, { "name": "minecraft:cherry_boat", - "id": 660 + "id": 668 }, { "name": "minecraft:cherry_button", @@ -853,7 +901,7 @@ }, { "name": "minecraft:cherry_chest_boat", - "id": 661 + "id": 669 }, { "name": "minecraft:cherry_door", @@ -897,7 +945,7 @@ }, { "name": "minecraft:cherry_sign", - "id": 662 + "id": 670 }, { "name": "minecraft:cherry_slab", @@ -929,19 +977,19 @@ }, { "name": "minecraft:chest_boat", - "id": 656 + "id": 664 }, { "name": "minecraft:chest_minecart", - "id": 393 + "id": 397 }, { "name": "minecraft:chicken", - "id": 276 + "id": 279 }, { "name": "minecraft:chicken_spawn_egg", - "id": 439 + "id": 444 }, { "name": "minecraft:chiseled_bookshelf", @@ -977,7 +1025,7 @@ }, { "name": "minecraft:chorus_fruit", - "id": 569 + "id": 574 }, { "name": "minecraft:chorus_plant", @@ -989,7 +1037,7 @@ }, { "name": "minecraft:clay_ball", - "id": 388 + "id": 392 }, { "name": "minecraft:client_request_placeholder_block", @@ -997,11 +1045,11 @@ }, { "name": "minecraft:clock", - "id": 397 + "id": 401 }, { "name": "minecraft:coal", - "id": 305 + "id": 308 }, { "name": "minecraft:coal_block", @@ -1013,7 +1061,7 @@ }, { "name": "minecraft:coast_armor_trim_smithing_template", - "id": 691 + "id": 702 }, { "name": "minecraft:cobbled_deepslate", @@ -1039,6 +1087,10 @@ "name": "minecraft:cobblestone", "id": 4 }, + { + "name": "minecraft:cobblestone_slab", + "id": -873 + }, { "name": "minecraft:cobblestone_wall", "id": 139 @@ -1049,19 +1101,19 @@ }, { "name": "minecraft:cocoa_beans", - "id": 416 + "id": 420 }, { "name": "minecraft:cod", - "id": 265 + "id": 268 }, { "name": "minecraft:cod_bucket", - "id": 367 + "id": 371 }, { "name": "minecraft:cod_spawn_egg", - "id": 485 + "id": 490 }, { "name": "minecraft:colored_torch_bp", @@ -1077,15 +1129,15 @@ }, { "name": "minecraft:command_block_minecart", - "id": 574 + "id": 579 }, { "name": "minecraft:comparator", - "id": 533 + "id": 538 }, { "name": "minecraft:compass", - "id": 395 + "id": 399 }, { "name": "minecraft:composter", @@ -1093,15 +1145,15 @@ }, { "name": "minecraft:compound", - "id": 605 + "id": 613 }, { "name": "minecraft:concrete", - "id": 721 + "id": 743 }, { "name": "minecraft:concrete_powder", - "id": 722 + "id": 744 }, { "name": "minecraft:conduit", @@ -1109,35 +1161,35 @@ }, { "name": "minecraft:cooked_beef", - "id": 275 + "id": 278 }, { "name": "minecraft:cooked_chicken", - "id": 277 + "id": 280 }, { "name": "minecraft:cooked_cod", - "id": 269 + "id": 272 }, { "name": "minecraft:cooked_mutton", - "id": 562 + "id": 567 }, { "name": "minecraft:cooked_porkchop", - "id": 264 + "id": 267 }, { "name": "minecraft:cooked_rabbit", - "id": 290 + "id": 293 }, { "name": "minecraft:cooked_salmon", - "id": 270 + "id": 273 }, { "name": "minecraft:cookie", - "id": 272 + "id": 275 }, { "name": "minecraft:copper_block", @@ -1157,7 +1209,7 @@ }, { "name": "minecraft:copper_ingot", - "id": 515 + "id": 520 }, { "name": "minecraft:copper_ore", @@ -1169,19 +1221,19 @@ }, { "name": "minecraft:coral", - "id": 719 + "id": 740 }, { "name": "minecraft:coral_block", - "id": -132 + "id": 729 }, { "name": "minecraft:coral_fan", - "id": -133 + "id": 730 }, { "name": "minecraft:coral_fan_dead", - "id": -134 + "id": 731 }, { "name": "minecraft:coral_fan_hang", @@ -1195,9 +1247,13 @@ "name": "minecraft:coral_fan_hang3", "id": -137 }, + { + "name": "minecraft:cornflower", + "id": -838 + }, { "name": "minecraft:cow_spawn_egg", - "id": 440 + "id": 445 }, { "name": "minecraft:cracked_deepslate_bricks", @@ -1225,11 +1281,11 @@ }, { "name": "minecraft:creeper_banner_pattern", - "id": 593 + "id": 598 }, { "name": "minecraft:creeper_spawn_egg", - "id": 445 + "id": 450 }, { "name": "minecraft:crimson_button", @@ -1237,7 +1293,7 @@ }, { "name": "minecraft:crimson_door", - "id": 627 + "id": 635 }, { "name": "minecraft:crimson_double_slab", @@ -1281,7 +1337,7 @@ }, { "name": "minecraft:crimson_sign", - "id": 625 + "id": 633 }, { "name": "minecraft:crimson_slab", @@ -1309,7 +1365,7 @@ }, { "name": "minecraft:crossbow", - "id": 586 + "id": 591 }, { "name": "minecraft:crying_obsidian", @@ -1349,7 +1405,7 @@ }, { "name": "minecraft:cyan_dye", - "id": 405 + "id": 409 }, { "name": "minecraft:cyan_glazed_terracotta", @@ -1377,11 +1433,11 @@ }, { "name": "minecraft:danger_pottery_sherd", - "id": 673 + "id": 681 }, { "name": "minecraft:dark_oak_boat", - "id": 384 + "id": 388 }, { "name": "minecraft:dark_oak_button", @@ -1389,11 +1445,11 @@ }, { "name": "minecraft:dark_oak_chest_boat", - "id": 654 + "id": 662 }, { "name": "minecraft:dark_oak_door", - "id": 568 + "id": 573 }, { "name": "minecraft:dark_oak_double_slab", @@ -1427,9 +1483,13 @@ "name": "minecraft:dark_oak_pressure_plate", "id": -152 }, + { + "name": "minecraft:dark_oak_sapling", + "id": -829 + }, { "name": "minecraft:dark_oak_sign", - "id": 591 + "id": 596 }, { "name": "minecraft:dark_oak_slab", @@ -1471,22 +1531,62 @@ "name": "minecraft:dead_brain_coral", "id": -586 }, + { + "name": "minecraft:dead_brain_coral_block", + "id": -854 + }, + { + "name": "minecraft:dead_brain_coral_fan", + "id": -844 + }, { "name": "minecraft:dead_bubble_coral", "id": -587 }, + { + "name": "minecraft:dead_bubble_coral_block", + "id": -855 + }, + { + "name": "minecraft:dead_bubble_coral_fan", + "id": -845 + }, { "name": "minecraft:dead_fire_coral", "id": -588 }, + { + "name": "minecraft:dead_fire_coral_block", + "id": -856 + }, + { + "name": "minecraft:dead_fire_coral_fan", + "id": -846 + }, { "name": "minecraft:dead_horn_coral", "id": -589 }, + { + "name": "minecraft:dead_horn_coral_block", + "id": -857 + }, + { + "name": "minecraft:dead_horn_coral_fan", + "id": -847 + }, { "name": "minecraft:dead_tube_coral", "id": -585 }, + { + "name": "minecraft:dead_tube_coral_block", + "id": -853 + }, + { + "name": "minecraft:dead_tube_coral_fan", + "id": -134 + }, { "name": "minecraft:deadbush", "id": 32 @@ -1581,11 +1681,11 @@ }, { "name": "minecraft:diamond", - "id": 307 + "id": 310 }, { "name": "minecraft:diamond_axe", - "id": 322 + "id": 325 }, { "name": "minecraft:diamond_block", @@ -1593,27 +1693,27 @@ }, { "name": "minecraft:diamond_boots", - "id": 353 + "id": 357 }, { "name": "minecraft:diamond_chestplate", - "id": 351 + "id": 355 }, { "name": "minecraft:diamond_helmet", - "id": 350 + "id": 354 }, { "name": "minecraft:diamond_hoe", - "id": 335 + "id": 339 }, { "name": "minecraft:diamond_horse_armor", - "id": 544 + "id": 549 }, { "name": "minecraft:diamond_leggings", - "id": 352 + "id": 356 }, { "name": "minecraft:diamond_ore", @@ -1621,15 +1721,15 @@ }, { "name": "minecraft:diamond_pickaxe", - "id": 321 + "id": 324 }, { "name": "minecraft:diamond_shovel", - "id": 320 + "id": 323 }, { "name": "minecraft:diamond_sword", - "id": 319 + "id": 322 }, { "name": "minecraft:diorite", @@ -1649,7 +1749,7 @@ }, { "name": "minecraft:disc_fragment_5", - "id": 648 + "id": 656 }, { "name": "minecraft:dispenser", @@ -1657,11 +1757,11 @@ }, { "name": "minecraft:dolphin_spawn_egg", - "id": 489 + "id": 494 }, { "name": "minecraft:donkey_spawn_egg", - "id": 470 + "id": 475 }, { "name": "minecraft:double_cut_copper_slab", @@ -1669,7 +1769,7 @@ }, { "name": "minecraft:double_plant", - "id": 175 + "id": 738 }, { "name": "minecraft:double_stone_block_slab", @@ -1689,7 +1789,7 @@ }, { "name": "minecraft:dragon_breath", - "id": 571 + "id": 576 }, { "name": "minecraft:dragon_egg", @@ -1697,7 +1797,7 @@ }, { "name": "minecraft:dried_kelp", - "id": 271 + "id": 274 }, { "name": "minecraft:dried_kelp_block", @@ -1713,27 +1813,27 @@ }, { "name": "minecraft:drowned_spawn_egg", - "id": 488 + "id": 493 }, { "name": "minecraft:dune_armor_trim_smithing_template", - "id": 690 + "id": 701 }, { "name": "minecraft:dye", - "id": 730 + "id": 755 }, { "name": "minecraft:echo_shard", - "id": 658 + "id": 666 }, { "name": "minecraft:egg", - "id": 394 + "id": 398 }, { "name": "minecraft:elder_guardian_spawn_egg", - "id": 476 + "id": 481 }, { "name": "minecraft:element_0", @@ -2213,11 +2313,11 @@ }, { "name": "minecraft:elytra", - "id": 575 + "id": 580 }, { "name": "minecraft:emerald", - "id": 523 + "id": 528 }, { "name": "minecraft:emerald_block", @@ -2229,15 +2329,15 @@ }, { "name": "minecraft:empty_map", - "id": 526 + "id": 531 }, { "name": "minecraft:enchanted_book", - "id": 532 + "id": 537 }, { "name": "minecraft:enchanted_golden_apple", - "id": 260 + "id": 263 }, { "name": "minecraft:enchanting_table", @@ -2253,7 +2353,7 @@ }, { "name": "minecraft:end_crystal", - "id": 733 + "id": 758 }, { "name": "minecraft:end_gateway", @@ -2281,35 +2381,35 @@ }, { "name": "minecraft:ender_dragon_spawn_egg", - "id": 512 + "id": 517 }, { "name": "minecraft:ender_eye", - "id": 437 + "id": 442 }, { "name": "minecraft:ender_pearl", - "id": 426 + "id": 430 }, { "name": "minecraft:enderman_spawn_egg", - "id": 446 + "id": 451 }, { "name": "minecraft:endermite_spawn_egg", - "id": 464 + "id": 469 }, { "name": "minecraft:evoker_spawn_egg", - "id": 480 + "id": 485 }, { "name": "minecraft:experience_bottle", - "id": 519 + "id": 524 }, { "name": "minecraft:explorer_pottery_sherd", - "id": 674 + "id": 682 }, { "name": "minecraft:exposed_chiseled_copper", @@ -2353,7 +2453,7 @@ }, { "name": "minecraft:eye_armor_trim_smithing_template", - "id": 694 + "id": 705 }, { "name": "minecraft:farmland", @@ -2361,11 +2461,11 @@ }, { "name": "minecraft:feather", - "id": 330 + "id": 334 }, { "name": "minecraft:fence", - "id": 714 + "id": 728 }, { "name": "minecraft:fence_gate", @@ -2373,15 +2473,19 @@ }, { "name": "minecraft:fermented_spider_eye", - "id": 432 + "id": 437 + }, + { + "name": "minecraft:fern", + "id": -848 }, { "name": "minecraft:field_masoned_banner_pattern", - "id": 596 + "id": 601 }, { "name": "minecraft:filled_map", - "id": 424 + "id": 428 }, { "name": "minecraft:fire", @@ -2389,23 +2493,31 @@ }, { "name": "minecraft:fire_charge", - "id": 520 + "id": 525 }, { "name": "minecraft:fire_coral", "id": -583 }, + { + "name": "minecraft:fire_coral_block", + "id": -851 + }, + { + "name": "minecraft:fire_coral_fan", + "id": -842 + }, { "name": "minecraft:firework_rocket", - "id": 530 + "id": 535 }, { "name": "minecraft:firework_star", - "id": 531 + "id": 536 }, { "name": "minecraft:fishing_rod", - "id": 396 + "id": 400 }, { "name": "minecraft:fletching_table", @@ -2413,19 +2525,31 @@ }, { "name": "minecraft:flint", - "id": 359 + "id": 363 }, { "name": "minecraft:flint_and_steel", - "id": 302 + "id": 305 + }, + { + "name": "minecraft:flow_armor_trim_smithing_template", + "id": 716 + }, + { + "name": "minecraft:flow_banner_pattern", + "id": 605 + }, + { + "name": "minecraft:flow_pottery_sherd", + "id": 683 }, { "name": "minecraft:flower_banner_pattern", - "id": 592 + "id": 597 }, { "name": "minecraft:flower_pot", - "id": 525 + "id": 530 }, { "name": "minecraft:flowering_azalea", @@ -2441,15 +2565,15 @@ }, { "name": "minecraft:fox_spawn_egg", - "id": 495 + "id": 500 }, { "name": "minecraft:frame", - "id": 524 + "id": 529 }, { "name": "minecraft:friend_pottery_sherd", - "id": 675 + "id": 684 }, { "name": "minecraft:frog_spawn", @@ -2457,7 +2581,7 @@ }, { "name": "minecraft:frog_spawn_egg", - "id": 639 + "id": 647 }, { "name": "minecraft:frosted_ice", @@ -2469,11 +2593,11 @@ }, { "name": "minecraft:ghast_spawn_egg", - "id": 458 + "id": 463 }, { "name": "minecraft:ghast_tear", - "id": 428 + "id": 433 }, { "name": "minecraft:gilded_blackstone", @@ -2485,7 +2609,7 @@ }, { "name": "minecraft:glass_bottle", - "id": 431 + "id": 436 }, { "name": "minecraft:glass_pane", @@ -2493,23 +2617,23 @@ }, { "name": "minecraft:glistering_melon_slice", - "id": 438 + "id": 443 }, { "name": "minecraft:globe_banner_pattern", - "id": 599 + "id": 604 }, { "name": "minecraft:glow_berries", - "id": 734 + "id": 759 }, { "name": "minecraft:glow_frame", - "id": 634 + "id": 642 }, { "name": "minecraft:glow_ink_sac", - "id": 514 + "id": 519 }, { "name": "minecraft:glow_lichen", @@ -2517,11 +2641,11 @@ }, { "name": "minecraft:glow_squid_spawn_egg", - "id": 509 + "id": 514 }, { "name": "minecraft:glow_stick", - "id": 612 + "id": 620 }, { "name": "minecraft:glowingobsidian", @@ -2533,15 +2657,15 @@ }, { "name": "minecraft:glowstone_dust", - "id": 398 + "id": 402 }, { "name": "minecraft:goat_horn", - "id": 638 + "id": 646 }, { "name": "minecraft:goat_spawn_egg", - "id": 508 + "id": 513 }, { "name": "minecraft:gold_block", @@ -2549,11 +2673,11 @@ }, { "name": "minecraft:gold_ingot", - "id": 309 + "id": 312 }, { "name": "minecraft:gold_nugget", - "id": 429 + "id": 434 }, { "name": "minecraft:gold_ore", @@ -2561,43 +2685,43 @@ }, { "name": "minecraft:golden_apple", - "id": 259 + "id": 262 }, { "name": "minecraft:golden_axe", - "id": 328 + "id": 332 }, { "name": "minecraft:golden_boots", - "id": 357 + "id": 361 }, { "name": "minecraft:golden_carrot", - "id": 284 + "id": 287 }, { "name": "minecraft:golden_chestplate", - "id": 355 + "id": 359 }, { "name": "minecraft:golden_helmet", - "id": 354 + "id": 358 }, { "name": "minecraft:golden_hoe", - "id": 336 + "id": 340 }, { "name": "minecraft:golden_horse_armor", - "id": 543 + "id": 548 }, { "name": "minecraft:golden_leggings", - "id": 356 + "id": 360 }, { "name": "minecraft:golden_pickaxe", - "id": 327 + "id": 331 }, { "name": "minecraft:golden_rail", @@ -2605,11 +2729,11 @@ }, { "name": "minecraft:golden_shovel", - "id": 326 + "id": 330 }, { "name": "minecraft:golden_sword", - "id": 325 + "id": 329 }, { "name": "minecraft:granite", @@ -2653,7 +2777,7 @@ }, { "name": "minecraft:gray_dye", - "id": 407 + "id": 411 }, { "name": "minecraft:gray_glazed_terracotta", @@ -2701,7 +2825,7 @@ }, { "name": "minecraft:green_dye", - "id": 401 + "id": 405 }, { "name": "minecraft:green_glazed_terracotta", @@ -2733,11 +2857,19 @@ }, { "name": "minecraft:guardian_spawn_egg", - "id": 465 + "id": 470 }, { "name": "minecraft:gunpowder", - "id": 331 + "id": 335 + }, + { + "name": "minecraft:guster_banner_pattern", + "id": 606 + }, + { + "name": "minecraft:guster_pottery_sherd", + "id": 685 }, { "name": "minecraft:hanging_roots", @@ -2865,11 +2997,11 @@ }, { "name": "minecraft:hard_stained_glass", - "id": 727 + "id": 752 }, { "name": "minecraft:hard_stained_glass_pane", - "id": 728 + "id": 753 }, { "name": "minecraft:hard_white_stained_glass", @@ -2897,15 +3029,19 @@ }, { "name": "minecraft:heart_of_the_sea", - "id": 582 + "id": 587 }, { "name": "minecraft:heart_pottery_sherd", - "id": 676 + "id": 686 }, { "name": "minecraft:heartbreak_pottery_sherd", - "id": 677 + "id": 687 + }, + { + "name": "minecraft:heavy_core", + "id": -316 }, { "name": "minecraft:heavy_weighted_pressure_plate", @@ -2913,7 +3049,7 @@ }, { "name": "minecraft:hoglin_spawn_egg", - "id": 501 + "id": 506 }, { "name": "minecraft:honey_block", @@ -2921,11 +3057,11 @@ }, { "name": "minecraft:honey_bottle", - "id": 603 + "id": 610 }, { "name": "minecraft:honeycomb", - "id": 602 + "id": 609 }, { "name": "minecraft:honeycomb_block", @@ -2933,31 +3069,39 @@ }, { "name": "minecraft:hopper", - "id": 538 + "id": 543 }, { "name": "minecraft:hopper_minecart", - "id": 537 + "id": 542 }, { "name": "minecraft:horn_coral", "id": -584 }, + { + "name": "minecraft:horn_coral_block", + "id": -852 + }, + { + "name": "minecraft:horn_coral_fan", + "id": -843 + }, { "name": "minecraft:horse_spawn_egg", - "id": 462 + "id": 467 }, { "name": "minecraft:host_armor_trim_smithing_template", - "id": 704 + "id": 715 }, { "name": "minecraft:howl_pottery_sherd", - "id": 678 + "id": 688 }, { "name": "minecraft:husk_spawn_egg", - "id": 468 + "id": 473 }, { "name": "minecraft:ice", @@ -2965,7 +3109,7 @@ }, { "name": "minecraft:ice_bomb", - "id": 606 + "id": 614 }, { "name": "minecraft:infested_deepslate", @@ -2981,7 +3125,7 @@ }, { "name": "minecraft:ink_sac", - "id": 417 + "id": 421 }, { "name": "minecraft:invisible_bedrock", @@ -2989,7 +3133,7 @@ }, { "name": "minecraft:iron_axe", - "id": 301 + "id": 304 }, { "name": "minecraft:iron_bars", @@ -3001,43 +3145,43 @@ }, { "name": "minecraft:iron_boots", - "id": 349 + "id": 353 }, { "name": "minecraft:iron_chestplate", - "id": 347 + "id": 351 }, { "name": "minecraft:iron_door", - "id": 375 + "id": 379 }, { "name": "minecraft:iron_golem_spawn_egg", - "id": 510 + "id": 515 }, { "name": "minecraft:iron_helmet", - "id": 346 + "id": 350 }, { "name": "minecraft:iron_hoe", - "id": 334 + "id": 338 }, { "name": "minecraft:iron_horse_armor", - "id": 542 + "id": 547 }, { "name": "minecraft:iron_ingot", - "id": 308 + "id": 311 }, { "name": "minecraft:iron_leggings", - "id": 348 + "id": 352 }, { "name": "minecraft:iron_nugget", - "id": 580 + "id": 585 }, { "name": "minecraft:iron_ore", @@ -3045,15 +3189,15 @@ }, { "name": "minecraft:iron_pickaxe", - "id": 300 + "id": 303 }, { "name": "minecraft:iron_shovel", - "id": 299 + "id": 302 }, { "name": "minecraft:iron_sword", - "id": 310 + "id": 313 }, { "name": "minecraft:iron_trapdoor", @@ -3185,7 +3329,7 @@ }, { "name": "minecraft:jungle_boat", - "id": 381 + "id": 385 }, { "name": "minecraft:jungle_button", @@ -3193,11 +3337,11 @@ }, { "name": "minecraft:jungle_chest_boat", - "id": 651 + "id": 659 }, { "name": "minecraft:jungle_door", - "id": 566 + "id": 571 }, { "name": "minecraft:jungle_double_slab", @@ -3231,9 +3375,13 @@ "name": "minecraft:jungle_pressure_plate", "id": -153 }, + { + "name": "minecraft:jungle_sapling", + "id": -827 + }, { "name": "minecraft:jungle_sign", - "id": 589 + "id": 594 }, { "name": "minecraft:jungle_slab", @@ -3261,7 +3409,7 @@ }, { "name": "minecraft:kelp", - "id": 386 + "id": 390 }, { "name": "minecraft:ladder", @@ -3277,7 +3425,7 @@ }, { "name": "minecraft:lapis_lazuli", - "id": 418 + "id": 422 }, { "name": "minecraft:lapis_ore", @@ -3287,49 +3435,53 @@ "name": "minecraft:large_amethyst_bud", "id": -330 }, + { + "name": "minecraft:large_fern", + "id": -865 + }, { "name": "minecraft:lava", "id": 11 }, { "name": "minecraft:lava_bucket", - "id": 366 + "id": 370 }, { "name": "minecraft:lead", - "id": 558 + "id": 563 }, { "name": "minecraft:leather", - "id": 385 + "id": 389 }, { "name": "minecraft:leather_boots", - "id": 341 + "id": 345 }, { "name": "minecraft:leather_chestplate", - "id": 339 + "id": 343 }, { "name": "minecraft:leather_helmet", - "id": 338 + "id": 342 }, { "name": "minecraft:leather_horse_armor", - "id": 541 + "id": 546 }, { "name": "minecraft:leather_leggings", - "id": 340 + "id": 344 }, { "name": "minecraft:leaves", - "id": 715 + "id": 733 }, { "name": "minecraft:leaves2", - "id": 716 + "id": 734 }, { "name": "minecraft:lectern", @@ -3365,7 +3517,7 @@ }, { "name": "minecraft:light_blue_dye", - "id": 411 + "id": 415 }, { "name": "minecraft:light_blue_glazed_terracotta", @@ -3413,7 +3565,7 @@ }, { "name": "minecraft:light_gray_dye", - "id": 406 + "id": 410 }, { "name": "minecraft:light_gray_shulker_box", @@ -3443,6 +3595,14 @@ "name": "minecraft:lightning_rod", "id": -312 }, + { + "name": "minecraft:lilac", + "id": -863 + }, + { + "name": "minecraft:lily_of_the_valley", + "id": -839 + }, { "name": "minecraft:lime_candle", "id": -418 @@ -3465,7 +3625,7 @@ }, { "name": "minecraft:lime_dye", - "id": 409 + "id": 413 }, { "name": "minecraft:lime_glazed_terracotta", @@ -3493,7 +3653,7 @@ }, { "name": "minecraft:lingering_potion", - "id": 573 + "id": 578 }, { "name": "minecraft:lit_blast_furnace", @@ -3525,7 +3685,7 @@ }, { "name": "minecraft:llama_spawn_egg", - "id": 478 + "id": 483 }, { "name": "minecraft:lodestone", @@ -3533,20 +3693,24 @@ }, { "name": "minecraft:lodestone_compass", - "id": 613 + "id": 621 }, { "name": "minecraft:log", - "id": 713 + "id": 727 }, { "name": "minecraft:log2", - "id": 720 + "id": 742 }, { "name": "minecraft:loom", "id": -204 }, + { + "name": "minecraft:mace", + "id": 326 + }, { "name": "minecraft:magenta_candle", "id": -415 @@ -3569,7 +3733,7 @@ }, { "name": "minecraft:magenta_dye", - "id": 412 + "id": 416 }, { "name": "minecraft:magenta_glazed_terracotta", @@ -3601,15 +3765,15 @@ }, { "name": "minecraft:magma_cream", - "id": 434 + "id": 439 }, { "name": "minecraft:magma_cube_spawn_egg", - "id": 459 + "id": 464 }, { "name": "minecraft:mangrove_boat", - "id": 646 + "id": 654 }, { "name": "minecraft:mangrove_button", @@ -3617,11 +3781,11 @@ }, { "name": "minecraft:mangrove_chest_boat", - "id": 655 + "id": 663 }, { "name": "minecraft:mangrove_door", - "id": 644 + "id": 652 }, { "name": "minecraft:mangrove_double_slab", @@ -3665,7 +3829,7 @@ }, { "name": "minecraft:mangrove_sign", - "id": 645 + "id": 653 }, { "name": "minecraft:mangrove_slab", @@ -3693,7 +3857,7 @@ }, { "name": "minecraft:medicine", - "id": 610 + "id": 618 }, { "name": "minecraft:medium_amethyst_bud", @@ -3705,11 +3869,11 @@ }, { "name": "minecraft:melon_seeds", - "id": 294 + "id": 297 }, { "name": "minecraft:melon_slice", - "id": 273 + "id": 276 }, { "name": "minecraft:melon_stem", @@ -3717,15 +3881,15 @@ }, { "name": "minecraft:milk_bucket", - "id": 364 + "id": 368 }, { "name": "minecraft:minecart", - "id": 373 + "id": 377 }, { "name": "minecraft:miner_pottery_sherd", - "id": 679 + "id": 689 }, { "name": "minecraft:mob_spawner", @@ -3733,7 +3897,7 @@ }, { "name": "minecraft:mojang_banner_pattern", - "id": 595 + "id": 600 }, { "name": "minecraft:monster_egg", @@ -3741,7 +3905,7 @@ }, { "name": "minecraft:mooshroom_spawn_egg", - "id": 444 + "id": 449 }, { "name": "minecraft:moss_block", @@ -3765,7 +3929,7 @@ }, { "name": "minecraft:mourner_pottery_sherd", - "id": 680 + "id": 690 }, { "name": "minecraft:moving_block", @@ -3801,91 +3965,103 @@ }, { "name": "minecraft:mule_spawn_egg", - "id": 471 + "id": 476 }, { "name": "minecraft:mushroom_stew", - "id": 261 + "id": 264 }, { "name": "minecraft:music_disc_11", - "id": 555 + "id": 560 }, { "name": "minecraft:music_disc_13", - "id": 545 - }, - { - "name": "minecraft:music_disc_5", - "id": 647 - }, - { - "name": "minecraft:music_disc_blocks", - "id": 547 - }, - { - "name": "minecraft:music_disc_cat", - "id": 546 - }, - { - "name": "minecraft:music_disc_chirp", - "id": 548 - }, - { - "name": "minecraft:music_disc_far", - "id": 549 - }, - { - "name": "minecraft:music_disc_mall", "id": 550 }, { - "name": "minecraft:music_disc_mellohi", - "id": 551 + "name": "minecraft:music_disc_5", + "id": 655 }, { - "name": "minecraft:music_disc_otherside", - "id": 637 - }, - { - "name": "minecraft:music_disc_pigstep", - "id": 631 - }, - { - "name": "minecraft:music_disc_relic", - "id": 705 - }, - { - "name": "minecraft:music_disc_stal", + "name": "minecraft:music_disc_blocks", "id": 552 }, { - "name": "minecraft:music_disc_strad", + "name": "minecraft:music_disc_cat", + "id": 551 + }, + { + "name": "minecraft:music_disc_chirp", "id": 553 }, { - "name": "minecraft:music_disc_wait", - "id": 556 + "name": "minecraft:music_disc_creator", + "id": 749 }, { - "name": "minecraft:music_disc_ward", + "name": "minecraft:music_disc_creator_music_box", + "id": 750 + }, + { + "name": "minecraft:music_disc_far", "id": 554 }, { - "name": "minecraft:mutton", + "name": "minecraft:music_disc_mall", + "id": 555 + }, + { + "name": "minecraft:music_disc_mellohi", + "id": 556 + }, + { + "name": "minecraft:music_disc_otherside", + "id": 645 + }, + { + "name": "minecraft:music_disc_pigstep", + "id": 639 + }, + { + "name": "minecraft:music_disc_precipice", + "id": 751 + }, + { + "name": "minecraft:music_disc_relic", + "id": 718 + }, + { + "name": "minecraft:music_disc_stal", + "id": 557 + }, + { + "name": "minecraft:music_disc_strad", + "id": 558 + }, + { + "name": "minecraft:music_disc_wait", "id": 561 }, + { + "name": "minecraft:music_disc_ward", + "id": 559 + }, + { + "name": "minecraft:mutton", + "id": 566 + }, { "name": "minecraft:mycelium", "id": 110 }, { "name": "minecraft:name_tag", - "id": 559 + "id": 564 }, { "name": "minecraft:nautilus_shell", - "id": 581 + "id": 586 }, { "name": "minecraft:nether_brick", @@ -3895,6 +4071,10 @@ "name": "minecraft:nether_brick_fence", "id": 113 }, + { + "name": "minecraft:nether_brick_slab", + "id": -877 + }, { "name": "minecraft:nether_brick_stairs", "id": 114 @@ -3905,15 +4085,15 @@ }, { "name": "minecraft:nether_sprouts", - "id": 632 + "id": 640 }, { "name": "minecraft:nether_star", - "id": 529 + "id": 534 }, { "name": "minecraft:nether_wart", - "id": 295 + "id": 298 }, { "name": "minecraft:nether_wart_block", @@ -3921,11 +4101,11 @@ }, { "name": "minecraft:netherbrick", - "id": 534 + "id": 539 }, { "name": "minecraft:netherite_axe", - "id": 617 + "id": 625 }, { "name": "minecraft:netherite_block", @@ -3933,47 +4113,47 @@ }, { "name": "minecraft:netherite_boots", - "id": 623 + "id": 631 }, { "name": "minecraft:netherite_chestplate", - "id": 621 + "id": 629 }, { "name": "minecraft:netherite_helmet", - "id": 620 + "id": 628 }, { "name": "minecraft:netherite_hoe", - "id": 618 + "id": 626 }, { "name": "minecraft:netherite_ingot", - "id": 619 + "id": 627 }, { "name": "minecraft:netherite_leggings", - "id": 622 + "id": 630 }, { "name": "minecraft:netherite_pickaxe", - "id": 616 - }, - { - "name": "minecraft:netherite_scrap", "id": 624 }, + { + "name": "minecraft:netherite_scrap", + "id": 632 + }, { "name": "minecraft:netherite_shovel", - "id": 615 + "id": 623 }, { "name": "minecraft:netherite_sword", - "id": 614 + "id": 622 }, { "name": "minecraft:netherite_upgrade_smithing_template", - "id": 688 + "id": 699 }, { "name": "minecraft:netherrack", @@ -3993,15 +4173,15 @@ }, { "name": "minecraft:npc_spawn_egg", - "id": 475 + "id": 480 }, { "name": "minecraft:oak_boat", - "id": 379 + "id": 383 }, { "name": "minecraft:oak_chest_boat", - "id": 649 + "id": 657 }, { "name": "minecraft:oak_double_slab", @@ -4027,9 +4207,13 @@ "name": "minecraft:oak_planks", "id": 5 }, + { + "name": "minecraft:oak_sapling", + "id": 6 + }, { "name": "minecraft:oak_sign", - "id": 361 + "id": 365 }, { "name": "minecraft:oak_slab", @@ -4053,12 +4237,20 @@ }, { "name": "minecraft:ocelot_spawn_egg", - "id": 455 + "id": 460 }, { "name": "minecraft:ochre_froglight", "id": -471 }, + { + "name": "minecraft:ominous_bottle", + "id": 611 + }, + { + "name": "minecraft:ominous_trial_key", + "id": 258 + }, { "name": "minecraft:orange_candle", "id": -414 @@ -4081,7 +4273,7 @@ }, { "name": "minecraft:orange_dye", - "id": 413 + "id": 417 }, { "name": "minecraft:orange_glazed_terracotta", @@ -4103,10 +4295,18 @@ "name": "minecraft:orange_terracotta", "id": -724 }, + { + "name": "minecraft:orange_tulip", + "id": -834 + }, { "name": "minecraft:orange_wool", "id": -557 }, + { + "name": "minecraft:oxeye_daisy", + "id": -837 + }, { "name": "minecraft:oxidized_chiseled_copper", "id": -763 @@ -4157,51 +4357,59 @@ }, { "name": "minecraft:painting", - "id": 360 + "id": 364 }, { "name": "minecraft:panda_spawn_egg", - "id": 494 + "id": 499 }, { "name": "minecraft:paper", - "id": 390 + "id": 394 }, { "name": "minecraft:parrot_spawn_egg", - "id": 483 + "id": 488 }, { "name": "minecraft:pearlescent_froglight", "id": -469 }, + { + "name": "minecraft:peony", + "id": -867 + }, + { + "name": "minecraft:petrified_oak_slab", + "id": -902 + }, { "name": "minecraft:phantom_membrane", - "id": 585 + "id": 590 }, { "name": "minecraft:phantom_spawn_egg", - "id": 491 + "id": 496 }, { "name": "minecraft:pig_spawn_egg", - "id": 441 + "id": 446 }, { "name": "minecraft:piglin_banner_pattern", - "id": 598 + "id": 603 }, { "name": "minecraft:piglin_brute_spawn_egg", - "id": 504 + "id": 509 }, { "name": "minecraft:piglin_spawn_egg", - "id": 502 + "id": 507 }, { "name": "minecraft:pillager_spawn_egg", - "id": 496 + "id": 501 }, { "name": "minecraft:pink_candle", @@ -4225,7 +4433,7 @@ }, { "name": "minecraft:pink_dye", - "id": 408 + "id": 412 }, { "name": "minecraft:pink_glazed_terracotta", @@ -4251,6 +4459,10 @@ "name": "minecraft:pink_terracotta", "id": -729 }, + { + "name": "minecraft:pink_tulip", + "id": -836 + }, { "name": "minecraft:pink_wool", "id": -566 @@ -4273,15 +4485,15 @@ }, { "name": "minecraft:pitcher_pod", - "id": 298 + "id": 301 }, { "name": "minecraft:planks", - "id": 718 + "id": 739 }, { "name": "minecraft:plenty_pottery_sherd", - "id": 681 + "id": 691 }, { "name": "minecraft:podzol", @@ -4293,11 +4505,11 @@ }, { "name": "minecraft:poisonous_potato", - "id": 283 + "id": 286 }, { "name": "minecraft:polar_bear_spawn_egg", - "id": 477 + "id": 482 }, { "name": "minecraft:polished_andesite", @@ -4417,11 +4629,15 @@ }, { "name": "minecraft:popped_chorus_fruit", - "id": 570 + "id": 575 + }, + { + "name": "minecraft:poppy", + "id": 38 }, { "name": "minecraft:porkchop", - "id": 263 + "id": 266 }, { "name": "minecraft:portal", @@ -4429,7 +4645,7 @@ }, { "name": "minecraft:potato", - "id": 281 + "id": 284 }, { "name": "minecraft:potatoes", @@ -4437,7 +4653,7 @@ }, { "name": "minecraft:potion", - "id": 430 + "id": 435 }, { "name": "minecraft:powder_snow", @@ -4445,7 +4661,7 @@ }, { "name": "minecraft:powder_snow_bucket", - "id": 371 + "id": 375 }, { "name": "minecraft:powered_comparator", @@ -4465,11 +4681,11 @@ }, { "name": "minecraft:prismarine_crystals", - "id": 560 + "id": 565 }, { "name": "minecraft:prismarine_shard", - "id": 576 + "id": 581 }, { "name": "minecraft:prismarine_stairs", @@ -4477,19 +4693,19 @@ }, { "name": "minecraft:prize_pottery_sherd", - "id": 682 + "id": 692 }, { "name": "minecraft:pufferfish", - "id": 268 + "id": 271 }, { "name": "minecraft:pufferfish_bucket", - "id": 370 + "id": 374 }, { "name": "minecraft:pufferfish_spawn_egg", - "id": 486 + "id": 491 }, { "name": "minecraft:pumpkin", @@ -4497,11 +4713,11 @@ }, { "name": "minecraft:pumpkin_pie", - "id": 285 + "id": 288 }, { "name": "minecraft:pumpkin_seeds", - "id": 293 + "id": 296 }, { "name": "minecraft:pumpkin_stem", @@ -4529,7 +4745,7 @@ }, { "name": "minecraft:purple_dye", - "id": 404 + "id": 408 }, { "name": "minecraft:purple_glazed_terracotta", @@ -4565,7 +4781,7 @@ }, { "name": "minecraft:quartz", - "id": 535 + "id": 540 }, { "name": "minecraft:quartz_block", @@ -4579,29 +4795,33 @@ "name": "minecraft:quartz_ore", "id": 153 }, + { + "name": "minecraft:quartz_slab", + "id": -876 + }, { "name": "minecraft:quartz_stairs", "id": 156 }, { "name": "minecraft:rabbit", - "id": 289 + "id": 292 }, { "name": "minecraft:rabbit_foot", - "id": 539 + "id": 544 }, { "name": "minecraft:rabbit_hide", - "id": 540 + "id": 545 }, { "name": "minecraft:rabbit_spawn_egg", - "id": 463 + "id": 468 }, { "name": "minecraft:rabbit_stew", - "id": 291 + "id": 294 }, { "name": "minecraft:rail", @@ -4609,19 +4829,19 @@ }, { "name": "minecraft:raiser_armor_trim_smithing_template", - "id": 702 + "id": 713 }, { "name": "minecraft:rapid_fertilizer", - "id": 608 + "id": 616 }, { "name": "minecraft:ravager_spawn_egg", - "id": 498 + "id": 503 }, { "name": "minecraft:raw_copper", - "id": 518 + "id": 523 }, { "name": "minecraft:raw_copper_block", @@ -4629,7 +4849,7 @@ }, { "name": "minecraft:raw_gold", - "id": 517 + "id": 522 }, { "name": "minecraft:raw_gold_block", @@ -4637,7 +4857,7 @@ }, { "name": "minecraft:raw_iron", - "id": 516 + "id": 521 }, { "name": "minecraft:raw_iron_block", @@ -4645,7 +4865,7 @@ }, { "name": "minecraft:recovery_compass", - "id": 657 + "id": 665 }, { "name": "minecraft:red_candle", @@ -4669,11 +4889,11 @@ }, { "name": "minecraft:red_dye", - "id": 400 + "id": 404 }, { "name": "minecraft:red_flower", - "id": 38 + "id": 737 }, { "name": "minecraft:red_glazed_terracotta", @@ -4719,13 +4939,17 @@ "name": "minecraft:red_terracotta", "id": -737 }, + { + "name": "minecraft:red_tulip", + "id": -833 + }, { "name": "minecraft:red_wool", "id": -556 }, { "name": "minecraft:redstone", - "id": 376 + "id": 380 }, { "name": "minecraft:redstone_block", @@ -4753,7 +4977,7 @@ }, { "name": "minecraft:repeater", - "id": 423 + "id": 427 }, { "name": "minecraft:repeating_command_block", @@ -4769,27 +4993,31 @@ }, { "name": "minecraft:rib_armor_trim_smithing_template", - "id": 698 + "id": 709 + }, + { + "name": "minecraft:rose_bush", + "id": -866 }, { "name": "minecraft:rotten_flesh", - "id": 278 + "id": 281 }, { "name": "minecraft:saddle", - "id": 374 + "id": 378 }, { "name": "minecraft:salmon", - "id": 266 + "id": 269 }, { "name": "minecraft:salmon_bucket", - "id": 368 + "id": 372 }, { "name": "minecraft:salmon_spawn_egg", - "id": 487 + "id": 492 }, { "name": "minecraft:sand", @@ -4799,18 +5027,26 @@ "name": "minecraft:sandstone", "id": 24 }, + { + "name": "minecraft:sandstone_slab", + "id": -872 + }, { "name": "minecraft:sandstone_stairs", "id": 128 }, { "name": "minecraft:sapling", - "id": 6 + "id": 732 }, { "name": "minecraft:scaffolding", "id": -165 }, + { + "name": "minecraft:scrape_pottery_sherd", + "id": 693 + }, { "name": "minecraft:sculk", "id": -458 @@ -4845,31 +5081,35 @@ }, { "name": "minecraft:sentry_armor_trim_smithing_template", - "id": 689 + "id": 700 }, { "name": "minecraft:shaper_armor_trim_smithing_template", - "id": 703 + "id": 714 }, { "name": "minecraft:sheaf_pottery_sherd", - "id": 683 + "id": 694 }, { "name": "minecraft:shears", - "id": 425 + "id": 429 }, { "name": "minecraft:sheep_spawn_egg", - "id": 442 + "id": 447 }, { "name": "minecraft:shelter_pottery_sherd", - "id": 684 + "id": 695 }, { "name": "minecraft:shield", - "id": 358 + "id": 362 + }, + { + "name": "minecraft:short_grass", + "id": 31 }, { "name": "minecraft:shroomlight", @@ -4877,19 +5117,19 @@ }, { "name": "minecraft:shulker_box", - "id": 725 + "id": 747 }, { "name": "minecraft:shulker_shell", - "id": 577 + "id": 582 }, { "name": "minecraft:shulker_spawn_egg", - "id": 474 + "id": 479 }, { "name": "minecraft:silence_armor_trim_smithing_template", - "id": 700 + "id": 711 }, { "name": "minecraft:silver_glazed_terracotta", @@ -4897,27 +5137,27 @@ }, { "name": "minecraft:silverfish_spawn_egg", - "id": 447 + "id": 452 }, { "name": "minecraft:skeleton_horse_spawn_egg", - "id": 472 + "id": 477 }, { "name": "minecraft:skeleton_spawn_egg", - "id": 448 + "id": 453 }, { "name": "minecraft:skull", - "id": 527 + "id": 532 }, { "name": "minecraft:skull_banner_pattern", - "id": 594 + "id": 599 }, { "name": "minecraft:skull_pottery_sherd", - "id": 685 + "id": 696 }, { "name": "minecraft:slime", @@ -4925,11 +5165,11 @@ }, { "name": "minecraft:slime_ball", - "id": 392 + "id": 396 }, { "name": "minecraft:slime_spawn_egg", - "id": 449 + "id": 454 }, { "name": "minecraft:small_amethyst_bud", @@ -4967,21 +5207,25 @@ "name": "minecraft:smooth_stone", "id": -183 }, + { + "name": "minecraft:smooth_stone_slab", + "id": 44 + }, { "name": "minecraft:sniffer_egg", "id": -596 }, { "name": "minecraft:sniffer_spawn_egg", - "id": 505 + "id": 510 }, { "name": "minecraft:snort_pottery_sherd", - "id": 686 + "id": 697 }, { "name": "minecraft:snout_armor_trim_smithing_template", - "id": 697 + "id": 708 }, { "name": "minecraft:snow", @@ -4989,7 +5233,7 @@ }, { "name": "minecraft:snow_golem_spawn_egg", - "id": 511 + "id": 516 }, { "name": "minecraft:snow_layer", @@ -4997,11 +5241,11 @@ }, { "name": "minecraft:snowball", - "id": 377 + "id": 381 }, { "name": "minecraft:soul_campfire", - "id": 633 + "id": 641 }, { "name": "minecraft:soul_fire", @@ -5025,27 +5269,27 @@ }, { "name": "minecraft:sparkler", - "id": 611 + "id": 619 }, { "name": "minecraft:spawn_egg", - "id": 732 + "id": 757 }, { "name": "minecraft:spider_eye", - "id": 279 + "id": 282 }, { "name": "minecraft:spider_spawn_egg", - "id": 450 + "id": 455 }, { "name": "minecraft:spire_armor_trim_smithing_template", - "id": 699 + "id": 710 }, { "name": "minecraft:splash_potion", - "id": 572 + "id": 577 }, { "name": "minecraft:sponge", @@ -5057,7 +5301,7 @@ }, { "name": "minecraft:spruce_boat", - "id": 382 + "id": 386 }, { "name": "minecraft:spruce_button", @@ -5065,11 +5309,11 @@ }, { "name": "minecraft:spruce_chest_boat", - "id": 652 + "id": 660 }, { "name": "minecraft:spruce_door", - "id": 564 + "id": 569 }, { "name": "minecraft:spruce_double_slab", @@ -5103,9 +5347,13 @@ "name": "minecraft:spruce_pressure_plate", "id": -154 }, + { + "name": "minecraft:spruce_sapling", + "id": -825 + }, { "name": "minecraft:spruce_sign", - "id": 587 + "id": 592 }, { "name": "minecraft:spruce_slab", @@ -5133,23 +5381,23 @@ }, { "name": "minecraft:spyglass", - "id": 636 + "id": 644 }, { "name": "minecraft:squid_spawn_egg", - "id": 454 + "id": 459 }, { "name": "minecraft:stained_glass", - "id": 723 + "id": 745 }, { "name": "minecraft:stained_glass_pane", - "id": 724 + "id": 746 }, { "name": "minecraft:stained_hardened_clay", - "id": 706 + "id": 719 }, { "name": "minecraft:standing_banner", @@ -5161,7 +5409,7 @@ }, { "name": "minecraft:stick", - "id": 323 + "id": 327 }, { "name": "minecraft:sticky_piston", @@ -5177,11 +5425,11 @@ }, { "name": "minecraft:stone_axe", - "id": 318 + "id": 321 }, { "name": "minecraft:stone_block_slab", - "id": 44 + "id": 736 }, { "name": "minecraft:stone_block_slab2", @@ -5195,6 +5443,10 @@ "name": "minecraft:stone_block_slab4", "id": -166 }, + { + "name": "minecraft:stone_brick_slab", + "id": -875 + }, { "name": "minecraft:stone_brick_stairs", "id": 109 @@ -5205,11 +5457,11 @@ }, { "name": "minecraft:stone_hoe", - "id": 333 + "id": 337 }, { "name": "minecraft:stone_pickaxe", - "id": 317 + "id": 320 }, { "name": "minecraft:stone_pressure_plate", @@ -5217,7 +5469,7 @@ }, { "name": "minecraft:stone_shovel", - "id": 316 + "id": 319 }, { "name": "minecraft:stone_stairs", @@ -5225,7 +5477,7 @@ }, { "name": "minecraft:stone_sword", - "id": 315 + "id": 318 }, { "name": "minecraft:stonebrick", @@ -5241,15 +5493,15 @@ }, { "name": "minecraft:stray_spawn_egg", - "id": 466 + "id": 471 }, { "name": "minecraft:strider_spawn_egg", - "id": 500 + "id": 505 }, { "name": "minecraft:string", - "id": 329 + "id": 333 }, { "name": "minecraft:stripped_acacia_log", @@ -5345,11 +5597,15 @@ }, { "name": "minecraft:sugar", - "id": 420 + "id": 424 }, { "name": "minecraft:sugar_cane", - "id": 389 + "id": 393 + }, + { + "name": "minecraft:sunflower", + "id": 175 }, { "name": "minecraft:suspicious_gravel", @@ -5361,11 +5617,11 @@ }, { "name": "minecraft:suspicious_stew", - "id": 601 + "id": 608 }, { "name": "minecraft:sweet_berries", - "id": 288 + "id": 291 }, { "name": "minecraft:sweet_berry_bush", @@ -5373,15 +5629,19 @@ }, { "name": "minecraft:tadpole_bucket", - "id": 641 + "id": 649 }, { "name": "minecraft:tadpole_spawn_egg", - "id": 640 + "id": 648 + }, + { + "name": "minecraft:tall_grass", + "id": -864 }, { "name": "minecraft:tallgrass", - "id": 31 + "id": 741 }, { "name": "minecraft:target", @@ -5389,7 +5649,7 @@ }, { "name": "minecraft:tide_armor_trim_smithing_template", - "id": 696 + "id": 707 }, { "name": "minecraft:tinted_glass", @@ -5401,7 +5661,7 @@ }, { "name": "minecraft:tnt_minecart", - "id": 536 + "id": 541 }, { "name": "minecraft:torch", @@ -5417,15 +5677,15 @@ }, { "name": "minecraft:torchflower_seeds", - "id": 297 + "id": 300 }, { "name": "minecraft:totem_of_undying", - "id": 579 + "id": 584 }, { "name": "minecraft:trader_llama_spawn_egg", - "id": 659 + "id": 667 }, { "name": "minecraft:trapdoor", @@ -5437,7 +5697,7 @@ }, { "name": "minecraft:trial_key", - "id": 707 + "id": 259 }, { "name": "minecraft:trial_spawner", @@ -5445,7 +5705,7 @@ }, { "name": "minecraft:trident", - "id": 557 + "id": 562 }, { "name": "minecraft:trip_wire", @@ -5457,20 +5717,28 @@ }, { "name": "minecraft:tropical_fish", - "id": 267 + "id": 270 }, { "name": "minecraft:tropical_fish_bucket", - "id": 369 + "id": 373 }, { "name": "minecraft:tropical_fish_spawn_egg", - "id": 484 + "id": 489 }, { "name": "minecraft:tube_coral", "id": -131 }, + { + "name": "minecraft:tube_coral_block", + "id": -132 + }, + { + "name": "minecraft:tube_coral_fan", + "id": -133 + }, { "name": "minecraft:tuff", "id": -333 @@ -5517,15 +5785,15 @@ }, { "name": "minecraft:turtle_helmet", - "id": 584 + "id": 589 }, { "name": "minecraft:turtle_scute", - "id": 583 + "id": 588 }, { "name": "minecraft:turtle_spawn_egg", - "id": 490 + "id": 495 }, { "name": "minecraft:twisting_vines", @@ -5565,19 +5833,19 @@ }, { "name": "minecraft:vex_armor_trim_smithing_template", - "id": 695 + "id": 706 }, { "name": "minecraft:vex_spawn_egg", - "id": 481 + "id": 486 }, { "name": "minecraft:villager_spawn_egg", - "id": 453 + "id": 458 }, { "name": "minecraft:vindicator_spawn_egg", - "id": 479 + "id": 484 }, { "name": "minecraft:vine", @@ -5593,15 +5861,15 @@ }, { "name": "minecraft:wandering_trader_spawn_egg", - "id": 497 + "id": 502 }, { "name": "minecraft:ward_armor_trim_smithing_template", - "id": 693 + "id": 704 }, { "name": "minecraft:warden_spawn_egg", - "id": 643 + "id": 651 }, { "name": "minecraft:warped_button", @@ -5609,7 +5877,7 @@ }, { "name": "minecraft:warped_door", - "id": 628 + "id": 636 }, { "name": "minecraft:warped_double_slab", @@ -5629,7 +5897,7 @@ }, { "name": "minecraft:warped_fungus_on_a_stick", - "id": 629 + "id": 637 }, { "name": "minecraft:warped_hanging_sign", @@ -5657,7 +5925,7 @@ }, { "name": "minecraft:warped_sign", - "id": 626 + "id": 634 }, { "name": "minecraft:warped_slab", @@ -5693,7 +5961,7 @@ }, { "name": "minecraft:water_bucket", - "id": 365 + "id": 369 }, { "name": "minecraft:waterlily", @@ -5861,7 +6129,7 @@ }, { "name": "minecraft:wayfinder_armor_trim_smithing_template", - "id": 701 + "id": 712 }, { "name": "minecraft:weathered_chiseled_copper", @@ -5913,11 +6181,11 @@ }, { "name": "minecraft:wheat", - "id": 337 + "id": 341 }, { "name": "minecraft:wheat_seeds", - "id": 292 + "id": 295 }, { "name": "minecraft:white_candle", @@ -5941,7 +6209,7 @@ }, { "name": "minecraft:white_dye", - "id": 414 + "id": 418 }, { "name": "minecraft:white_glazed_terracotta", @@ -5963,21 +6231,25 @@ "name": "minecraft:white_terracotta", "id": 159 }, + { + "name": "minecraft:white_tulip", + "id": -835 + }, { "name": "minecraft:white_wool", "id": 35 }, { "name": "minecraft:wild_armor_trim_smithing_template", - "id": 692 + "id": 703 }, { "name": "minecraft:wind_charge", - "id": 378 + "id": 260 }, { "name": "minecraft:witch_spawn_egg", - "id": 456 + "id": 461 }, { "name": "minecraft:wither_rose", @@ -5985,27 +6257,27 @@ }, { "name": "minecraft:wither_skeleton_spawn_egg", - "id": 469 + "id": 474 }, { "name": "minecraft:wither_spawn_egg", - "id": 513 + "id": 518 }, { "name": "minecraft:wolf_armor", - "id": 710 + "id": 722 }, { "name": "minecraft:wolf_spawn_egg", - "id": 443 + "id": 448 }, { "name": "minecraft:wood", - "id": 726 + "id": 748 }, { "name": "minecraft:wooden_axe", - "id": 314 + "id": 317 }, { "name": "minecraft:wooden_button", @@ -6013,15 +6285,15 @@ }, { "name": "minecraft:wooden_door", - "id": 362 + "id": 366 }, { "name": "minecraft:wooden_hoe", - "id": 332 + "id": 336 }, { "name": "minecraft:wooden_pickaxe", - "id": 313 + "id": 316 }, { "name": "minecraft:wooden_pressure_plate", @@ -6029,27 +6301,27 @@ }, { "name": "minecraft:wooden_shovel", - "id": 312 + "id": 315 }, { "name": "minecraft:wooden_slab", - "id": 717 + "id": 735 }, { "name": "minecraft:wooden_sword", - "id": 311 + "id": 314 }, { "name": "minecraft:wool", - "id": 711 + "id": 725 }, { "name": "minecraft:writable_book", - "id": 521 + "id": 526 }, { "name": "minecraft:written_book", - "id": 522 + "id": 527 }, { "name": "minecraft:yellow_candle", @@ -6073,7 +6345,7 @@ }, { "name": "minecraft:yellow_dye", - "id": 410 + "id": 414 }, { "name": "minecraft:yellow_flower", @@ -6105,22 +6377,22 @@ }, { "name": "minecraft:zoglin_spawn_egg", - "id": 503 + "id": 508 }, { "name": "minecraft:zombie_horse_spawn_egg", - "id": 473 + "id": 478 }, { "name": "minecraft:zombie_pigman_spawn_egg", - "id": 452 + "id": 457 }, { "name": "minecraft:zombie_spawn_egg", - "id": 451 + "id": 456 }, { "name": "minecraft:zombie_villager_spawn_egg", - "id": 482 + "id": 487 } ] \ No newline at end of file diff --git a/core/src/main/resources/mappings b/core/src/main/resources/mappings index 968a22bba..ec45f59c8 160000 --- a/core/src/main/resources/mappings +++ b/core/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 968a22bbab02d7d003c5b451a40d8bb2439b0d97 +Subproject commit ec45f59c8590945c9226921ef7e339f510983dc1 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index aa68a0bc0..8301029d2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -10,8 +10,7 @@ netty-io-uring = "0.0.25.Final-SNAPSHOT" guava = "29.0-jre" gson = "2.3.1" # Provided by Spigot 1.8.8 websocket = "1.5.1" -protocol = "3.0.0.Beta1-20240411.165033-129" -protocol-connection = "3.0.0.Beta1-20240411.165033-128" +protocol = "3.0.0.Beta2-20240520.153053-5" raknet = "1.0.0.CR3-20240416.144209-1" blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "e5b0bcc" @@ -117,12 +116,9 @@ viaproxy = { group = "net.raphimc", name = "ViaProxy", version.ref = "viaproxy" viaversion = { group = "com.viaversion", name = "viaversion", version.ref = "viaversion" } websocket = { group = "org.java-websocket", name = "Java-WebSocket", version.ref = "websocket" } -#protocol-common = { group = "org.cloudburstmc.protocol", name = "common", version.ref = "protocol-connection" } -#protocol-codec = { group = "org.cloudburstmc.protocol", name = "bedrock-codec", version.ref = "protocol" } -#protocol-connection = { group = "org.cloudburstmc.protocol", name = "bedrock-connection", version.ref = "protocol-connection" } -protocol-common = { group = "com.github.GeyserMC.Protocol", name = "common", version = "ade21be" } -protocol-codec = { group = "com.github.GeyserMC.Protocol", name = "bedrock-codec", version = "ade21be" } -protocol-connection = { group = "com.github.GeyserMC.Protocol", name = "bedrock-connection", version = "ade21be" } +protocol-common = { group = "org.cloudburstmc.protocol", name = "common", version.ref = "protocol" } +protocol-codec = { group = "org.cloudburstmc.protocol", name = "bedrock-codec", version.ref = "protocol" } +protocol-connection = { group = "org.cloudburstmc.protocol", name = "bedrock-connection", version.ref = "protocol" } math = { group = "org.cloudburstmc.math", name = "immutable", version = "2.0" } From cb0488a271c6db3637476477902234725461aa7f Mon Sep 17 00:00:00 2001 From: Valaphee The Meerkat <32491319+valaphee@users.noreply.github.com> Date: Mon, 27 May 2024 14:08:04 +0200 Subject: [PATCH 191/272] Fix NPE in TippedArrow when it has no components (#4694) --- .../geyser/item/type/TippedArrowItem.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java index 85291886e..db33bb584 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java @@ -41,16 +41,18 @@ public class TippedArrowItem extends ArrowItem { @Override public ItemData.Builder translateToBedrock(int count, DataComponents components, ItemMapping mapping, ItemMappings mappings) { - PotionContents potionContents = components.get(DataComponentType.POTION_CONTENTS); - if (potionContents != null) { - TippedArrowPotion tippedArrowPotion = TippedArrowPotion.of(potionContents.getPotionId()); - if (tippedArrowPotion != null) { - return ItemData.builder() - .definition(mapping.getBedrockDefinition()) - .damage(tippedArrowPotion.getBedrockId()) - .count(count); + if (components != null) { + PotionContents potionContents = components.get(DataComponentType.POTION_CONTENTS); + if (potionContents != null) { + TippedArrowPotion tippedArrowPotion = TippedArrowPotion.of(potionContents.getPotionId()); + if (tippedArrowPotion != null) { + return ItemData.builder() + .definition(mapping.getBedrockDefinition()) + .damage(tippedArrowPotion.getBedrockId()) + .count(count); + } + GeyserImpl.getInstance().getLogger().debug("Unknown Java potion (tipped arrow): " + potionContents.getPotionId()); } - GeyserImpl.getInstance().getLogger().debug("Unknown Java potion (tipped arrow): " + potionContents.getPotionId()); } return super.translateToBedrock(count, components, mapping, mappings); } From 3570caae258e43b61bfc628d18f0408e3b08af78 Mon Sep 17 00:00:00 2001 From: Valaphee The Meerkat <32491319+valaphee@users.noreply.github.com> Date: Mon, 27 May 2024 16:53:42 +0200 Subject: [PATCH 192/272] Fix crafting output not updating sometimes (#4692) * Only cancel crafting grid future if slot == 0 * Add some comments --- .../inventory/JavaContainerSetSlotTranslator.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java index 4372b5ea5..57da00b51 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java @@ -71,10 +71,6 @@ public class JavaContainerSetSlotTranslator extends PacketTranslator= inventory.getSize()) { GeyserLogger logger = session.getGeyser().getLogger(); @@ -111,14 +107,22 @@ public class JavaContainerSetSlotTranslator extends PacketTranslator Date: Mon, 27 May 2024 10:59:36 -0700 Subject: [PATCH 193/272] Switch to centralized GitHub actions (#4693) * Switch to centralized GitHub actions * Update PR actions as well * Publish preview only if success * Webhook on success & failure --- .github/workflows/build-remote.yml | 36 ++++----- .github/workflows/build.yml | 125 +++++++++++++---------------- .github/workflows/preview.yml | 57 +++++-------- 3 files changed, 97 insertions(+), 121 deletions(-) diff --git a/.github/workflows/build-remote.yml b/.github/workflows/build-remote.yml index d49920785..c815b4740 100644 --- a/.github/workflows/build-remote.yml +++ b/.github/workflows/build-remote.yml @@ -22,79 +22,79 @@ jobs: run: | echo "BUILD_NUMBER=${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV - - name: Set up JDK 21 + - name: Setup Java # See https://github.com/actions/setup-java/commits - uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0 + uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1 with: java-version: 21 distribution: temurin - name: Checkout repository and submodules # See https://github.com/actions/checkout/commits - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 with: repository: ${{ inputs.repository }} ref: ${{ inputs.ref }} submodules: recursive - path: geyser - name: Validate Gradle Wrapper # See https://github.com/gradle/wrapper-validation-action/commits - uses: gradle/wrapper-validation-action@699bb18358f12c5b78b37bb0111d3a0e2276e0e2 # v2.1.1 + uses: gradle/actions/wrapper-validation@db19848a5fa7950289d3668fb053140cf3028d43 # v3.3.2 + + - name: Setup Gradle + # See https://github.com/gradle/actions/commits + uses: gradle/actions/setup-gradle@db19848a5fa7950289d3668fb053140cf3028d43 # v3.3.2 + with: + cache-read-only: true - name: Build Geyser - # See https://github.com/gradle/actions/commits - uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 - with: - arguments: build - build-root-directory: geyser - cache-read-only: true + run: ./gradlew build - name: Archive artifacts (Geyser Fabric) # See https://github.com/actions/upload-artifact/commits - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 if: success() with: name: Geyser Fabric path: geyser/bootstrap/mod/fabric/build/libs/Geyser-Fabric.jar if-no-files-found: error - name: Archive artifacts (Geyser NeoForge) - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 if: success() with: name: Geyser NeoForge path: geyser/bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar if-no-files-found: error - name: Archive artifacts (Geyser Standalone) - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 if: success() with: name: Geyser Standalone path: geyser/bootstrap/standalone/build/libs/Geyser-Standalone.jar if-no-files-found: error - name: Archive artifacts (Geyser Spigot) - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 if: success() with: name: Geyser Spigot path: geyser/bootstrap/spigot/build/libs/Geyser-Spigot.jar if-no-files-found: error - name: Archive artifacts (Geyser BungeeCord) - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 if: success() with: name: Geyser BungeeCord path: geyser/bootstrap/bungeecord/build/libs/Geyser-BungeeCord.jar if-no-files-found: error - name: Archive artifacts (Geyser Velocity) - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 if: success() with: name: Geyser Velocity path: geyser/bootstrap/velocity/build/libs/Geyser-Velocity.jar if-no-files-found: error - name: Archive artifacts (Geyser ViaProxy) - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 if: success() with: name: Geyser ViaProxy diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7ec013dc2..f2f2a2c82 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,84 +21,86 @@ on: jobs: build: runs-on: ubuntu-latest - env: - PROJECT: 'geyser' steps: - - name: Set Build Number - env: - BUILD_JSON: ${{ vars.RELEASEACTION_PREVRELEASE }} - run: | - BUILD_NUMBER=$(echo $BUILD_JSON | jq --arg branch "${GITHUB_REF_NAME}" 'if .[$branch] == null then 1 else .[$branch] | .t | tonumber + 1 end // 1') - echo "BUILD_NUMBER=${BUILD_NUMBER:=$GITHUB_RUN_NUMBER}" >> $GITHUB_ENV + - name: Get Release Info + id: release-info + uses: GeyserMC/actions/previous-release@master + with: + data: ${{ vars.RELEASEACTION_PREVRELEASE }} - name: Checkout repository and submodules # See https://github.com/actions/checkout/commits - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 with: submodules: recursive - name: Validate Gradle Wrapper - # See https://github.com/gradle/wrapper-validation-action/commits - uses: gradle/wrapper-validation-action@699bb18358f12c5b78b37bb0111d3a0e2276e0e2 # v2.1.1 + # See https://github.com/gradle/actions/commits + uses: gradle/actions/wrapper-validation@db19848a5fa7950289d3668fb053140cf3028d43 # v3.3.2 # See https://github.com/actions/setup-java/commits - - uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0 + - name: Setup Java + uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1 with: java-version: 21 distribution: temurin - - name: Build + - name: Setup Gradle # See https://github.com/gradle/actions/commits - uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 + uses: gradle/actions/setup-gradle@db19848a5fa7950289d3668fb053140cf3028d43 # v3.3.2 with: - arguments: build gradle-home-cache-cleanup: true + + - name: Build Geyser + run: ./gradlew build + env: + BUILD_NUMBER: ${{ steps.release-info.outputs.curentRelease }} - name: Archive artifacts (Geyser Fabric) # See https://github.com/actions/upload-artifact/commits - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 if: success() with: name: Geyser Fabric path: bootstrap/mod/fabric/build/libs/Geyser-Fabric.jar if-no-files-found: error - name: Archive artifacts (Geyser NeoForge) - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 if: success() with: name: Geyser NeoForge path: bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar if-no-files-found: error - name: Archive artifacts (Geyser Standalone) - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 if: success() with: name: Geyser Standalone path: bootstrap/standalone/build/libs/Geyser-Standalone.jar if-no-files-found: error - name: Archive artifacts (Geyser Spigot) - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 if: success() with: name: Geyser Spigot path: bootstrap/spigot/build/libs/Geyser-Spigot.jar if-no-files-found: error - name: Archive artifacts (Geyser BungeeCord) - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 if: success() with: name: Geyser BungeeCord path: bootstrap/bungeecord/build/libs/Geyser-BungeeCord.jar if-no-files-found: error - name: Archive artifacts (Geyser Velocity) - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 if: success() with: name: Geyser Velocity path: bootstrap/velocity/build/libs/Geyser-Velocity.jar if-no-files-found: error - name: Archive artifacts (Geyser ViaProxy) - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 if: success() with: name: Geyser ViaProxy @@ -107,17 +109,23 @@ jobs: - name: Publish to Maven Repository if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} - uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 + run: ./gradlew publish env: + BUILD_NUMBER: ${{ steps.release-info.outputs.curentRelease }} ORG_GRADLE_PROJECT_geysermcUsername: ${{ vars.DEPLOY_USER }} ORG_GRADLE_PROJECT_geysermcPassword: ${{ secrets.DEPLOY_PASS }} - with: - arguments: publish + + - name: Get Version + if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} + id: get-version + run: | + version=$(cat gradle.properties | grep -o "version=[0-9\\.]*" | cut -d"=" -f2) + echo "VERSION=${version}" >> $GITHUB_OUTPUT - name: Get Release Metadata if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} - # See https://github.com/Kas-tle/base-release-action/releases/tag/main-11 - uses: Kas-tle/base-release-action@b863fa0f89bd15267a96a72efb84aec25f168d4c # main-11 + uses: GeyserMC/actions/release@master + id: metadata with: appID: ${{ secrets.RELEASE_APP_ID }} appPrivateKey: ${{ secrets.RELEASE_APP_PK }} @@ -131,61 +139,42 @@ jobs: viaproxy:bootstrap/viaproxy/build/libs/Geyser-ViaProxy.jar releaseEnabled: false saveMetadata: true - - name: Update Generated Metadata - if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} - run: | - cat metadata.json - echo - mv metadata.json metadata.json.tmp - version=$(cat gradle.properties | grep -o "version=[0-9\\.]*" | cut -d"=" -f2) - jq --arg project "${PROJECT}" --arg version "${version}" ' - . - | .changes |= map({"commit", "summary", "message"}) - | .downloads |= map_values({"name", "sha256"}) - | {$project, "repo", $version, "number": .build, "changes", "downloads"} - ' metadata.json.tmp > metadata.json - cat metadata.json + releaseProject: 'geyser' + releaseVersion: ${{ steps.get-version.outputs.VERSION }} - name: Publish to Downloads API if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} - shell: bash - env: - DOWNLOADS_USERNAME: ${{ vars.DOWNLOADS_USERNAME }} - DOWNLOADS_PRIVATE_KEY: ${{ secrets.DOWNLOADS_PRIVATE_KEY }} - DOWNLOADS_SERVER_IP: ${{ secrets.DOWNLOADS_SERVER_IP }} - run: | - # Save the private key to a file - echo "$DOWNLOADS_PRIVATE_KEY" > id_ecdsa - chmod 600 id_ecdsa - # Create the build folder - ssh -o StrictHostKeyChecking=no -i id_ecdsa $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP mkdir -p "~/uploads/$PROJECT/$GITHUB_RUN_NUMBER/" - # Copy over artifacts - rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" bootstrap/**/build/libs/Geyser-*.jar $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$PROJECT/$GITHUB_RUN_NUMBER/ - rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" bootstrap/mod/**/build/libs/Geyser-*.jar $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$PROJECT/$GITHUB_RUN_NUMBER/ - # Run the build script - rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" metadata.json $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$PROJECT/$GITHUB_RUN_NUMBER/ + uses: GeyserMC/actions/upload-release@master + with: + username: ${{ vars.DOWNLOADS_USERNAME }} + privateKey: ${{ secrets.DOWNLOADS_PRIVATE_KEY }} + host: ${{ secrets.DOWNLOADS_SERVER_IP }} + files: | + bootstrap/bungeecord/build/libs/Geyser-BungeeCord.jar + bootstrap/mod/fabric/build/libs/Geyser-Fabric.jar + bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar + bootstrap/spigot/build/libs/Geyser-Spigot.jar + bootstrap/standalone/build/libs/Geyser-Standalone.jar + bootstrap/velocity/build/libs/Geyser-Velocity.jar + bootstrap/viaproxy/build/libs/Geyser-ViaProxy.jar - name: Publish to Modrinth (Fabric) - uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} env: + BUILD_NUMBER: ${{ steps.release-info.outputs.curentRelease }} MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }} - with: - arguments: fabric:modrinth - gradle-home-cache-cleanup: true + run: ./gradlew fabric:modrinth - name: Publish to Modrinth (NeoForge) - uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} env: + BUILD_NUMBER: ${{ steps.release-info.outputs.curentRelease }} MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }} - with: - arguments: neoforge:modrinth - gradle-home-cache-cleanup: true + run: ./gradlew neoforge:modrinth - name: Notify Discord if: ${{ (success() || failure()) && github.repository == 'GeyserMC/Geyser' }} - # See https://github.com/Tim203/actions-git-discord-webhook/commits - uses: Tim203/actions-git-discord-webhook@70f38ded3aca51635ec978ab4e1a58cd4cd0c2ff + uses: GeyserMC/actions/notify-discord@master with: - webhook_url: ${{ secrets.DISCORD_WEBHOOK }} + discordWebhook: ${{ secrets.DISCORD_WEBHOOK }} status: ${{ job.status }} + body: ${{ steps.metadata.outputs.body }} diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 1268f0674..a90d60ef7 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -26,30 +26,30 @@ on: jobs: upload: runs-on: ubuntu-latest - env: - PROJECT: 'geyserpreview' steps: - name: Set Variables id: setvars run: | if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then echo "BUILD=${{ github.event.inputs.build }}" >> $GITHUB_ENV - echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_ENV + echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT echo "RUN=${{ github.event.inputs.runId }}" >> $GITHUB_OUTPUT else echo "BUILD=${{ inputs.build }}" >> $GITHUB_ENV - echo "VERSION=${{ inputs.version }}" >> $GITHUB_ENV + echo "VERSION=${{ inputs.version }}" >> $GITHUB_OUTPUT echo "RUN=${{ github.run_id }}" >> $GITHUB_OUTPUT fi - - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 + - name: Download Artifacts + # See https://github.com/actions/download-artifact/commits + uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.6 with: run-id: ${{ steps.setvars.outputs.RUN }} github-token: ${{ secrets.GITHUB_TOKEN }} merge-multiple: true - name: Get Preview Metadata if: success() - # See https://github.com/Kas-tle/base-release-action/releases/tag/main-11 - uses: Kas-tle/base-release-action@664c39985eb9d0d393ce98e7eb8414d3d98e762a # main-11 + uses: GeyserMC/actions/release@master + id: metadata with: appID: ${{ secrets.RELEASE_APP_ID }} appPrivateKey: ${{ secrets.RELEASE_APP_PK }} @@ -64,33 +64,20 @@ jobs: releaseEnabled: false saveMetadata: true updateReleaseData: false - - name: Update Generated Metadata - if: success() - run: | - cat metadata.json - echo - mv metadata.json metadata.json.tmp - jq --arg project "${PROJECT}" --arg version "${VERSION}" --arg number "${BUILD}" ' - . - | .downloads |= map_values({"name", "sha256"}) - | {$project, "repo", $version, "number": $number | tonumber, "changes": [], "downloads"} - ' metadata.json.tmp > metadata.json - cat metadata.json + releaseProject: 'geyserpreview' + releaseVersion: ${{ steps.setvars.outputs.VERSION }} - name: Publish to Downloads API if: success() - shell: bash - env: - DOWNLOADS_USERNAME: ${{ vars.DOWNLOADS_USERNAME }} - DOWNLOADS_PRIVATE_KEY: ${{ secrets.DOWNLOADS_PRIVATE_KEY }} - DOWNLOADS_SERVER_IP: ${{ secrets.DOWNLOADS_SERVER_IP }} - run: | - # Save the private key to a file - echo "$DOWNLOADS_PRIVATE_KEY" > id_ecdsa - chmod 600 id_ecdsa - # Create the build folder - ssh -o StrictHostKeyChecking=no -i id_ecdsa $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP mkdir -p "~/uploads/$PROJECT/$BUILD/" - # Copy over artifacts - rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" Geyser-*.jar $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$PROJECT/$BUILD/ - # Run the build script - # Push the metadata - rsync -P -e "ssh -o StrictHostKeyChecking=no -i id_ecdsa" metadata.json $DOWNLOADS_USERNAME@$DOWNLOADS_SERVER_IP:~/uploads/$PROJECT/$BUILD/ + uses: GeyserMC/actions/upload-release@master + with: + username: ${{ vars.DOWNLOADS_USERNAME }} + privateKey: ${{ secrets.DOWNLOADS_PRIVATE_KEY }} + host: ${{ secrets.DOWNLOADS_SERVER_IP }} + files: | + Geyser-BungeeCord.jar + Geyser-Fabric.jar + Geyser-NeoForge.jar + Geyser-Spigot.jar + Geyser-Standalone.jar + Geyser-Velocity.jar + Geyser-ViaProxy.jar From 444b5ecee8bf80e8ae93caa52dad8918a29a7542 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 27 May 2024 14:33:11 -0400 Subject: [PATCH 194/272] Remove BlockStateUpdater dependency Not currently used --- core/build.gradle.kts | 1 - .../populator/BlockRegistryPopulator.java | 15 --------------- gradle/libs.versions.toml | 3 --- 3 files changed, 19 deletions(-) diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 42d4e13c5..a27c4fc89 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -24,7 +24,6 @@ dependencies { implementation(libs.websocket) api(libs.bundles.protocol) - implementation(libs.blockstateupdater) api(libs.mcauthlib) api(libs.mcprotocollib) { diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java index 936935306..6b856c509 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java @@ -35,8 +35,6 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import it.unimi.dsi.fastutil.ints.IntSet; import it.unimi.dsi.fastutil.objects.*; -import org.cloudburstmc.blockstateupdater.BlockStateUpdater; -import org.cloudburstmc.blockstateupdater.util.tagupdater.CompoundTagUpdaterContext; import org.cloudburstmc.nbt.*; import org.cloudburstmc.protocol.bedrock.codec.v671.Bedrock_v671; import org.cloudburstmc.protocol.bedrock.codec.v685.Bedrock_v685; @@ -85,19 +83,6 @@ public final class BlockRegistryPopulator { interface Remapper { NbtMap remap(NbtMap tag); - - static Remapper of(BlockStateUpdater... updaters) { - CompoundTagUpdaterContext context = new CompoundTagUpdaterContext(); - for (BlockStateUpdater updater : updaters) { - updater.registerUpdaters(context); - } - - return tag -> { - NbtMapBuilder updated = context.update(tag, 0).toBuilder(); - updated.remove("version"); // we already removed this, but the context adds it. remove it again. - return updated.build(); - }; - } } public static void populate(Stage stage) { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8301029d2..1995a6ada 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,6 @@ gson = "2.3.1" # Provided by Spigot 1.8.8 websocket = "1.5.1" protocol = "3.0.0.Beta2-20240520.153053-5" raknet = "1.0.0.CR3-20240416.144209-1" -blockstateupdater="1.20.80-20240411.142413-1" mcauthlib = "e5b0bcc" mcprotocollib = "1.20.6-2-20240520.030045-8" adventure = "4.14.0" @@ -122,8 +121,6 @@ protocol-connection = { group = "org.cloudburstmc.protocol", name = "bedrock-con math = { group = "org.cloudburstmc.math", name = "immutable", version = "2.0" } -blockstateupdater = { group = "org.cloudburstmc", name = "block-state-updater", version.ref = "blockstateupdater"} - # plugins indra = { group = "net.kyori", name = "indra-common", version.ref = "indra" } shadow = { group = "com.github.johnrengelman", name = "shadow", version.ref = "shadow" } From 675faf6bb45676e248bb1f0b0f871429966e8feb Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 27 May 2024 14:35:02 -0400 Subject: [PATCH 195/272] Remove unused chat class --- .../geysermc/geyser/text/ChatTypeEntry.java | 53 ------------------- 1 file changed, 53 deletions(-) delete mode 100644 core/src/main/java/org/geysermc/geyser/text/ChatTypeEntry.java diff --git a/core/src/main/java/org/geysermc/geyser/text/ChatTypeEntry.java b/core/src/main/java/org/geysermc/geyser/text/ChatTypeEntry.java deleted file mode 100644 index f139b0bba..000000000 --- a/core/src/main/java/org/geysermc/geyser/text/ChatTypeEntry.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.geyser.text; - -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.cloudburstmc.protocol.bedrock.packet.TextPacket; -import org.geysermc.mcprotocollib.protocol.data.game.chat.BuiltinChatType; - -public record ChatTypeEntry(TextPacket.@NonNull Type bedrockChatType, @Nullable TextDecoration textDecoration) { - private static final ChatTypeEntry CHAT = new ChatTypeEntry(TextPacket.Type.CHAT, null); - private static final ChatTypeEntry RAW = new ChatTypeEntry(TextPacket.Type.RAW, null); - - /** - * Apply defaults to a map so it isn't empty in the event a chat message is sent before the login packet. - */ - public static void applyDefaults(Int2ObjectMap chatTypes) { - // So the proper way to do this, probably, would be to dump the NBT data from vanilla and load it. - // But, the only way this happens is if a chat message is sent to us before the login packet, which is rare. - // So we'll just make sure chat ends up in the right place. - chatTypes.put(BuiltinChatType.CHAT.ordinal(), CHAT); - chatTypes.put(BuiltinChatType.SAY_COMMAND.ordinal(), RAW); - chatTypes.put(BuiltinChatType.MSG_COMMAND_INCOMING.ordinal(), RAW); - chatTypes.put(BuiltinChatType.MSG_COMMAND_OUTGOING.ordinal(), RAW); - chatTypes.put(BuiltinChatType.TEAM_MSG_COMMAND_INCOMING.ordinal(), RAW); - chatTypes.put(BuiltinChatType.TEAM_MSG_COMMAND_OUTGOING.ordinal(), RAW); - chatTypes.put(BuiltinChatType.EMOTE_COMMAND.ordinal(), RAW); - } -} From fe63665d8818af2836e9db3447f8625d49beaeb6 Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Tue, 28 May 2024 00:11:05 -0700 Subject: [PATCH 196/272] Composite gradle setup and artifact archival (#4696) * Composite gradle setup and artifact archival * Remove 'geyser' path for PRs * Move upload-preview workflow --- .github/workflows/build-remote.yml | 85 +++++-------------------- .github/workflows/build.yml | 86 +++++--------------------- .github/workflows/dispatch-preview.yml | 33 ++++++++++ .github/workflows/preview.yml | 83 ------------------------- .github/workflows/pull-request.yml | 16 ++++- 5 files changed, 77 insertions(+), 226 deletions(-) create mode 100644 .github/workflows/dispatch-preview.yml delete mode 100644 .github/workflows/preview.yml diff --git a/.github/workflows/build-remote.yml b/.github/workflows/build-remote.yml index c815b4740..7cb89cc61 100644 --- a/.github/workflows/build-remote.yml +++ b/.github/workflows/build-remote.yml @@ -22,81 +22,26 @@ jobs: run: | echo "BUILD_NUMBER=${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV - - name: Setup Java - # See https://github.com/actions/setup-java/commits - uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1 - with: - java-version: 21 - distribution: temurin - - - name: Checkout repository and submodules - # See https://github.com/actions/checkout/commits - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - with: - repository: ${{ inputs.repository }} - ref: ${{ inputs.ref }} - submodules: recursive - - - name: Validate Gradle Wrapper - # See https://github.com/gradle/wrapper-validation-action/commits - uses: gradle/actions/wrapper-validation@db19848a5fa7950289d3668fb053140cf3028d43 # v3.3.2 - - name: Setup Gradle - # See https://github.com/gradle/actions/commits - uses: gradle/actions/setup-gradle@db19848a5fa7950289d3668fb053140cf3028d43 # v3.3.2 + uses: GeyserMC/actions/setup-gradle-composite@master with: - cache-read-only: true + checkout_repository: ${{ inputs.repository }} + checkout_ref: ${{ inputs.ref }} + setup-java_java-version: 21 + setup-gradle_cache-read-only: true - name: Build Geyser run: ./gradlew build - - name: Archive artifacts (Geyser Fabric) - # See https://github.com/actions/upload-artifact/commits - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + - name: Archive Artifacts + uses: GeyserMC/actions/upload-multi-artifact@master if: success() with: - name: Geyser Fabric - path: geyser/bootstrap/mod/fabric/build/libs/Geyser-Fabric.jar - if-no-files-found: error - - name: Archive artifacts (Geyser NeoForge) - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 - if: success() - with: - name: Geyser NeoForge - path: geyser/bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar - if-no-files-found: error - - name: Archive artifacts (Geyser Standalone) - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 - if: success() - with: - name: Geyser Standalone - path: geyser/bootstrap/standalone/build/libs/Geyser-Standalone.jar - if-no-files-found: error - - name: Archive artifacts (Geyser Spigot) - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 - if: success() - with: - name: Geyser Spigot - path: geyser/bootstrap/spigot/build/libs/Geyser-Spigot.jar - if-no-files-found: error - - name: Archive artifacts (Geyser BungeeCord) - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 - if: success() - with: - name: Geyser BungeeCord - path: geyser/bootstrap/bungeecord/build/libs/Geyser-BungeeCord.jar - if-no-files-found: error - - name: Archive artifacts (Geyser Velocity) - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 - if: success() - with: - name: Geyser Velocity - path: geyser/bootstrap/velocity/build/libs/Geyser-Velocity.jar - if-no-files-found: error - - name: Archive artifacts (Geyser ViaProxy) - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 - if: success() - with: - name: Geyser ViaProxy - path: geyser/bootstrap/viaproxy/build/libs/Geyser-ViaProxy.jar - if-no-files-found: error \ No newline at end of file + artifacts: | + bootstrap/mod/fabric/build/libs/Geyser-Fabric.jar + bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar + bootstrap/standalone/build/libs/Geyser-Standalone.jar + bootstrap/spigot/build/libs/Geyser-Spigot.jar + bootstrap/bungeecord/build/libs/Geyser-BungeeCord.jar + bootstrap/velocity/build/libs/Geyser-Velocity.jar + bootstrap/viaproxy/build/libs/Geyser-ViaProxy.jar \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f2f2a2c82..b8f855a53 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,84 +28,28 @@ jobs: with: data: ${{ vars.RELEASEACTION_PREVRELEASE }} - - name: Checkout repository and submodules - # See https://github.com/actions/checkout/commits - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - with: - submodules: recursive - - - name: Validate Gradle Wrapper - # See https://github.com/gradle/actions/commits - uses: gradle/actions/wrapper-validation@db19848a5fa7950289d3668fb053140cf3028d43 # v3.3.2 - - # See https://github.com/actions/setup-java/commits - - name: Setup Java - uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1 - with: - java-version: 21 - distribution: temurin - - name: Setup Gradle - # See https://github.com/gradle/actions/commits - uses: gradle/actions/setup-gradle@db19848a5fa7950289d3668fb053140cf3028d43 # v3.3.2 + uses: GeyserMC/actions/setup-gradle-composite@master with: - gradle-home-cache-cleanup: true + setup-java_java-version: 21 - name: Build Geyser run: ./gradlew build env: BUILD_NUMBER: ${{ steps.release-info.outputs.curentRelease }} - - name: Archive artifacts (Geyser Fabric) - # See https://github.com/actions/upload-artifact/commits - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + - name: Archive Artifacts + uses: GeyserMC/actions/upload-multi-artifact@master if: success() with: - name: Geyser Fabric - path: bootstrap/mod/fabric/build/libs/Geyser-Fabric.jar - if-no-files-found: error - - name: Archive artifacts (Geyser NeoForge) - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 - if: success() - with: - name: Geyser NeoForge - path: bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar - if-no-files-found: error - - name: Archive artifacts (Geyser Standalone) - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 - if: success() - with: - name: Geyser Standalone - path: bootstrap/standalone/build/libs/Geyser-Standalone.jar - if-no-files-found: error - - name: Archive artifacts (Geyser Spigot) - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 - if: success() - with: - name: Geyser Spigot - path: bootstrap/spigot/build/libs/Geyser-Spigot.jar - if-no-files-found: error - - name: Archive artifacts (Geyser BungeeCord) - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 - if: success() - with: - name: Geyser BungeeCord - path: bootstrap/bungeecord/build/libs/Geyser-BungeeCord.jar - if-no-files-found: error - - name: Archive artifacts (Geyser Velocity) - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 - if: success() - with: - name: Geyser Velocity - path: bootstrap/velocity/build/libs/Geyser-Velocity.jar - if-no-files-found: error - - name: Archive artifacts (Geyser ViaProxy) - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 - if: success() - with: - name: Geyser ViaProxy - path: bootstrap/viaproxy/build/libs/Geyser-ViaProxy.jar - if-no-files-found: error + artifacts: | + bootstrap/mod/fabric/build/libs/Geyser-Fabric.jar + bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar + bootstrap/standalone/build/libs/Geyser-Standalone.jar + bootstrap/spigot/build/libs/Geyser-Spigot.jar + bootstrap/bungeecord/build/libs/Geyser-BungeeCord.jar + bootstrap/velocity/build/libs/Geyser-Velocity.jar + bootstrap/viaproxy/build/libs/Geyser-ViaProxy.jar - name: Publish to Maven Repository if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} @@ -116,14 +60,14 @@ jobs: ORG_GRADLE_PROJECT_geysermcPassword: ${{ secrets.DEPLOY_PASS }} - name: Get Version - if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} + if: ${{ (success() || failure()) && github.repository == 'GeyserMC/Geyser' }} id: get-version run: | version=$(cat gradle.properties | grep -o "version=[0-9\\.]*" | cut -d"=" -f2) echo "VERSION=${version}" >> $GITHUB_OUTPUT - name: Get Release Metadata - if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} + if: ${{ (success() || failure()) && github.repository == 'GeyserMC/Geyser' }} uses: GeyserMC/actions/release@master id: metadata with: @@ -141,6 +85,7 @@ jobs: saveMetadata: true releaseProject: 'geyser' releaseVersion: ${{ steps.get-version.outputs.VERSION }} + - name: Publish to Downloads API if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} uses: GeyserMC/actions/upload-release@master @@ -156,6 +101,7 @@ jobs: bootstrap/standalone/build/libs/Geyser-Standalone.jar bootstrap/velocity/build/libs/Geyser-Velocity.jar bootstrap/viaproxy/build/libs/Geyser-ViaProxy.jar + changelog: ${{ steps.metadata.outputs.body }} - name: Publish to Modrinth (Fabric) if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} diff --git a/.github/workflows/dispatch-preview.yml b/.github/workflows/dispatch-preview.yml new file mode 100644 index 000000000..83df08e37 --- /dev/null +++ b/.github/workflows/dispatch-preview.yml @@ -0,0 +1,33 @@ +name: Dispatch Preview + +on: + workflow_dispatch: + inputs: + runId: + required: true + description: 'ID of the action to pull artifacts from' + build: + required: true + description: 'Build number for the release' + version: + required: true + description: 'Version under which to upload to the Downloads API' + +jobs: + dispatch-preview: + # Allow access to secrets if we are uploading a preview + secrets: inherit + uses: GeyserMC/actions/.github/workflows/upload-preview.yml@master + with: + build: ${{ inputs.build }} + version: ${{ inputs.version }} + files: | + bungeecord:Geyser-BungeeCord.jar + fabric:Geyser-Fabric.jar + neoforge:Geyser-NeoForge.jar + spigot:Geyser-Spigot.jar + standalone:Geyser-Standalone.jar + velocity:Geyser-Velocity.jar + viaproxy:Geyser-ViaProxy.jar + project: geyserpreview + runId: ${{ inputs.runId }} \ No newline at end of file diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml deleted file mode 100644 index a90d60ef7..000000000 --- a/.github/workflows/preview.yml +++ /dev/null @@ -1,83 +0,0 @@ -name: Upload Preview - -on: - workflow_dispatch: - inputs: - runId: - required: true - description: 'ID of the action to pull artifacts from' - build: - required: true - description: 'Build number for the release' - version: - required: true - description: 'Version under which to upload to the Downloads API' - workflow_call: - inputs: - build: - required: true - description: 'Build number for the release' - type: string - version: - required: true - description: 'Version under which to upload to the Downloads API' - type: string - -jobs: - upload: - runs-on: ubuntu-latest - steps: - - name: Set Variables - id: setvars - run: | - if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then - echo "BUILD=${{ github.event.inputs.build }}" >> $GITHUB_ENV - echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT - echo "RUN=${{ github.event.inputs.runId }}" >> $GITHUB_OUTPUT - else - echo "BUILD=${{ inputs.build }}" >> $GITHUB_ENV - echo "VERSION=${{ inputs.version }}" >> $GITHUB_OUTPUT - echo "RUN=${{ github.run_id }}" >> $GITHUB_OUTPUT - fi - - name: Download Artifacts - # See https://github.com/actions/download-artifact/commits - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.6 - with: - run-id: ${{ steps.setvars.outputs.RUN }} - github-token: ${{ secrets.GITHUB_TOKEN }} - merge-multiple: true - - name: Get Preview Metadata - if: success() - uses: GeyserMC/actions/release@master - id: metadata - with: - appID: ${{ secrets.RELEASE_APP_ID }} - appPrivateKey: ${{ secrets.RELEASE_APP_PK }} - files: | - bungeecord:Geyser-BungeeCord.jar - fabric:Geyser-Fabric.jar - neoforge:Geyser-NeoForge.jar - spigot:Geyser-Spigot.jar - standalone:Geyser-Standalone.jar - velocity:Geyser-Velocity.jar - viaproxy:Geyser-ViaProxy.jar - releaseEnabled: false - saveMetadata: true - updateReleaseData: false - releaseProject: 'geyserpreview' - releaseVersion: ${{ steps.setvars.outputs.VERSION }} - - name: Publish to Downloads API - if: success() - uses: GeyserMC/actions/upload-release@master - with: - username: ${{ vars.DOWNLOADS_USERNAME }} - privateKey: ${{ secrets.DOWNLOADS_PRIVATE_KEY }} - host: ${{ secrets.DOWNLOADS_SERVER_IP }} - files: | - Geyser-BungeeCord.jar - Geyser-Fabric.jar - Geyser-NeoForge.jar - Geyser-Spigot.jar - Geyser-Standalone.jar - Geyser-Velocity.jar - Geyser-ViaProxy.jar diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index bc5e57b6b..6167bb18e 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -8,7 +8,7 @@ jobs: # Forbid access to secrets nor GH Token perms while building the PR permissions: {} secrets: {} - uses: ./.github/workflows/build-remote.yml + uses: GeyserMC/Geyser/.github/workflows/build-remote.yml@master with: repository: ${{ github.event.pull_request.head.repo.full_name }} ref: ${{ github.event.pull_request.head.sha }} @@ -18,7 +18,17 @@ jobs: contains(github.event.pull_request.labels.*.name, 'PR: Needs Testing') # Allow access to secrets if we are uploading a preview secrets: inherit - uses: ./.github/workflows/preview.yml + uses: GeyserMC/actions/.github/workflows/upload-preview.yml@master with: build: ${{ github.run_number }} - version: pr.${{ github.event.pull_request.number }} \ No newline at end of file + version: pr.${{ github.event.pull_request.number }} + files: | + bungeecord:Geyser-BungeeCord.jar + fabric:Geyser-Fabric.jar + neoforge:Geyser-NeoForge.jar + spigot:Geyser-Spigot.jar + standalone:Geyser-Standalone.jar + velocity:Geyser-Velocity.jar + viaproxy:Geyser-ViaProxy.jar + project: geyserpreview + runId: ${{ github.run_id }} \ No newline at end of file From 0fcf0f9b4f62e4b0deb03678f029f60b2112ae8b Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 28 May 2024 17:23:19 +0200 Subject: [PATCH 197/272] Update Bungee version check, create logger earlier (#4697) * use the logger where possible instead of system.out.print * make loggers final * yeet unused constructors * velocity is more complicated --- .../bungeecord/GeyserBungeeLogger.java | 7 +-- .../bungeecord/GeyserBungeePlugin.java | 23 +++++----- .../platform/mod/GeyserModBootstrap.java | 7 ++- .../geyser/platform/mod/GeyserModLogger.java | 4 -- .../platform/spigot/GeyserPaperLogger.java | 4 +- .../platform/spigot/GeyserSpigotLogger.java | 4 +- .../platform/spigot/GeyserSpigotPlugin.java | 43 +++++++++---------- .../standalone/GeyserStandaloneBootstrap.java | 4 +- .../velocity/GeyserVelocityLogger.java | 4 +- .../velocity/GeyserVelocityPlugin.java | 38 ++++++++-------- .../java/org/geysermc/geyser/GeyserImpl.java | 1 + .../geysermc/geyser/text/GeyserLocale.java | 11 ++--- 12 files changed, 67 insertions(+), 83 deletions(-) diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeeLogger.java b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeeLogger.java index daeb20102..e8cf7ee39 100644 --- a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeeLogger.java +++ b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeeLogger.java @@ -26,22 +26,19 @@ package org.geysermc.geyser.platform.bungeecord; import lombok.Getter; +import lombok.RequiredArgsConstructor; import lombok.Setter; import org.geysermc.geyser.GeyserLogger; import java.util.logging.Level; import java.util.logging.Logger; +@RequiredArgsConstructor public class GeyserBungeeLogger implements GeyserLogger { private final Logger logger; @Getter @Setter private boolean debug; - public GeyserBungeeLogger(Logger logger, boolean debug) { - this.logger = logger; - this.debug = debug; - } - @Override public void severe(String message) { logger.severe(message); diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeePlugin.java b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeePlugin.java index 4191c8578..062ef6f76 100644 --- a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeePlugin.java +++ b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeePlugin.java @@ -58,14 +58,13 @@ import java.util.Map; import java.util.Optional; import java.util.UUID; import java.util.concurrent.TimeUnit; -import java.util.logging.Level; public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap { private GeyserCommandManager geyserCommandManager; private GeyserBungeeConfiguration geyserConfig; private GeyserBungeeInjector geyserInjector; - private GeyserBungeeLogger geyserLogger; + private final GeyserBungeeLogger geyserLogger = new GeyserBungeeLogger(getLogger()); private IGeyserPingPassthrough geyserBungeePingPassthrough; private GeyserImpl geyser; @@ -82,21 +81,21 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap { // Copied from ViaVersion. // https://github.com/ViaVersion/ViaVersion/blob/b8072aad86695cc8ec6f5e4103e43baf3abf6cc5/bungee/src/main/java/us/myles/ViaVersion/BungeePlugin.java#L43 try { - ProtocolConstants.class.getField("MINECRAFT_1_20_3"); + ProtocolConstants.class.getField("MINECRAFT_1_20_5"); } catch (NoSuchFieldException e) { - getLogger().warning(" / \\"); - getLogger().warning(" / \\"); - getLogger().warning(" / | \\"); - getLogger().warning(" / | \\ " + GeyserLocale.getLocaleStringLog("geyser.bootstrap.unsupported_proxy", getProxy().getName())); - getLogger().warning(" / \\ " + GeyserLocale.getLocaleStringLog("geyser.may_not_work_as_intended_all_caps")); - getLogger().warning(" / o \\"); - getLogger().warning("/_____________\\"); + geyserLogger.error(" / \\"); + geyserLogger.error(" / \\"); + geyserLogger.error(" / | \\"); + geyserLogger.error(" / | \\ " + GeyserLocale.getLocaleStringLog("geyser.bootstrap.unsupported_proxy", getProxy().getName())); + geyserLogger.error(" / \\ " + GeyserLocale.getLocaleStringLog("geyser.may_not_work_as_intended_all_caps")); + geyserLogger.error(" / o \\"); + geyserLogger.error("/_____________\\"); } if (!this.loadConfig()) { return; } - this.geyserLogger = new GeyserBungeeLogger(getLogger(), geyserConfig.isDebugMode()); + this.geyserLogger.setDebug(geyserConfig.isDebugMode()); GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger); this.geyser = GeyserImpl.load(PlatformType.BUNGEECORD, this); this.geyserInjector = new GeyserBungeeInjector(this); @@ -293,7 +292,7 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap { "config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()), this); this.geyserConfig = FileUtils.loadConfig(configFile, GeyserBungeeConfiguration.class); } catch (IOException ex) { - getLogger().log(Level.SEVERE, GeyserLocale.getLocaleStringLog("geyser.config.failed"), ex); + geyserLogger.error(GeyserLocale.getLocaleStringLog("geyser.config.failed"), ex); ex.printStackTrace(); return false; } diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java index 786faac93..d7373f0a9 100644 --- a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModBootstrap.java @@ -34,7 +34,6 @@ import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; import net.minecraft.server.MinecraftServer; import net.minecraft.world.entity.player.Player; -import org.apache.logging.log4j.LogManager; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.GeyserBootstrap; @@ -80,7 +79,7 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap { private GeyserCommandManager geyserCommandManager; private GeyserModConfiguration geyserConfig; private GeyserModInjector geyserInjector; - private GeyserModLogger geyserLogger; + private final GeyserModLogger geyserLogger = new GeyserModLogger(); private IGeyserPingPassthrough geyserPingPassthrough; private WorldManager geyserWorldManager; @@ -92,7 +91,7 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap { if (!loadConfig()) { return; } - this.geyserLogger = new GeyserModLogger(geyserConfig.isDebugMode()); + this.geyserLogger.setDebug(geyserConfig.isDebugMode()); GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger); this.geyser = GeyserImpl.load(this.platform.platformType(), this); @@ -288,7 +287,7 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap { this.geyserConfig = FileUtils.loadConfig(configFile, GeyserModConfiguration.class); return true; } catch (IOException ex) { - LogManager.getLogger("geyser").error(GeyserLocale.getLocaleStringLog("geyser.config.failed"), ex); + geyserLogger.error(GeyserLocale.getLocaleStringLog("geyser.config.failed"), ex); ex.printStackTrace(); return false; } diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModLogger.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModLogger.java index 444b725e9..9260288d7 100644 --- a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModLogger.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/GeyserModLogger.java @@ -37,10 +37,6 @@ public class GeyserModLogger implements GeyserLogger { private boolean debug; - public GeyserModLogger(boolean isDebug) { - debug = isDebug; - } - @Override public void severe(String message) { logger.fatal(message); diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserPaperLogger.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserPaperLogger.java index 930f84cec..9ebd6519a 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserPaperLogger.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserPaperLogger.java @@ -34,8 +34,8 @@ import java.util.logging.Logger; public final class GeyserPaperLogger extends GeyserSpigotLogger { private final ComponentLogger componentLogger; - public GeyserPaperLogger(Plugin plugin, Logger logger, boolean debug) { - super(logger, debug); + public GeyserPaperLogger(Plugin plugin, Logger logger) { + super(logger); componentLogger = plugin.getComponentLogger(); } diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotLogger.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotLogger.java index fe56cba1c..5c6101eae 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotLogger.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotLogger.java @@ -25,15 +25,15 @@ package org.geysermc.geyser.platform.spigot; -import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.RequiredArgsConstructor; import lombok.Setter; import org.geysermc.geyser.GeyserLogger; import java.util.logging.Level; import java.util.logging.Logger; -@AllArgsConstructor +@RequiredArgsConstructor public class GeyserSpigotLogger implements GeyserLogger { private final Logger logger; @Getter @Setter diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java index e33de5f9b..d138ad074 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java @@ -79,14 +79,14 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.UUID; -import java.util.logging.Level; public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { private GeyserSpigotCommandManager geyserCommandManager; private GeyserSpigotConfiguration geyserConfig; private GeyserSpigotInjector geyserInjector; - private GeyserSpigotLogger geyserLogger; + private final GeyserSpigotLogger geyserLogger = GeyserPaperLogger.supported() ? + new GeyserPaperLogger(this, getLogger()) : new GeyserSpigotLogger(getLogger()); private IGeyserPingPassthrough geyserSpigotPingPassthrough; private GeyserSpigotWorldManager geyserWorldManager; @@ -114,12 +114,12 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { // We depend on this as a fallback in certain scenarios BlockData.class.getMethod("getAsString"); } catch (ClassNotFoundException | NoSuchMethodException e) { - getLogger().severe("*********************************************"); - getLogger().severe(""); - getLogger().severe(GeyserLocale.getLocaleStringLog("geyser.bootstrap.unsupported_server.header")); - getLogger().severe(GeyserLocale.getLocaleStringLog("geyser.bootstrap.unsupported_server.message", "1.13.2")); - getLogger().severe(""); - getLogger().severe("*********************************************"); + geyserLogger.error("*********************************************"); + geyserLogger.error(""); + geyserLogger.error(GeyserLocale.getLocaleStringLog("geyser.bootstrap.unsupported_server.header")); + geyserLogger.error(GeyserLocale.getLocaleStringLog("geyser.bootstrap.unsupported_server.message", "1.13.2")); + geyserLogger.error(""); + geyserLogger.error("*********************************************"); Bukkit.getPluginManager().disablePlugin(this); return; } @@ -128,12 +128,12 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { Class.forName("net.md_5.bungee.chat.ComponentSerializer"); } catch (ClassNotFoundException e) { if (!PaperAdventure.canSendMessageUsingComponent()) { // Prepare for Paper eventually removing Bungee chat - getLogger().severe("*********************************************"); - getLogger().severe(""); - getLogger().severe(GeyserLocale.getLocaleStringLog("geyser.bootstrap.unsupported_server_type.header", getServer().getName())); - getLogger().severe(GeyserLocale.getLocaleStringLog("geyser.bootstrap.unsupported_server_type.message", "Paper")); - getLogger().severe(""); - getLogger().severe("*********************************************"); + geyserLogger.error("*********************************************"); + geyserLogger.error(""); + geyserLogger.error(GeyserLocale.getLocaleStringLog("geyser.bootstrap.unsupported_server_type.header", getServer().getName())); + geyserLogger.error(GeyserLocale.getLocaleStringLog("geyser.bootstrap.unsupported_server_type.message", "Paper")); + geyserLogger.error(""); + geyserLogger.error("*********************************************"); Bukkit.getPluginManager().disablePlugin(this); return; } @@ -142,11 +142,11 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { try { Class.forName("io.netty.util.internal.ObjectPool$ObjectCreator"); } catch (ClassNotFoundException e) { - getLogger().severe("*********************************************"); - getLogger().severe(""); - getLogger().severe("This version of Spigot is using an outdated version of netty. Please use Paper instead!"); - getLogger().severe(""); - getLogger().severe("*********************************************"); + geyserLogger.error("*********************************************"); + geyserLogger.error(""); + geyserLogger.error("This version of Spigot is using an outdated version of netty. Please use Paper instead!"); + geyserLogger.error(""); + geyserLogger.error("*********************************************"); Bukkit.getPluginManager().disablePlugin(this); return; } @@ -154,8 +154,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { if (!loadConfig()) { return; } - this.geyserLogger = GeyserPaperLogger.supported() ? new GeyserPaperLogger(this, getLogger(), geyserConfig.isDebugMode()) - : new GeyserSpigotLogger(getLogger(), geyserConfig.isDebugMode()); + this.geyserLogger.setDebug(geyserConfig.isDebugMode()); GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger); // Turn "(MC: 1.16.4)" into 1.16.4. @@ -486,7 +485,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()), this); this.geyserConfig = FileUtils.loadConfig(configFile, GeyserSpigotConfiguration.class); } catch (IOException ex) { - getLogger().log(Level.SEVERE, GeyserLocale.getLocaleStringLog("geyser.config.failed"), ex); + geyserLogger.error(GeyserLocale.getLocaleStringLog("geyser.config.failed"), ex); ex.printStackTrace(); Bukkit.getPluginManager().disablePlugin(this); return false; diff --git a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneBootstrap.java b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneBootstrap.java index 039004867..f289fa2ba 100644 --- a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneBootstrap.java +++ b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneBootstrap.java @@ -71,7 +71,7 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap { private GeyserCommandManager geyserCommandManager; private GeyserStandaloneConfiguration geyserConfig; - private GeyserStandaloneLogger geyserLogger; + private final GeyserStandaloneLogger geyserLogger = new GeyserStandaloneLogger(); private IGeyserPingPassthrough geyserPingPassthrough; private GeyserStandaloneGUI gui; @Getter @@ -181,8 +181,6 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap { } } - this.geyserLogger = new GeyserStandaloneLogger(); - if (useGui && gui == null) { gui = new GeyserStandaloneGUI(geyserLogger); gui.redirectSystemStreams(); diff --git a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityLogger.java b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityLogger.java index 567870e7f..4d10e4daf 100644 --- a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityLogger.java +++ b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityLogger.java @@ -25,13 +25,13 @@ package org.geysermc.geyser.platform.velocity; -import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.RequiredArgsConstructor; import lombok.Setter; import org.geysermc.geyser.GeyserLogger; import org.slf4j.Logger; -@AllArgsConstructor +@RequiredArgsConstructor public class GeyserVelocityLogger implements GeyserLogger { private final Logger logger; @Getter @Setter diff --git a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPlugin.java b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPlugin.java index 347a47d63..539bdadbf 100644 --- a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPlugin.java +++ b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPlugin.java @@ -64,44 +64,44 @@ import java.util.UUID; @Plugin(id = "geyser", name = GeyserImpl.NAME + "-Velocity", version = GeyserImpl.VERSION, url = "https://geysermc.org", authors = "GeyserMC") public class GeyserVelocityPlugin implements GeyserBootstrap { - @Inject - private Logger logger; - - @Inject - private ProxyServer proxyServer; - - @Inject - private CommandManager commandManager; + private final ProxyServer proxyServer; + private final CommandManager commandManager; + private final GeyserVelocityLogger geyserLogger; private GeyserCommandManager geyserCommandManager; private GeyserVelocityConfiguration geyserConfig; private GeyserVelocityInjector geyserInjector; - private GeyserVelocityLogger geyserLogger; private IGeyserPingPassthrough geyserPingPassthrough; - private GeyserImpl geyser; @Getter private final Path configFolder = Paths.get("plugins/" + GeyserImpl.NAME + "-Velocity/"); + @Inject + public GeyserVelocityPlugin(ProxyServer server, Logger logger, CommandManager manager) { + this.geyserLogger = new GeyserVelocityLogger(logger); + this.proxyServer = server; + this.commandManager = manager; + } + @Override public void onGeyserInitialize() { GeyserLocale.init(this); if (!ProtocolVersion.isSupported(GameProtocol.getJavaProtocolVersion())) { - logger.error(" / \\"); - logger.error(" / \\"); - logger.error(" / | \\"); - logger.error(" / | \\ " + GeyserLocale.getLocaleStringLog("geyser.bootstrap.unsupported_proxy", proxyServer.getVersion().getName())); - logger.error(" / \\ " + GeyserLocale.getLocaleStringLog("geyser.may_not_work_as_intended_all_caps")); - logger.error(" / o \\"); - logger.error("/_____________\\"); + geyserLogger.error(" / \\"); + geyserLogger.error(" / \\"); + geyserLogger.error(" / | \\"); + geyserLogger.error(" / | \\ " + GeyserLocale.getLocaleStringLog("geyser.bootstrap.unsupported_proxy", proxyServer.getVersion().getName())); + geyserLogger.error(" / \\ " + GeyserLocale.getLocaleStringLog("geyser.may_not_work_as_intended_all_caps")); + geyserLogger.error(" / o \\"); + geyserLogger.error("/_____________\\"); } if (!loadConfig()) { return; } - this.geyserLogger = new GeyserVelocityLogger(logger, geyserConfig.isDebugMode()); + this.geyserLogger.setDebug(geyserConfig.isDebugMode()); GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger); this.geyser = GeyserImpl.load(PlatformType.VELOCITY, this); @@ -249,7 +249,7 @@ public class GeyserVelocityPlugin implements GeyserBootstrap { "config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()), this); this.geyserConfig = FileUtils.loadConfig(configFile, GeyserVelocityConfiguration.class); } catch (IOException ex) { - logger.error(GeyserLocale.getLocaleStringLog("geyser.config.failed"), ex); + geyserLogger.error(GeyserLocale.getLocaleStringLog("geyser.config.failed"), ex); ex.printStackTrace(); return false; } diff --git a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java index d5635acf9..6a404ae11 100644 --- a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java +++ b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java @@ -766,6 +766,7 @@ public class GeyserImpl implements GeyserApi { return 0; } + //noinspection DataFlowIssue return Integer.parseInt(BUILD_NUMBER); } diff --git a/core/src/main/java/org/geysermc/geyser/text/GeyserLocale.java b/core/src/main/java/org/geysermc/geyser/text/GeyserLocale.java index c6a58e75e..cfe950409 100644 --- a/core/src/main/java/org/geysermc/geyser/text/GeyserLocale.java +++ b/core/src/main/java/org/geysermc/geyser/text/GeyserLocale.java @@ -148,9 +148,9 @@ public class GeyserLocale { } catch (IOException ignored) {} } } else { - if (GeyserImpl.getInstance() != null && !validLocalLanguage) { + if (!validLocalLanguage) { // Don't warn on missing locales if a local file has been found - GeyserImpl.getInstance().getLogger().warning("Missing locale: " + locale); + bootstrap.getGeyserLogger().warning("Missing locale: " + locale); } } @@ -162,12 +162,7 @@ public class GeyserLocale { localeProp.load(stream); } catch (IOException e) { String message = "Unable to load custom language override!"; - if (GeyserImpl.getInstance() != null) { - GeyserImpl.getInstance().getLogger().error(message, e); - } else { - System.err.println(message); - e.printStackTrace(); - } + bootstrap.getGeyserLogger().error(message, e); } LOCALE_MAPPINGS.putIfAbsent(locale, localeProp); From 63c84bc25bacc6df0384dcd2542fe1103358f096 Mon Sep 17 00:00:00 2001 From: chris Date: Wed, 29 May 2024 06:39:39 +0200 Subject: [PATCH 198/272] Yeet lectern cache (#4695) * attempt to yeet lectern cache * yeet lecternutils usage * properly update lecterns * yeet accidental diff --- .../mod/world/GeyserModWorldManager.java | 106 +----------------- .../manager/GeyserSpigotWorldManager.java | 72 ------------ .../geyser/level/GeyserWorldManager.java | 56 +-------- .../geysermc/geyser/level/WorldManager.java | 36 ------ .../geyser/level/block/type/Block.java | 65 +++++------ .../geyser/level/block/type/BlockState.java | 9 ++ .../geyser/level/block/type/LecternBlock.java | 66 ++++++++--- .../geyser/session/GeyserSession.java | 15 --- .../inventory/LecternInventoryTranslator.java | 35 +++--- .../level/JavaForgetLevelChunkTranslator.java | 12 -- .../JavaLevelChunkWithLightTranslator.java | 24 +--- .../geysermc/geyser/util/DimensionUtils.java | 3 - .../geysermc/geyser/util/InventoryUtils.java | 1 - 13 files changed, 108 insertions(+), 392 deletions(-) diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java index 656305690..7aac684bb 100644 --- a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java @@ -25,11 +25,6 @@ package org.geysermc.geyser.platform.mod.world; -import org.geysermc.mcprotocollib.protocol.data.game.Holder; -import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityInfo; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import net.minecraft.SharedConstants; @@ -48,24 +43,19 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BannerBlockEntity; import net.minecraft.world.level.block.entity.BannerPatternLayers; import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.LecternBlockEntity; import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunkSection; import net.minecraft.world.level.chunk.status.ChunkStatus; import org.checkerframework.checker.nullness.qual.NonNull; -import org.cloudburstmc.math.vector.Vector3i; -import org.cloudburstmc.nbt.NbtMap; -import org.cloudburstmc.nbt.NbtMapBuilder; -import org.cloudburstmc.nbt.NbtType; -import org.geysermc.erosion.util.LecternUtils; import org.geysermc.geyser.level.GeyserWorldManager; import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.platform.mod.GeyserModBootstrap; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.util.BlockEntityUtils; +import org.geysermc.mcprotocollib.protocol.data.game.Holder; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -121,94 +111,6 @@ public class GeyserModWorldManager extends GeyserWorldManager { return SharedConstants.getCurrentVersion().getProtocolVersion() == GameProtocol.getJavaProtocolVersion(); } - @Override - public boolean shouldExpectLecternHandled(GeyserSession session) { - return true; - } - - @Override - public void sendLecternData(GeyserSession session, int x, int z, List blockEntityInfos) { - server.execute(() -> { - ServerPlayer player = getPlayer(session); - if (player == null) { - return; - } - - //noinspection resource - level() is just a getter - LevelChunk chunk = player.level().getChunk(x, z); - final int chunkBlockX = x << 4; - final int chunkBlockZ = z << 4; - //noinspection ForLoopReplaceableByForEach - avoid constructing iterator - for (int i = 0; i < blockEntityInfos.size(); i++) { - BlockEntityInfo blockEntityInfo = blockEntityInfos.get(i); - BlockEntity blockEntity = chunk.getBlockEntity(new BlockPos(chunkBlockX + blockEntityInfo.getX(), - blockEntityInfo.getY(), chunkBlockZ + blockEntityInfo.getZ())); - sendLecternData(session, blockEntity, true); - } - }); - } - - @Override - public void sendLecternData(GeyserSession session, int x, int y, int z) { - server.execute(() -> { - ServerPlayer player = getPlayer(session); - if (player == null) { - return; - } - //noinspection resource - level() is just a getter - BlockEntity blockEntity = player.level().getBlockEntity(new BlockPos(x, y, z)); - sendLecternData(session, blockEntity, false); - }); - } - - private void sendLecternData(GeyserSession session, BlockEntity blockEntity, boolean isChunkLoad) { - if (!(blockEntity instanceof LecternBlockEntity lectern)) { - return; - } - - int x = blockEntity.getBlockPos().getX(); - int y = blockEntity.getBlockPos().getY(); - int z = blockEntity.getBlockPos().getZ(); - - if (!lectern.hasBook()) { - if (!isChunkLoad) { - BlockEntityUtils.updateBlockEntity(session, LecternUtils.getBaseLecternTag(x, y, z, 0).build(), Vector3i.from(x, y, z)); - } - return; - } - - ItemStack book = lectern.getBook(); - int pageCount = getPageCount(book); - boolean hasBookPages = pageCount > 0; - NbtMapBuilder lecternTag = LecternUtils.getBaseLecternTag(x, y, z, hasBookPages ? pageCount : 1); - lecternTag.putInt("page", lectern.getPage() / 2); - NbtMapBuilder bookTag = NbtMap.builder() - .putByte("Count", (byte) book.getCount()) - .putShort("Damage", (short) 0) - .putString("Name", "minecraft:writable_book"); - List pages = new ArrayList<>(hasBookPages ? pageCount : 1); - if (hasBookPages) { - List bookPages = getPages(book); - for (String page : bookPages) { - NbtMapBuilder pageBuilder = NbtMap.builder() - .putString("photoname", "") - .putString("text", page); - pages.add(pageBuilder.build()); - } - } else { - // Empty page - NbtMapBuilder pageBuilder = NbtMap.builder() - .putString("photoname", "") - .putString("text", ""); - pages.add(pageBuilder.build()); - } - - bookTag.putCompound("tag", NbtMap.builder().putList("pages", NbtType.COMPOUND, pages).build()); - lecternTag.putCompound("book", bookTag.build()); - NbtMap blockEntityTag = lecternTag.build(); - BlockEntityUtils.updateBlockEntity(session, blockEntityTag, Vector3i.from(x, y, z)); - } - @Override public boolean hasPermission(GeyserSession session, String permission) { ServerPlayer player = getPlayer(session); diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java index f45b68675..e247a72c7 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/manager/GeyserSpigotWorldManager.java @@ -27,16 +27,12 @@ package org.geysermc.geyser.platform.spigot.world.manager; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import org.bukkit.Bukkit; -import org.bukkit.Chunk; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; -import org.cloudburstmc.nbt.NbtMap; -import org.geysermc.erosion.bukkit.BukkitLecterns; -import org.geysermc.erosion.bukkit.BukkitUtils; import org.geysermc.erosion.bukkit.PickBlockUtils; import org.geysermc.erosion.bukkit.SchedulerUtils; import org.geysermc.geyser.GeyserImpl; @@ -44,12 +40,9 @@ import org.geysermc.geyser.level.GameRule; import org.geysermc.geyser.level.WorldManager; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.util.BlockEntityUtils; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityInfo; -import java.util.List; import java.util.Objects; import java.util.concurrent.CompletableFuture; @@ -58,11 +51,9 @@ import java.util.concurrent.CompletableFuture; */ public class GeyserSpigotWorldManager extends WorldManager { private final Plugin plugin; - private final BukkitLecterns lecterns; public GeyserSpigotWorldManager(Plugin plugin) { this.plugin = plugin; - this.lecterns = new BukkitLecterns(plugin); } @Override @@ -95,69 +86,6 @@ public class GeyserSpigotWorldManager extends WorldManager { return true; } - @Override - public void sendLecternData(GeyserSession session, int x, int y, int z) { - Player bukkitPlayer; - if ((bukkitPlayer = Bukkit.getPlayer(session.getPlayerEntity().getUsername())) == null) { - return; - } - - Block block = bukkitPlayer.getWorld().getBlockAt(x, y, z); - // Run as a task to prevent async issues - SchedulerUtils.runTask(this.plugin, () -> sendLecternData(session, block, false), block); - } - - public void sendLecternData(GeyserSession session, int x, int z, List blockEntityInfos) { - Player bukkitPlayer; - if ((bukkitPlayer = Bukkit.getPlayer(session.getPlayerEntity().getUsername())) == null) { - return; - } - if (SchedulerUtils.FOLIA) { - Chunk chunk = getChunk(bukkitPlayer.getWorld(), x, z); - if (chunk == null) { - return; - } - Bukkit.getRegionScheduler().execute(this.plugin, bukkitPlayer.getWorld(), x, z, () -> - sendLecternData(session, chunk, blockEntityInfos)); - } else { - Bukkit.getScheduler().runTask(this.plugin, () -> { - Chunk chunk = getChunk(bukkitPlayer.getWorld(), x, z); - if (chunk == null) { - return; - } - sendLecternData(session, chunk, blockEntityInfos); - }); - } - } - - private @Nullable Chunk getChunk(World world, int x, int z) { - if (!world.isChunkLoaded(x, z)) { - return null; - } - return world.getChunkAt(x, z); - } - - private void sendLecternData(GeyserSession session, Chunk chunk, List blockEntityInfos) { - //noinspection ForLoopReplaceableByForEach - avoid constructing Iterator - for (int i = 0; i < blockEntityInfos.size(); i++) { - BlockEntityInfo info = blockEntityInfos.get(i); - Block block = chunk.getBlock(info.getX(), info.getY(), info.getZ()); - sendLecternData(session, block, true); - } - } - - private void sendLecternData(GeyserSession session, Block block, boolean isChunkLoad) { - NbtMap blockEntityTag = this.lecterns.getLecternData(block, isChunkLoad); - if (blockEntityTag != null) { - BlockEntityUtils.updateBlockEntity(session, blockEntityTag, BukkitUtils.getVector(block.getLocation())); - } - } - - @Override - public boolean shouldExpectLecternHandled(GeyserSession session) { - return true; - } - public boolean getGameRuleBool(GeyserSession session, GameRule gameRule) { org.bukkit.GameRule bukkitGameRule = org.bukkit.GameRule.getByName(gameRule.getJavaID()); if (bukkitGameRule == null) { diff --git a/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java b/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java index 3144f0cb2..9faa7424c 100644 --- a/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java +++ b/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java @@ -28,22 +28,17 @@ package org.geysermc.geyser.level; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; -import it.unimi.dsi.fastutil.objects.ObjectArrayList; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3i; -import org.cloudburstmc.nbt.NbtMap; -import org.cloudburstmc.nbt.NbtMapBuilder; -import org.geysermc.erosion.packet.backendbound.*; +import org.geysermc.erosion.packet.backendbound.BackendboundBatchBlockRequestPacket; +import org.geysermc.erosion.packet.backendbound.BackendboundBlockRequestPacket; +import org.geysermc.erosion.packet.backendbound.BackendboundPickBlockPacket; import org.geysermc.erosion.util.BlockPositionIterator; -import org.geysermc.erosion.util.LecternUtils; import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.util.BlockEntityUtils; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityInfo; -import java.util.List; import java.util.concurrent.CompletableFuture; public class GeyserWorldManager extends WorldManager { @@ -92,51 +87,6 @@ public class GeyserWorldManager extends WorldManager { return false; } - @Override - public void sendLecternData(GeyserSession session, int x, int z, List blockEntityInfos) { - var erosionHandler = session.getErosionHandler().getAsActive(); - if (erosionHandler == null) { - // No-op - don't send any additional information other than what the chunk has already sent - return; - } - List vectors = new ObjectArrayList<>(blockEntityInfos.size()); - //noinspection ForLoopReplaceableByForEach - avoid constructing iterator - for (int i = 0; i < blockEntityInfos.size(); i++) { - BlockEntityInfo info = blockEntityInfos.get(i); - vectors.add(Vector3i.from(info.getX(), info.getY(), info.getZ())); - } - erosionHandler.sendPacket(new BackendboundBatchBlockEntityPacket(x, z, vectors)); - } - - @Override - public void sendLecternData(GeyserSession session, int x, int y, int z) { - var erosionHandler = session.getErosionHandler().getAsActive(); - if (erosionHandler != null) { - erosionHandler.sendPacket(new BackendboundBlockEntityPacket(Vector3i.from(x, y, z))); - return; - } - - // Without direct server access, we can't get lectern information on-the-fly. - // I should have set this up so it's only called when there is a book in the block state. - Camotoy - NbtMapBuilder lecternTag = LecternUtils.getBaseLecternTag(x, y, z, 1); - lecternTag.putCompound("book", NbtMap.builder() - .putByte("Count", (byte) 1) - .putShort("Damage", (short) 0) - .putString("Name", "minecraft:written_book") - .putCompound("tag", NbtMap.builder() - .putString("photoname", "") - .putString("text", "") - .build()) - .build()); - lecternTag.putInt("page", -1); // I'm surprisingly glad this exists - it forces Bedrock to stop reading immediately. Usually. - BlockEntityUtils.updateBlockEntity(session, lecternTag.build(), Vector3i.from(x, y, z)); - } - - @Override - public boolean shouldExpectLecternHandled(GeyserSession session) { - return session.getErosionHandler().isActive(); - } - @Override public void setGameRule(GeyserSession session, String name, Object value) { super.setGameRule(session, name, value); diff --git a/core/src/main/java/org/geysermc/geyser/level/WorldManager.java b/core/src/main/java/org/geysermc/geyser/level/WorldManager.java index 6cd9c3e26..3670b6b73 100644 --- a/core/src/main/java/org/geysermc/geyser/level/WorldManager.java +++ b/core/src/main/java/org/geysermc/geyser/level/WorldManager.java @@ -40,11 +40,9 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponen import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemCodecHelper; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityInfo; import org.geysermc.mcprotocollib.protocol.data.game.setting.Difficulty; import java.util.HashMap; -import java.util.List; import java.util.Locale; import java.util.Map; import java.util.concurrent.CompletableFuture; @@ -118,40 +116,6 @@ public abstract class WorldManager { */ public abstract boolean hasOwnChunkCache(); - /** - * Sigh.
- * - * So, on Java Edition, the lectern is an inventory. Java opens it and gets the contents of the book there. - * On Bedrock, the lectern contents are part of the block entity tag. Therefore, Bedrock expects to have the contents - * of the lectern ready and present in the world. If the contents are not there, it takes at least two clicks for the - * lectern to update the tag and then present itself.
- * - * We solve this problem by querying all loaded lecterns, where possible, and sending their information in a block entity - * tag. - *

- * Note that the lectern data may be sent asynchronously. - * - * @param session the session of the player - * @param x the x coordinate of the lectern - * @param y the y coordinate of the lectern - * @param z the z coordinate of the lectern - */ - public abstract void sendLecternData(GeyserSession session, int x, int y, int z); - - /** - * {@link #sendLecternData(GeyserSession, int, int, int)} but batched for chunks. - * - * @param x chunk x - * @param z chunk z - * @param blockEntityInfos a list of coordinates (chunk local) to grab lecterns from. - */ - public abstract void sendLecternData(GeyserSession session, int x, int z, List blockEntityInfos); - - /** - * @return whether we should expect lectern data to update, or if we have to fall back on a workaround. - */ - public abstract boolean shouldExpectLecternHandled(GeyserSession session); - /** * Updates a gamerule value on the Java server * diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java b/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java index 9fe70c0f1..ee99b652a 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/Block.java @@ -91,39 +91,35 @@ public class Block { BlockDefinition definition = session.getBlockMappings().getBedrockBlock(state); sendBlockUpdatePacket(session, state, definition, position); - { - // Extended collision boxes for custom blocks - if (!session.getBlockMappings().getExtendedCollisionBoxes().isEmpty()) { - int aboveBlock = session.getGeyser().getWorldManager().getBlockAt(session, position.getX(), position.getY() + 1, position.getZ()); - BlockDefinition aboveBedrockExtendedCollisionDefinition = session.getBlockMappings().getExtendedCollisionBoxes().get(state.javaId()); - int belowBlock = session.getGeyser().getWorldManager().getBlockAt(session, position.getX(), position.getY() - 1, position.getZ()); - BlockDefinition belowBedrockExtendedCollisionDefinition = session.getBlockMappings().getExtendedCollisionBoxes().get(belowBlock); - if (belowBedrockExtendedCollisionDefinition != null && state.is(Blocks.AIR)) { - UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); - updateBlockPacket.setDataLayer(0); - updateBlockPacket.setBlockPosition(position); - updateBlockPacket.setDefinition(belowBedrockExtendedCollisionDefinition); - updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK); - session.sendUpstreamPacket(updateBlockPacket); - } else if (aboveBedrockExtendedCollisionDefinition != null && aboveBlock == Block.JAVA_AIR_ID) { - UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); - updateBlockPacket.setDataLayer(0); - updateBlockPacket.setBlockPosition(position.add(0, 1, 0)); - updateBlockPacket.setDefinition(aboveBedrockExtendedCollisionDefinition); - updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK); - session.sendUpstreamPacket(updateBlockPacket); - } else if (aboveBlock == Block.JAVA_AIR_ID) { - UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); - updateBlockPacket.setDataLayer(0); - updateBlockPacket.setBlockPosition(position.add(0, 1, 0)); - updateBlockPacket.setDefinition(session.getBlockMappings().getBedrockAir()); - updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK); - session.sendUpstreamPacket(updateBlockPacket); - } + // Extended collision boxes for custom blocks + if (!session.getBlockMappings().getExtendedCollisionBoxes().isEmpty()) { + int aboveBlock = session.getGeyser().getWorldManager().getBlockAt(session, position.getX(), position.getY() + 1, position.getZ()); + BlockDefinition aboveBedrockExtendedCollisionDefinition = session.getBlockMappings().getExtendedCollisionBoxes().get(state.javaId()); + int belowBlock = session.getGeyser().getWorldManager().getBlockAt(session, position.getX(), position.getY() - 1, position.getZ()); + BlockDefinition belowBedrockExtendedCollisionDefinition = session.getBlockMappings().getExtendedCollisionBoxes().get(belowBlock); + if (belowBedrockExtendedCollisionDefinition != null && state.is(Blocks.AIR)) { + UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); + updateBlockPacket.setDataLayer(0); + updateBlockPacket.setBlockPosition(position); + updateBlockPacket.setDefinition(belowBedrockExtendedCollisionDefinition); + updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK); + session.sendUpstreamPacket(updateBlockPacket); + } else if (aboveBedrockExtendedCollisionDefinition != null && aboveBlock == Block.JAVA_AIR_ID) { + UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); + updateBlockPacket.setDataLayer(0); + updateBlockPacket.setBlockPosition(position.add(0, 1, 0)); + updateBlockPacket.setDefinition(aboveBedrockExtendedCollisionDefinition); + updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK); + session.sendUpstreamPacket(updateBlockPacket); + } else if (aboveBlock == Block.JAVA_AIR_ID) { + UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); + updateBlockPacket.setDataLayer(0); + updateBlockPacket.setBlockPosition(position.add(0, 1, 0)); + updateBlockPacket.setDefinition(session.getBlockMappings().getBedrockAir()); + updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK); + session.sendUpstreamPacket(updateBlockPacket); } } - - handleLecternBlockUpdate(session, state, position); } protected void sendBlockUpdatePacket(GeyserSession session, BlockState state, BlockDefinition definition, Vector3i position) { @@ -153,13 +149,6 @@ public class Block { } } - protected void handleLecternBlockUpdate(GeyserSession session, BlockState state, Vector3i position) { - // Block state is out of bounds of this map - lectern has been destroyed, if it existed - if (!session.getGeyser().getWorldManager().shouldExpectLecternHandled(session)) { - session.getLecternCache().remove(position); - } - } - public Item asItem() { if (this.item == null) { return this.item = Item.byBlock(this); diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java b/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java index a312a7d5a..36c31f32e 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java @@ -56,6 +56,15 @@ public final class BlockState { return (T) get(property); } + public > T getValueNullable(Property property) { + var value = get(property); + if (value == null) { + return null; + } + //noinspection unchecked + return (T) get(property); + } + public boolean getValue(Property property, boolean def) { var value = get(property); if (value == null) { diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/LecternBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/LecternBlock.java index 6b8aa02b5..3139bd6de 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/LecternBlock.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/LecternBlock.java @@ -27,35 +27,67 @@ package org.geysermc.geyser.level.block.type; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; -import org.geysermc.erosion.util.LecternUtils; +import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.level.WorldManager; import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.level.block.entity.BedrockChunkWantsBlockEntityTag; +import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator; import org.geysermc.geyser.util.BlockEntityUtils; -public class LecternBlock extends Block { +import java.util.Collections; + +public class LecternBlock extends Block implements BedrockChunkWantsBlockEntityTag { public LecternBlock(String javaIdentifier, Builder builder) { super(javaIdentifier, builder); } @Override - protected void handleLecternBlockUpdate(GeyserSession session, BlockState state, Vector3i position) { - WorldManager worldManager = session.getGeyser().getWorldManager(); - if (worldManager.shouldExpectLecternHandled(session)) { - worldManager.sendLecternData(session, position.getX(), position.getY(), position.getZ()); - return; - } + public NbtMap createTag(GeyserSession session, Vector3i position, BlockState blockState) { + return getBaseLecternTag(position, blockState.getValue(Properties.HAS_BOOK)); + } + @Override + public void updateBlock(GeyserSession session, BlockState state, Vector3i position) { + WorldManager worldManager = session.getGeyser().getWorldManager(); boolean currentHasBook = state.getValue(Properties.HAS_BOOK); - Boolean previousHasBook = worldManager.blockAt(session, position).getValue(Properties.HAS_BOOK); // Can be null if not a lectern, watch out - if (currentHasBook != previousHasBook) { - if (currentHasBook) { - worldManager.sendLecternData(session, position.getX(), position.getY(), position.getZ()); - } else { - session.getLecternCache().remove(position); - NbtMap newLecternTag = LecternUtils.getBaseLecternTag(position.getX(), position.getY(), position.getZ(), 0).build(); - BlockEntityUtils.updateBlockEntity(session, newLecternTag, position); - } + Boolean previousHasBook = worldManager.blockAt(session, position).getValueNullable(Properties.HAS_BOOK); // Can be null if not a lectern, watch out + if (previousHasBook == null || currentHasBook != previousHasBook) { + BlockEntityUtils.updateBlockEntity(session, getBaseLecternTag(position, currentHasBook), position); + } + super.updateBlock(session, state, position); + } + + public static NbtMap getBaseLecternTag(Vector3i position, boolean hasBook) { + if (hasBook) { + return getBaseLecternTag(position, 1) + .putCompound("book", NbtMap.builder() + .putByte("Count", (byte) 1) + .putShort("Damage", (short) 0) + .putString("Name", "minecraft:writable_book") + .putCompound("tag", NbtMap.builder().putList("pages", NbtType.COMPOUND, Collections.singletonList( + NbtMap.builder() + .putString("photoname", "") + .putString("text", "") + .build() + )).build()) + .build()) + .build(); + } else { + return getBaseLecternTag(position, 0).build(); } } + + public static NbtMapBuilder getBaseLecternTag(Vector3i position, int pages) { + NbtMapBuilder builder = BlockEntityTranslator.getConstantBedrockTag("Lectern", position); + builder.putBoolean("isMovable", true); + + if (pages != 0) { + builder.putByte("hasBook", (byte) 1); + builder.putInt("totalPages", 1); // we'll override it anyway + } + + return builder; + } } diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 9d2a3ef06..17010e966 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -99,7 +99,6 @@ import org.geysermc.geyser.inventory.recipe.GeyserStonecutterData; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.BlockItem; import org.geysermc.geyser.level.JavaDimension; -import org.geysermc.geyser.level.WorldManager; import org.geysermc.geyser.level.physics.CollisionManager; import org.geysermc.geyser.network.netty.LocalSession; import org.geysermc.geyser.registry.Registries; @@ -257,13 +256,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { */ private final Map itemFrameCache = new Object2ObjectOpenHashMap<>(); - /** - * Stores a list of all lectern locations and their block entity tags. - * See {@link WorldManager#sendLecternData(GeyserSession, int, int, int)} - * for more information. - */ - private final @Nullable Set lecternCache; - /** * A list of all players that have a player head on with a custom texture. * Our workaround for these players is to give them a custom skin and geometry to emulate wearing a custom skull. @@ -609,13 +601,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { this.spawned = false; this.loggedIn = false; - if (geyser.getWorldManager().shouldExpectLecternHandled(this)) { - // Unneeded on these platforms - this.lecternCache = null; - } else { - this.lecternCache = new ObjectOpenHashSet<>(); - } - if (geyser.getConfig().getEmoteOffhandWorkaround() != EmoteOffhandWorkaroundOption.NO_EMOTES) { this.emotes = new HashSet<>(); geyser.getSessionManager().getSessions().values().forEach(player -> this.emotes.addAll(player.getEmotes())); diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java index 8fe1e96c0..3b33f5909 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java @@ -28,13 +28,18 @@ package org.geysermc.geyser.translator.inventory; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; -import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.erosion.util.LecternUtils; import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.inventory.*; +import org.geysermc.geyser.inventory.Container; +import org.geysermc.geyser.inventory.GeyserItemStack; +import org.geysermc.geyser.inventory.Inventory; +import org.geysermc.geyser.inventory.LecternContainer; +import org.geysermc.geyser.inventory.PlayerInventory; import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater; import org.geysermc.geyser.level.block.Blocks; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.level.block.type.LecternBlock; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.BlockEntityUtils; import org.geysermc.geyser.util.InventoryUtils; @@ -44,8 +49,6 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.component.WritableBook import org.geysermc.mcprotocollib.protocol.data.game.item.component.WrittenBookContent; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; -import java.util.Collections; - public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator { /** @@ -95,7 +98,10 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator // Now: Restore the lectern, if it actually exists if (lecternContainer.isUsingRealBlock()) { - GeyserImpl.getInstance().getWorldManager().sendLecternData(session, position.getX(), position.getY(), position.getZ()); + boolean hasBook = session.getGeyser().getWorldManager().blockAt(session, position).getValue(Properties.HAS_BOOK, false); + + NbtMap map = LecternBlock.getBaseLecternTag(position, hasBook); + BlockEntityUtils.updateBlockEntity(session, map, position); } } @@ -148,7 +154,8 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator session.setDroppingLecternBook(false); InventoryUtils.closeInventory(session, inventory.getJavaId(), false); } else if (lecternContainer.getBlockEntityTag() == null) { - Vector3i position = lecternContainer.isUsingRealBlock() ? session.getLastInteractionBlockPosition() : inventory.getHolderPosition(); + Vector3i position = lecternContainer.isUsingRealBlock() ? + session.getLastInteractionBlockPosition() : inventory.getHolderPosition(); NbtMap blockEntityTag; if (book.getComponents() != null) { @@ -164,7 +171,7 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator } ItemData itemData = book.getItemData(session); - NbtMapBuilder lecternTag = LecternUtils.getBaseLecternTag(position.getX(), position.getY(), position.getZ(), pages); + NbtMapBuilder lecternTag = LecternBlock.getBaseLecternTag(position, pages); lecternTag.putCompound("book", NbtMap.builder() .putByte("Count", (byte) itemData.getCount()) .putShort("Damage", (short) 0) @@ -175,19 +182,7 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator blockEntityTag = lecternTag.build(); } else { // There is *a* book here, but... no NBT. - NbtMapBuilder lecternTag = LecternUtils.getBaseLecternTag(position.getX(), position.getY(), position.getZ(), 1); - NbtMapBuilder bookTag = NbtMap.builder() - .putByte("Count", (byte) 1) - .putShort("Damage", (short) 0) - .putString("Name", "minecraft:writable_book") - .putCompound("tag", NbtMap.builder().putList("pages", NbtType.COMPOUND, Collections.singletonList( - NbtMap.builder() - .putString("photoname", "") - .putString("text", "") - .build() - )).build()); - - blockEntityTag = lecternTag.putCompound("book", bookTag.build()).build(); + blockEntityTag = LecternBlock.getBaseLecternTag(position, true); } // Even with serverside access to lecterns, we don't easily know which lectern this is, so we need to rebuild diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaForgetLevelChunkTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaForgetLevelChunkTranslator.java index b0abe0f59..e687e6f46 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaForgetLevelChunkTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaForgetLevelChunkTranslator.java @@ -33,7 +33,6 @@ import org.geysermc.geyser.util.ChunkUtils; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundForgetLevelChunkPacket; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; @Translator(packet = ClientboundForgetLevelChunkPacket.class) @@ -52,17 +51,6 @@ public class JavaForgetLevelChunkTranslator extends PacketTranslator iterator = session.getLecternCache().iterator(); - while (iterator.hasNext()) { - Vector3i position = iterator.next(); - if ((position.getX() >> 4) == packet.getX() && (position.getZ() >> 4) == packet.getZ()) { - iterator.remove(); - } - } - } - ChunkUtils.sendEmptyChunk(session, packet.getX(), packet.getZ(), false); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java index 18d12422e..e37edef66 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java @@ -34,14 +34,11 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NBTOutputStream; import org.cloudburstmc.nbt.NbtMap; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtUtils; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.packet.LevelChunkPacket; -import org.geysermc.erosion.util.LecternUtils; import org.geysermc.geyser.entity.type.ItemFrameEntity; import org.geysermc.geyser.level.BedrockDimension; -import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.level.chunk.BlockStorage; @@ -98,7 +95,6 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator bedrockBlockEntities = new ObjectArrayList<>(blockEntities.length); - final List lecterns = new ObjectArrayList<>(); BitSet waterloggedPaletteIds = new BitSet(); BitSet bedrockOnlyBlockEntityIds = new BitSet(); @@ -318,7 +314,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator> 4) - yOffset]; BlockState blockState = BlockRegistries.BLOCK_STATES.get(section.get(x, y & 0xF, z)); - if (type == BlockEntityType.LECTERN && blockState.getValue(Properties.HAS_BOOK)) { - // If getLecternBookStates is false, let's just treat it like a normal block entity - // Fill in tag with a default value - NbtMapBuilder lecternTag = LecternUtils.getBaseLecternTag(x + chunkBlockX, y, z + chunkBlockZ, 1); - lecternTag.putCompound("book", NbtMap.builder() - .putByte("Count", (byte) 1) - .putShort("Damage", (short) 0) - .putString("Name", "minecraft:written_book").build()); - lecternTag.putInt("page", -1); - bedrockBlockEntities.add(lecternTag.build()); - lecterns.add(blockEntity); - continue; - } - // Note that, since 1.20.5, tags can be null, but Bedrock still needs a default tag to render the item // Also, some properties - like banner base colors - are part of the tag and is processed here. BlockEntityTranslator blockEntityTranslator = BlockEntityUtils.getBlockEntityTranslator(type); @@ -525,10 +507,6 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator entry : session.getItemFrameCache().entrySet()) { Vector3i position = entry.getKey(); if ((position.getX() >> 4) == packet.getX() && (position.getZ() >> 4) == packet.getZ()) { diff --git a/core/src/main/java/org/geysermc/geyser/util/DimensionUtils.java b/core/src/main/java/org/geysermc/geyser/util/DimensionUtils.java index 54e1cc34a..8446a340a 100644 --- a/core/src/main/java/org/geysermc/geyser/util/DimensionUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/DimensionUtils.java @@ -65,9 +65,6 @@ public class DimensionUtils { session.getChunkCache().clear(); session.getEntityCache().removeAllEntities(); session.getItemFrameCache().clear(); - if (session.getLecternCache() != null) { - session.getLecternCache().clear(); - } session.getLodestoneCache().clear(); session.getPistonCache().clear(); session.getSkullCache().clear(); diff --git a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java index d253d2f8b..48ade52e2 100644 --- a/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/InventoryUtils.java @@ -479,7 +479,6 @@ public class InventoryUtils { for (int col = firstCol; col < width + firstCol; col++) { GeyserItemStack geyserItemStack = inventoryGetter.apply(col + (row * gridDimensions) + 1); if (geyserItemStack.isEmpty()) { - //noinspection ConstantValue inventoryHasItem = itemStack == null || itemStack.getId() == 0; if (inventoryHasItem) { break crafting; From 7ba95f1ad3715c2e9fe3676c44ed18659c64b097 Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Tue, 28 May 2024 00:11:05 -0700 Subject: [PATCH 199/272] Composite gradle setup and artifact archival (#4696) * Composite gradle setup and artifact archival * Remove 'geyser' path for PRs * Move upload-preview workflow --- .github/workflows/build-remote.yml | 85 +++++-------------------- .github/workflows/build.yml | 86 +++++--------------------- .github/workflows/dispatch-preview.yml | 33 ++++++++++ .github/workflows/preview.yml | 83 ------------------------- .github/workflows/pull-request.yml | 16 ++++- 5 files changed, 77 insertions(+), 226 deletions(-) create mode 100644 .github/workflows/dispatch-preview.yml delete mode 100644 .github/workflows/preview.yml diff --git a/.github/workflows/build-remote.yml b/.github/workflows/build-remote.yml index c815b4740..7cb89cc61 100644 --- a/.github/workflows/build-remote.yml +++ b/.github/workflows/build-remote.yml @@ -22,81 +22,26 @@ jobs: run: | echo "BUILD_NUMBER=${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV - - name: Setup Java - # See https://github.com/actions/setup-java/commits - uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1 - with: - java-version: 21 - distribution: temurin - - - name: Checkout repository and submodules - # See https://github.com/actions/checkout/commits - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - with: - repository: ${{ inputs.repository }} - ref: ${{ inputs.ref }} - submodules: recursive - - - name: Validate Gradle Wrapper - # See https://github.com/gradle/wrapper-validation-action/commits - uses: gradle/actions/wrapper-validation@db19848a5fa7950289d3668fb053140cf3028d43 # v3.3.2 - - name: Setup Gradle - # See https://github.com/gradle/actions/commits - uses: gradle/actions/setup-gradle@db19848a5fa7950289d3668fb053140cf3028d43 # v3.3.2 + uses: GeyserMC/actions/setup-gradle-composite@master with: - cache-read-only: true + checkout_repository: ${{ inputs.repository }} + checkout_ref: ${{ inputs.ref }} + setup-java_java-version: 21 + setup-gradle_cache-read-only: true - name: Build Geyser run: ./gradlew build - - name: Archive artifacts (Geyser Fabric) - # See https://github.com/actions/upload-artifact/commits - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + - name: Archive Artifacts + uses: GeyserMC/actions/upload-multi-artifact@master if: success() with: - name: Geyser Fabric - path: geyser/bootstrap/mod/fabric/build/libs/Geyser-Fabric.jar - if-no-files-found: error - - name: Archive artifacts (Geyser NeoForge) - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 - if: success() - with: - name: Geyser NeoForge - path: geyser/bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar - if-no-files-found: error - - name: Archive artifacts (Geyser Standalone) - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 - if: success() - with: - name: Geyser Standalone - path: geyser/bootstrap/standalone/build/libs/Geyser-Standalone.jar - if-no-files-found: error - - name: Archive artifacts (Geyser Spigot) - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 - if: success() - with: - name: Geyser Spigot - path: geyser/bootstrap/spigot/build/libs/Geyser-Spigot.jar - if-no-files-found: error - - name: Archive artifacts (Geyser BungeeCord) - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 - if: success() - with: - name: Geyser BungeeCord - path: geyser/bootstrap/bungeecord/build/libs/Geyser-BungeeCord.jar - if-no-files-found: error - - name: Archive artifacts (Geyser Velocity) - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 - if: success() - with: - name: Geyser Velocity - path: geyser/bootstrap/velocity/build/libs/Geyser-Velocity.jar - if-no-files-found: error - - name: Archive artifacts (Geyser ViaProxy) - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 - if: success() - with: - name: Geyser ViaProxy - path: geyser/bootstrap/viaproxy/build/libs/Geyser-ViaProxy.jar - if-no-files-found: error \ No newline at end of file + artifacts: | + bootstrap/mod/fabric/build/libs/Geyser-Fabric.jar + bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar + bootstrap/standalone/build/libs/Geyser-Standalone.jar + bootstrap/spigot/build/libs/Geyser-Spigot.jar + bootstrap/bungeecord/build/libs/Geyser-BungeeCord.jar + bootstrap/velocity/build/libs/Geyser-Velocity.jar + bootstrap/viaproxy/build/libs/Geyser-ViaProxy.jar \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f2f2a2c82..b8f855a53 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,84 +28,28 @@ jobs: with: data: ${{ vars.RELEASEACTION_PREVRELEASE }} - - name: Checkout repository and submodules - # See https://github.com/actions/checkout/commits - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - with: - submodules: recursive - - - name: Validate Gradle Wrapper - # See https://github.com/gradle/actions/commits - uses: gradle/actions/wrapper-validation@db19848a5fa7950289d3668fb053140cf3028d43 # v3.3.2 - - # See https://github.com/actions/setup-java/commits - - name: Setup Java - uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1 - with: - java-version: 21 - distribution: temurin - - name: Setup Gradle - # See https://github.com/gradle/actions/commits - uses: gradle/actions/setup-gradle@db19848a5fa7950289d3668fb053140cf3028d43 # v3.3.2 + uses: GeyserMC/actions/setup-gradle-composite@master with: - gradle-home-cache-cleanup: true + setup-java_java-version: 21 - name: Build Geyser run: ./gradlew build env: BUILD_NUMBER: ${{ steps.release-info.outputs.curentRelease }} - - name: Archive artifacts (Geyser Fabric) - # See https://github.com/actions/upload-artifact/commits - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + - name: Archive Artifacts + uses: GeyserMC/actions/upload-multi-artifact@master if: success() with: - name: Geyser Fabric - path: bootstrap/mod/fabric/build/libs/Geyser-Fabric.jar - if-no-files-found: error - - name: Archive artifacts (Geyser NeoForge) - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 - if: success() - with: - name: Geyser NeoForge - path: bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar - if-no-files-found: error - - name: Archive artifacts (Geyser Standalone) - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 - if: success() - with: - name: Geyser Standalone - path: bootstrap/standalone/build/libs/Geyser-Standalone.jar - if-no-files-found: error - - name: Archive artifacts (Geyser Spigot) - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 - if: success() - with: - name: Geyser Spigot - path: bootstrap/spigot/build/libs/Geyser-Spigot.jar - if-no-files-found: error - - name: Archive artifacts (Geyser BungeeCord) - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 - if: success() - with: - name: Geyser BungeeCord - path: bootstrap/bungeecord/build/libs/Geyser-BungeeCord.jar - if-no-files-found: error - - name: Archive artifacts (Geyser Velocity) - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 - if: success() - with: - name: Geyser Velocity - path: bootstrap/velocity/build/libs/Geyser-Velocity.jar - if-no-files-found: error - - name: Archive artifacts (Geyser ViaProxy) - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 - if: success() - with: - name: Geyser ViaProxy - path: bootstrap/viaproxy/build/libs/Geyser-ViaProxy.jar - if-no-files-found: error + artifacts: | + bootstrap/mod/fabric/build/libs/Geyser-Fabric.jar + bootstrap/mod/neoforge/build/libs/Geyser-NeoForge.jar + bootstrap/standalone/build/libs/Geyser-Standalone.jar + bootstrap/spigot/build/libs/Geyser-Spigot.jar + bootstrap/bungeecord/build/libs/Geyser-BungeeCord.jar + bootstrap/velocity/build/libs/Geyser-Velocity.jar + bootstrap/viaproxy/build/libs/Geyser-ViaProxy.jar - name: Publish to Maven Repository if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} @@ -116,14 +60,14 @@ jobs: ORG_GRADLE_PROJECT_geysermcPassword: ${{ secrets.DEPLOY_PASS }} - name: Get Version - if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} + if: ${{ (success() || failure()) && github.repository == 'GeyserMC/Geyser' }} id: get-version run: | version=$(cat gradle.properties | grep -o "version=[0-9\\.]*" | cut -d"=" -f2) echo "VERSION=${version}" >> $GITHUB_OUTPUT - name: Get Release Metadata - if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} + if: ${{ (success() || failure()) && github.repository == 'GeyserMC/Geyser' }} uses: GeyserMC/actions/release@master id: metadata with: @@ -141,6 +85,7 @@ jobs: saveMetadata: true releaseProject: 'geyser' releaseVersion: ${{ steps.get-version.outputs.VERSION }} + - name: Publish to Downloads API if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} uses: GeyserMC/actions/upload-release@master @@ -156,6 +101,7 @@ jobs: bootstrap/standalone/build/libs/Geyser-Standalone.jar bootstrap/velocity/build/libs/Geyser-Velocity.jar bootstrap/viaproxy/build/libs/Geyser-ViaProxy.jar + changelog: ${{ steps.metadata.outputs.body }} - name: Publish to Modrinth (Fabric) if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} diff --git a/.github/workflows/dispatch-preview.yml b/.github/workflows/dispatch-preview.yml new file mode 100644 index 000000000..83df08e37 --- /dev/null +++ b/.github/workflows/dispatch-preview.yml @@ -0,0 +1,33 @@ +name: Dispatch Preview + +on: + workflow_dispatch: + inputs: + runId: + required: true + description: 'ID of the action to pull artifacts from' + build: + required: true + description: 'Build number for the release' + version: + required: true + description: 'Version under which to upload to the Downloads API' + +jobs: + dispatch-preview: + # Allow access to secrets if we are uploading a preview + secrets: inherit + uses: GeyserMC/actions/.github/workflows/upload-preview.yml@master + with: + build: ${{ inputs.build }} + version: ${{ inputs.version }} + files: | + bungeecord:Geyser-BungeeCord.jar + fabric:Geyser-Fabric.jar + neoforge:Geyser-NeoForge.jar + spigot:Geyser-Spigot.jar + standalone:Geyser-Standalone.jar + velocity:Geyser-Velocity.jar + viaproxy:Geyser-ViaProxy.jar + project: geyserpreview + runId: ${{ inputs.runId }} \ No newline at end of file diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml deleted file mode 100644 index a90d60ef7..000000000 --- a/.github/workflows/preview.yml +++ /dev/null @@ -1,83 +0,0 @@ -name: Upload Preview - -on: - workflow_dispatch: - inputs: - runId: - required: true - description: 'ID of the action to pull artifacts from' - build: - required: true - description: 'Build number for the release' - version: - required: true - description: 'Version under which to upload to the Downloads API' - workflow_call: - inputs: - build: - required: true - description: 'Build number for the release' - type: string - version: - required: true - description: 'Version under which to upload to the Downloads API' - type: string - -jobs: - upload: - runs-on: ubuntu-latest - steps: - - name: Set Variables - id: setvars - run: | - if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then - echo "BUILD=${{ github.event.inputs.build }}" >> $GITHUB_ENV - echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT - echo "RUN=${{ github.event.inputs.runId }}" >> $GITHUB_OUTPUT - else - echo "BUILD=${{ inputs.build }}" >> $GITHUB_ENV - echo "VERSION=${{ inputs.version }}" >> $GITHUB_OUTPUT - echo "RUN=${{ github.run_id }}" >> $GITHUB_OUTPUT - fi - - name: Download Artifacts - # See https://github.com/actions/download-artifact/commits - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.6 - with: - run-id: ${{ steps.setvars.outputs.RUN }} - github-token: ${{ secrets.GITHUB_TOKEN }} - merge-multiple: true - - name: Get Preview Metadata - if: success() - uses: GeyserMC/actions/release@master - id: metadata - with: - appID: ${{ secrets.RELEASE_APP_ID }} - appPrivateKey: ${{ secrets.RELEASE_APP_PK }} - files: | - bungeecord:Geyser-BungeeCord.jar - fabric:Geyser-Fabric.jar - neoforge:Geyser-NeoForge.jar - spigot:Geyser-Spigot.jar - standalone:Geyser-Standalone.jar - velocity:Geyser-Velocity.jar - viaproxy:Geyser-ViaProxy.jar - releaseEnabled: false - saveMetadata: true - updateReleaseData: false - releaseProject: 'geyserpreview' - releaseVersion: ${{ steps.setvars.outputs.VERSION }} - - name: Publish to Downloads API - if: success() - uses: GeyserMC/actions/upload-release@master - with: - username: ${{ vars.DOWNLOADS_USERNAME }} - privateKey: ${{ secrets.DOWNLOADS_PRIVATE_KEY }} - host: ${{ secrets.DOWNLOADS_SERVER_IP }} - files: | - Geyser-BungeeCord.jar - Geyser-Fabric.jar - Geyser-NeoForge.jar - Geyser-Spigot.jar - Geyser-Standalone.jar - Geyser-Velocity.jar - Geyser-ViaProxy.jar diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index bc5e57b6b..6167bb18e 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -8,7 +8,7 @@ jobs: # Forbid access to secrets nor GH Token perms while building the PR permissions: {} secrets: {} - uses: ./.github/workflows/build-remote.yml + uses: GeyserMC/Geyser/.github/workflows/build-remote.yml@master with: repository: ${{ github.event.pull_request.head.repo.full_name }} ref: ${{ github.event.pull_request.head.sha }} @@ -18,7 +18,17 @@ jobs: contains(github.event.pull_request.labels.*.name, 'PR: Needs Testing') # Allow access to secrets if we are uploading a preview secrets: inherit - uses: ./.github/workflows/preview.yml + uses: GeyserMC/actions/.github/workflows/upload-preview.yml@master with: build: ${{ github.run_number }} - version: pr.${{ github.event.pull_request.number }} \ No newline at end of file + version: pr.${{ github.event.pull_request.number }} + files: | + bungeecord:Geyser-BungeeCord.jar + fabric:Geyser-Fabric.jar + neoforge:Geyser-NeoForge.jar + spigot:Geyser-Spigot.jar + standalone:Geyser-Standalone.jar + velocity:Geyser-Velocity.jar + viaproxy:Geyser-ViaProxy.jar + project: geyserpreview + runId: ${{ github.run_id }} \ No newline at end of file From dc154915f0637ec02c04ef582f30e5ca0f4b814f Mon Sep 17 00:00:00 2001 From: Kas-tle <26531652+Kas-tle@users.noreply.github.com> Date: Wed, 29 May 2024 01:48:33 -0700 Subject: [PATCH 200/272] Only include downloads on master --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b8f855a53..0e94ce965 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -124,3 +124,4 @@ jobs: discordWebhook: ${{ secrets.DISCORD_WEBHOOK }} status: ${{ job.status }} body: ${{ steps.metadata.outputs.body }} + includeDownloads: ${{ github.ref_name == 'master' }} From 8be60b41bf64e9dfec184d9047aa604bb7836b2a Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Wed, 29 May 2024 22:36:38 +0200 Subject: [PATCH 201/272] Remove lectern/item frame dropping handling for pre 1.20.60 --- .../BedrockItemFrameDropItemTranslator.java | 57 ------------ .../BedrockLecternUpdateTranslator.java | 88 +++++++------------ 2 files changed, 34 insertions(+), 111 deletions(-) delete mode 100644 core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockItemFrameDropItemTranslator.java diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockItemFrameDropItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockItemFrameDropItemTranslator.java deleted file mode 100644 index dff4631b0..000000000 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockItemFrameDropItemTranslator.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.geyser.translator.protocol.bedrock; - -import org.cloudburstmc.protocol.bedrock.packet.ItemFrameDropItemPacket; -import org.geysermc.geyser.entity.type.Entity; -import org.geysermc.geyser.entity.type.ItemFrameEntity; -import org.geysermc.geyser.session.GeyserSession; -import org.geysermc.geyser.translator.protocol.PacketTranslator; -import org.geysermc.geyser.translator.protocol.Translator; -import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; -import org.geysermc.mcprotocollib.protocol.data.game.entity.player.InteractAction; -import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket; - -/** - * Pre-1.16.210: used for both survival and creative item frame item removal - *

- * 1.16.210: only used in creative. - * 1.20.70: no longer used. - */ -@Translator(packet = ItemFrameDropItemPacket.class) -public class BedrockItemFrameDropItemTranslator extends PacketTranslator { - - // TODO: Remove when 1.20.60 is no longer supported - @Override - public void translate(GeyserSession session, ItemFrameDropItemPacket packet) { - Entity entity = ItemFrameEntity.getItemFrameEntity(session, packet.getBlockPosition()); - if (entity != null) { - ServerboundInteractPacket interactPacket = new ServerboundInteractPacket(entity.getEntityId(), - InteractAction.ATTACK, Hand.MAIN_HAND, session.isSneaking()); - session.sendDownstreamGamePacket(interactPacket); - } - } -} diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockLecternUpdateTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockLecternUpdateTranslator.java index e6d3d4dce..31a2d74cf 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockLecternUpdateTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockLecternUpdateTranslator.java @@ -25,11 +25,6 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; -import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; -import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; -import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; -import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundUseItemOnPacket; import org.cloudburstmc.protocol.bedrock.packet.LecternUpdatePacket; import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.LecternContainer; @@ -38,6 +33,8 @@ import org.geysermc.geyser.translator.inventory.LecternInventoryTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.InventoryUtils; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; /** * Used to translate moving pages, or closing the inventory @@ -47,61 +44,44 @@ public class BedrockLecternUpdateTranslator extends PacketTranslator currentJavaPage) { + for (int i = currentJavaPage; i < newJavaPage; i++) { + ServerboundContainerButtonClickPacket clickButtonPacket = new ServerboundContainerButtonClickPacket(session.getOpenInventory().getJavaId(), 2); + session.sendDownstreamGamePacket(clickButtonPacket); } - - // Send as many click button packets as we need to - // Java has the option to specify exact page numbers by adding 100 to the number, but buttonId variable - // is a byte when transmitted over the network and therefore this stops us at 128 - if (newJavaPage > currentJavaPage) { - for (int i = currentJavaPage; i < newJavaPage; i++) { - ServerboundContainerButtonClickPacket clickButtonPacket = new ServerboundContainerButtonClickPacket(session.getOpenInventory().getJavaId(), 2); - session.sendDownstreamGamePacket(clickButtonPacket); - } - } else { - for (int i = currentJavaPage; i > newJavaPage; i--) { - ServerboundContainerButtonClickPacket clickButtonPacket = new ServerboundContainerButtonClickPacket(session.getOpenInventory().getJavaId(), 1); - session.sendDownstreamGamePacket(clickButtonPacket); - } + } else { + for (int i = currentJavaPage; i > newJavaPage; i--) { + ServerboundContainerButtonClickPacket clickButtonPacket = new ServerboundContainerButtonClickPacket(session.getOpenInventory().getJavaId(), 1); + session.sendDownstreamGamePacket(clickButtonPacket); } } } From 66f30a2cb6f477ec8ff9d9aa34ec015a6cd6891d Mon Sep 17 00:00:00 2001 From: chris Date: Wed, 29 May 2024 23:43:39 +0200 Subject: [PATCH 202/272] Ensure we send commands/chat the same way a Java client would (#4703) * Ensure we send commands/chat the same way a Java client would * yeet static import, move blank check --- .../BedrockCommandRequestTranslator.java | 12 ++++--- .../bedrock/BedrockTextTranslator.java | 11 ++++++- .../translator/text/MessageTranslator.java | 33 +++++++++++++++++++ 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandRequestTranslator.java index 322d64cce..8d4df6f3f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandRequestTranslator.java @@ -26,8 +26,8 @@ package org.geysermc.geyser.translator.protocol.bedrock; import org.cloudburstmc.protocol.bedrock.packet.CommandRequestPacket; -import org.geysermc.geyser.api.util.PlatformType; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.api.util.PlatformType; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; @@ -39,15 +39,17 @@ public class BedrockCommandRequestTranslator extends PacketTranslator { @Override public void translate(GeyserSession session, TextPacket packet) { - String message = MessageTranslator.convertToPlainText(packet.getMessage()); + // Java trims all messages, and then checks for the leading slash + String message = MessageTranslator.convertToPlainText( + MessageTranslator.normalizeSpace(packet.getMessage()) + ); if (message.isBlank()) { // Java Edition (as of 1.17.1) just doesn't pass on these messages, so... we won't either! return; } + if (message.startsWith("/")) { + // Yes, Java actually allows whitespaces before commands and will still see those as valid + BedrockCommandRequestTranslator.handleCommand(session, message.substring(1)); + return; + } + if (MessageTranslator.isTooLong(message, session)) { return; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java index 5a0121039..bf6fdd763 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java @@ -387,6 +387,39 @@ public class MessageTranslator { return false; } + /** + * Normalizes whitespaces - a thing a vanilla client apparently does with commands and chat messages. + */ + public static String normalizeSpace(String string) { + if (string == null || string.isEmpty()) { + return string; + } + final int size = string.length(); + final char[] newChars = new char[size]; + int count = 0; + int whitespacesCount = 0; + boolean startWhitespaces = true; + for (int i = 0; i < size; i++) { + final char actualChar = string.charAt(i); + final boolean isWhitespace = Character.isWhitespace(actualChar); + if (isWhitespace) { + if (whitespacesCount == 0 && !startWhitespaces) { + newChars[count++] = ' '; + } + whitespacesCount++; + } else { + startWhitespaces = false; + // Replace non-breaking spaces with regular spaces for normalization + newChars[count++] = (actualChar == '\u00A0' ? ' ' : actualChar); + whitespacesCount = 0; + } + } + if (startWhitespaces) { + return ""; + } + return new String(newChars, 0, count - (whitespacesCount > 0 ? 1 : 0)).trim(); + } + public static void init() { // no-op } From c8fbffb6383713f64fe8c4a902cd78332b02941a Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Wed, 29 May 2024 21:47:50 -0400 Subject: [PATCH 203/272] Piston head correct pick block behavior --- .../geysermc/geyser/level/block/Blocks.java | 2 +- .../level/block/type/PistonHeadBlock.java | 42 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 core/src/main/java/org/geysermc/geyser/level/block/type/PistonHeadBlock.java diff --git a/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java b/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java index fa605c079..857a3fc13 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/Blocks.java @@ -315,7 +315,7 @@ public final class Blocks { public static final Block PISTON = register(new PistonBlock("piston", builder().destroyTime(1.5f).pushReaction(PistonBehavior.BLOCK) .booleanState(EXTENDED) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN))); - public static final Block PISTON_HEAD = register(new Block("piston_head", builder().destroyTime(1.5f).pushReaction(PistonBehavior.BLOCK) + public static final Block PISTON_HEAD = register(new PistonHeadBlock("piston_head", builder().destroyTime(1.5f).pushReaction(PistonBehavior.BLOCK) .enumState(FACING, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN) .booleanState(SHORT) .enumState(PISTON_TYPE))); diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/PistonHeadBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/PistonHeadBlock.java new file mode 100644 index 000000000..8a6b4f41c --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/PistonHeadBlock.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level.block.type; + +import org.geysermc.geyser.level.block.Blocks; +import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; + +public class PistonHeadBlock extends Block { + public PistonHeadBlock(String javaIdentifier, Builder builder) { + super(javaIdentifier, builder); + } + + @Override + public ItemStack pickItem(BlockState state) { + Block block = state.getValue(Properties.PISTON_TYPE).equals("sticky") ? Blocks.STICKY_PISTON : Blocks.PISTON; + return new ItemStack(block.asItem().javaId()); + } +} From da5d8006ad182b550392393bb68187677be36c30 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Thu, 30 May 2024 22:29:00 -0400 Subject: [PATCH 204/272] Add native offhand support for *some* items About 46 items are data-driven enough where we can tell Bedrock these items are permitted in the offhand. --- .../populator/ItemRegistryPopulator.java | 27 +++++++++++++++++++ core/src/main/resources/mappings | 2 +- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java index 5fcea504f..8f515c1cb 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java @@ -38,6 +38,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; +import org.cloudburstmc.nbt.NbtUtils; import org.cloudburstmc.protocol.bedrock.codec.v671.Bedrock_v671; import org.cloudburstmc.protocol.bedrock.codec.v685.Bedrock_v685; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; @@ -102,6 +103,13 @@ public class ItemRegistryPopulator { throw new AssertionError("Unable to load Java runtime item IDs", e); } + NbtMap vanillaComponents; + try (InputStream stream = bootstrap.getResourceOrThrow("mappings/item_components.nbt")) { + vanillaComponents = (NbtMap) NbtUtils.createGZIPReader(stream, true, true).readTag(); + } catch (Exception e) { + throw new AssertionError("Unable to load Bedrock item components", e); + } + boolean customItemsAllowed = GeyserImpl.getInstance().getConfig().isAddNonBedrockItems(); // List values here is important compared to HashSet - we need to preserve the order of what's given to us @@ -531,6 +539,25 @@ public class ItemRegistryPopulator { } } + for (Map.Entry entry : vanillaComponents.entrySet()) { + String id = entry.getKey(); + ItemDefinition definition = definitions.get(id); + if (definition == null) { + // Newer item most likely + GeyserImpl.getInstance().getLogger().debug( + "Skipping vanilla component " + id + " for protocol " + palette.protocolVersion() + ); + continue; + } + + NbtMapBuilder root = NbtMap.builder() + .putString("name", id) + .putInt("id", definition.getRuntimeId()) + .putCompound("components", (NbtMap) entry.getValue()); + + componentItemData.add(new ComponentItemData(id, root.build())); + } + // Register the item forms of custom blocks if (BlockRegistries.CUSTOM_BLOCKS.get().length != 0) { for (CustomBlockData customBlock : BlockRegistries.CUSTOM_BLOCKS.get()) { diff --git a/core/src/main/resources/mappings b/core/src/main/resources/mappings index ec45f59c8..88e50df10 160000 --- a/core/src/main/resources/mappings +++ b/core/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit ec45f59c8590945c9226921ef7e339f510983dc1 +Subproject commit 88e50df1008916c266428ac11f76f07dc24638c5 From 214cc5a8240faa733ebf19682599fa3ab546198d Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 1 Jun 2024 01:25:30 -0400 Subject: [PATCH 205/272] Initial changes for Java 1.21 --- core/src/main/java/org/geysermc/geyser/item/Items.java | 9 ++++++--- .../java/org/geysermc/geyser/network/GameProtocol.java | 2 +- .../geyser/registry/populator/Conversion685_671.java | 6 ++++++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/Items.java b/core/src/main/java/org/geysermc/geyser/item/Items.java index 8c271a7bb..732ee558a 100644 --- a/core/src/main/java/org/geysermc/geyser/item/Items.java +++ b/core/src/main/java/org/geysermc/geyser/item/Items.java @@ -838,6 +838,7 @@ public final class Items { public static final Item ARMADILLO_SCUTE = register(new Item("armadillo_scute", builder())); public static final Item WOLF_ARMOR = register(new ArmorItem("wolf_armor", ArmorMaterial.ARMADILLO, builder().stackSize(1).maxDamage(64))); public static final Item FLINT_AND_STEEL = register(new Item("flint_and_steel", builder().stackSize(1).maxDamage(64))); + public static final Item BOWL = register(new Item("bowl", builder())); public static final Item APPLE = register(new Item("apple", builder())); public static final Item BOW = register(new Item("bow", builder().stackSize(1).maxDamage(384))); public static final Item ARROW = register(new ArrowItem("arrow", builder())); @@ -887,7 +888,6 @@ public final class Items { public static final Item NETHERITE_AXE = register(new TieredItem("netherite_axe", ToolTier.NETHERITE, builder().stackSize(1).maxDamage(2031).attackDamage(10.0))); public static final Item NETHERITE_HOE = register(new TieredItem("netherite_hoe", ToolTier.NETHERITE, builder().stackSize(1).maxDamage(2031).attackDamage(1.0))); public static final Item STICK = register(new Item("stick", builder())); - public static final Item BOWL = register(new Item("bowl", builder())); public static final Item MUSHROOM_STEW = register(new Item("mushroom_stew", builder().stackSize(1))); public static final Item STRING = register(new BlockItem("string", builder(), Blocks.TRIPWIRE)); public static final Item FEATHER = register(new Item("feather", builder())); @@ -1044,7 +1044,7 @@ public final class Items { public static final Item BLAZE_POWDER = register(new Item("blaze_powder", builder())); public static final Item MAGMA_CREAM = register(new Item("magma_cream", builder())); public static final Item BREWING_STAND = register(new BlockItem(builder(), Blocks.BREWING_STAND)); - public static final Item CAULDRON = register(new BlockItem(builder(), Blocks.CAULDRON, Blocks.LAVA_CAULDRON, Blocks.POWDER_SNOW_CAULDRON, Blocks.WATER_CAULDRON)); + public static final Item CAULDRON = register(new BlockItem(builder(), Blocks.CAULDRON, Blocks.LAVA_CAULDRON, Blocks.WATER_CAULDRON, Blocks.POWDER_SNOW_CAULDRON)); public static final Item ENDER_EYE = register(new Item("ender_eye", builder())); public static final Item GLISTERING_MELON_SLICE = register(new Item("glistering_melon_slice", builder())); public static final Item ARMADILLO_SPAWN_EGG = register(new SpawnEggItem("armadillo_spawn_egg", builder())); @@ -1132,7 +1132,7 @@ public final class Items { public static final Item WIND_CHARGE = register(new Item("wind_charge", builder())); public static final Item WRITABLE_BOOK = register(new WritableBookItem("writable_book", builder().stackSize(1))); public static final Item WRITTEN_BOOK = register(new WrittenBookItem("written_book", builder().stackSize(16))); - public static final Item MACE = register(new MaceItem("mace", builder().stackSize(1).maxDamage(250))); + public static final Item MACE = register(new MaceItem("mace", builder().stackSize(1).maxDamage(500))); public static final Item ITEM_FRAME = register(new Item("item_frame", builder())); public static final Item GLOW_ITEM_FRAME = register(new Item("glow_item_frame", builder())); public static final Item FLOWER_POT = register(new BlockItem(builder(), Blocks.FLOWER_POT)); @@ -1211,6 +1211,8 @@ public final class Items { public static final Item MUSIC_DISC_CAT = register(new Item("music_disc_cat", builder().stackSize(1))); public static final Item MUSIC_DISC_BLOCKS = register(new Item("music_disc_blocks", builder().stackSize(1))); public static final Item MUSIC_DISC_CHIRP = register(new Item("music_disc_chirp", builder().stackSize(1))); + public static final Item MUSIC_DISC_CREATOR = register(new Item("music_disc_creator", builder().stackSize(1))); + public static final Item MUSIC_DISC_CREATOR_MUSIC_BOX = register(new Item("music_disc_creator_music_box", builder().stackSize(1))); public static final Item MUSIC_DISC_FAR = register(new Item("music_disc_far", builder().stackSize(1))); public static final Item MUSIC_DISC_MALL = register(new Item("music_disc_mall", builder().stackSize(1))); public static final Item MUSIC_DISC_MELLOHI = register(new Item("music_disc_mellohi", builder().stackSize(1))); @@ -1223,6 +1225,7 @@ public final class Items { public static final Item MUSIC_DISC_RELIC = register(new Item("music_disc_relic", builder().stackSize(1))); public static final Item MUSIC_DISC_5 = register(new Item("music_disc_5", builder().stackSize(1))); public static final Item MUSIC_DISC_PIGSTEP = register(new Item("music_disc_pigstep", builder().stackSize(1))); + public static final Item MUSIC_DISC_PRECIPICE = register(new Item("music_disc_precipice", builder().stackSize(1))); public static final Item DISC_FRAGMENT_5 = register(new Item("disc_fragment_5", builder())); public static final Item TRIDENT = register(new Item("trident", builder().stackSize(1).maxDamage(250).attackDamage(9.0))); public static final Item PHANTOM_MEMBRANE = register(new Item("phantom_membrane", builder())); diff --git a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java index 1c58288c7..773f0ae32 100644 --- a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java +++ b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java @@ -106,7 +106,7 @@ public final class GameProtocol { * @return the supported Minecraft: Java Edition version names */ public static List getJavaVersions() { - return List.of("1.20.5", DEFAULT_JAVA_CODEC.getMinecraftVersion()); + return List.of(DEFAULT_JAVA_CODEC.getMinecraftVersion()); } /** diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion685_671.java b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion685_671.java index 250fd9d9f..3bb6b5faf 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion685_671.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion685_671.java @@ -27,6 +27,7 @@ package org.geysermc.geyser.registry.populator; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; +import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.registry.type.GeyserMappingItem; @@ -41,10 +42,15 @@ public class Conversion685_671 { private static final List OMINOUS_BLOCKS = List.of("minecraft:trial_spawner", "minecraft:vault"); private static final List NEW_BLOCKS = Stream.of(NEW_CORAL_BLOCKS, NEW_DOUBLE_PLANTS, NEW_STONE_BLOCK_SLABS, NEW_TALLGRASSES).flatMap(List::stream).toList(); private static final List MODIFIED_BLOCKS = Stream.of(NEW_BLOCKS, OMINOUS_BLOCKS).flatMap(List::stream).toList(); + private static final List NEW_MUSIC_DISCS = List.of(Items.MUSIC_DISC_CREATOR, Items.MUSIC_DISC_CREATOR_MUSIC_BOX, Items.MUSIC_DISC_PRECIPICE); static GeyserMappingItem remapItem(@SuppressWarnings("unused") Item item, GeyserMappingItem mapping) { String identifer = mapping.getBedrockIdentifier(); + if (NEW_MUSIC_DISCS.contains(item)) { + return mapping.withBedrockIdentifier("minecraft:music_disc_otherside"); + } + if (!NEW_BLOCKS.contains(identifer)) { return mapping; } From 65fd409a0099be88abe31d00ba21903dbd92eed0 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sun, 2 Jun 2024 20:42:53 -0400 Subject: [PATCH 206/272] Painting re-implemented. Started on enchantments --- .../geyser/entity/type/PaintingEntity.java | 14 ++- .../living/animal/tameable/WolfEntity.java | 38 ++++---- .../org/geysermc/geyser/item/Enchantment.java | 47 +++++++++ .../geysermc/geyser/item/type/BannerItem.java | 4 +- .../geysermc/geyser/level/PaintingType.java | 32 +++++-- .../registry/populator/Conversion685_671.java | 2 +- .../geyser/session/GeyserSession.java | 14 ++- .../geyser/session/cache/RegistryCache.java | 13 ++- .../cache/registry/SimpleJavaRegistry.java | 5 + .../geysermc/geyser/text/TextDecoration.java | 96 ++++++++----------- ...BedrockInventoryTransactionTranslator.java | 6 +- .../BedrockMobEquipmentTranslator.java | 7 +- .../protocol/java/JavaRespawnTranslator.java | 2 +- .../translator/text/MessageTranslator.java | 22 +++-- gradle/libs.versions.toml | 2 +- 15 files changed, 187 insertions(+), 117 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/item/Enchantment.java diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/PaintingEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/PaintingEntity.java index f5145c11f..6d0294783 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/PaintingEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/PaintingEntity.java @@ -30,6 +30,8 @@ import org.cloudburstmc.protocol.bedrock.packet.AddPaintingPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.level.PaintingType; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.Holder; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.PaintingVariant; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; @@ -49,8 +51,14 @@ public class PaintingEntity extends Entity { // Wait until we get the metadata needed } - public void setPaintingType(ObjectEntityMetadata entityMetadata) { - PaintingType type = PaintingType.getByPaintingType(entityMetadata.getValue()); + public void setPaintingType(ObjectEntityMetadata> entityMetadata) { + if (!entityMetadata.getValue().isId()) { + return; + } + PaintingType type = session.getRegistryCache().paintings().byId(entityMetadata.getValue().id()); + if (type == null) { + return; + } AddPaintingPacket addPaintingPacket = new AddPaintingPacket(); addPaintingPacket.setUniqueEntityId(geyserId); addPaintingPacket.setRuntimeEntityId(geyserId); @@ -79,7 +87,7 @@ public class PaintingEntity extends Entity { private Vector3f fixOffset(PaintingType paintingName) { Vector3f position = super.position; position = position.add(0.5, 0.5, 0.5); - double widthOffset = paintingName.getWidth() > 1 ? 0.5 : 0; + double widthOffset = paintingName.getWidth() > 1 && paintingName.getWidth() != 3 ? 0.5 : 0; double heightOffset = paintingName.getHeight() > 1 && paintingName.getHeight() != 3 ? 0.5 : 0; return switch (direction) { diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java index 4573f0e7a..57fb901b4 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java @@ -36,33 +36,25 @@ import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.inventory.item.Enchantment; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.DyeItem; -import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractiveTag; import org.geysermc.geyser.util.ItemUtils; +import org.geysermc.mcprotocollib.protocol.data.game.Holder; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.WolfVariant; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import java.util.Collections; import java.util.Locale; -import java.util.Set; import java.util.UUID; public class WolfEntity extends TameableEntity { - /** - * A list of all foods a wolf can eat on Java Edition. - * Used to display interactive tag or particles if needed. - * TODO generate - */ - private static final Set WOLF_FOODS = Set.of(Items.PUFFERFISH, Items.TROPICAL_FISH, Items.CHICKEN, Items.COOKED_CHICKEN, - Items.PORKCHOP, Items.BEEF, Items.RABBIT, Items.COOKED_PORKCHOP, Items.COOKED_BEEF, Items.ROTTEN_FLESH, Items.MUTTON, Items.COOKED_MUTTON, - Items.COOKED_RABBIT); - private byte collarColor = 14; // Red - default private boolean isCurseOfBinding = false; @@ -112,12 +104,14 @@ public class WolfEntity extends TameableEntity { } // 1.20.5+ - public void setWolfVariant(IntEntityMetadata entityMetadata) { - WolfVariant wolfVariant = session.getRegistryCache().wolfVariants().byId(entityMetadata.getPrimitiveValue()); - if (wolfVariant == null) { - wolfVariant = WolfVariant.PALE; - } - dirtyMetadata.put(EntityDataTypes.VARIANT, wolfVariant.ordinal()); + public void setWolfVariant(ObjectEntityMetadata> entityMetadata) { + entityMetadata.getValue().ifId(id -> { + BuiltInWolfVariant wolfVariant = session.getRegistryCache().wolfVariants().byId(id); + if (wolfVariant == null) { + wolfVariant = BuiltInWolfVariant.PALE; + } + dirtyMetadata.put(EntityDataTypes.VARIANT, wolfVariant.ordinal()); + }); } @Override @@ -187,7 +181,7 @@ public class WolfEntity extends TameableEntity { } // Ordered by bedrock id - public enum WolfVariant { + public enum BuiltInWolfVariant { PALE, ASHEN, BLACK, @@ -198,16 +192,16 @@ public class WolfEntity extends TameableEntity { STRIPED, WOODS; - private static final WolfVariant[] VALUES = values(); + private static final BuiltInWolfVariant[] VALUES = values(); private final String javaIdentifier; - WolfVariant() { + BuiltInWolfVariant() { this.javaIdentifier = "minecraft:" + this.name().toLowerCase(Locale.ROOT); } - public static @Nullable WolfVariant getByJavaIdentifier(String javaIdentifier) { - for (WolfVariant wolfVariant : VALUES) { + public static @Nullable BuiltInWolfVariant getByJavaIdentifier(String javaIdentifier) { + for (BuiltInWolfVariant wolfVariant : VALUES) { if (wolfVariant.javaIdentifier.equals(javaIdentifier)) { return wolfVariant; } diff --git a/core/src/main/java/org/geysermc/geyser/item/Enchantment.java b/core/src/main/java/org/geysermc/geyser/item/Enchantment.java new file mode 100644 index 000000000..506467afd --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/item/Enchantment.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.item; + +import org.checkerframework.checker.nullness.qual.Nullable; +import org.cloudburstmc.nbt.NbtMap; +import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; + +/** + * @param anvilCost also as a rarity multiplier + */ +public record Enchantment(String supportedItemsTag, int maxLevel, int anvilCost, @Nullable String exclusiveSetTag) { + + // Implementation note: I have a feeling the tags can be a list of items, because in vanilla they're HolderSet classes. + // I'm not sure how that's wired over the network, so we'll put it off. + public static Enchantment read(RegistryEntry entry) { + NbtMap data = entry.getData(); + String supportedItems = data.getString("supported_items"); + int maxLevel = data.getInt("max_level"); + int anvilCost = data.getInt("anvil_cost"); + String exclusiveSet = data.getString("exclusive_set", null); + return new Enchantment(supportedItems, maxLevel, anvilCost, exclusiveSet); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index b53843882..cf0105622 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -146,8 +146,8 @@ public class BannerItem extends BlockItem { } else { List patternList = new ArrayList<>(patterns.size()); for (BannerPatternLayer patternLayer : patterns) { - patternLayer.getPattern().ifId(holder -> { - BannerPattern bannerPattern = session.getRegistryCache().bannerPatterns().byId(holder.id()); + patternLayer.getPattern().ifId(id -> { + BannerPattern bannerPattern = session.getRegistryCache().bannerPatterns().byId(id); if (bannerPattern != null) { NbtMap tag = NbtMap.builder() .putString("Pattern", bannerPattern.getBedrockIdentifier()) diff --git a/core/src/main/java/org/geysermc/geyser/level/PaintingType.java b/core/src/main/java/org/geysermc/geyser/level/PaintingType.java index 643fd735d..de35d97f1 100644 --- a/core/src/main/java/org/geysermc/geyser/level/PaintingType.java +++ b/core/src/main/java/org/geysermc/geyser/level/PaintingType.java @@ -29,6 +29,8 @@ import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; +import java.util.Locale; + @AllArgsConstructor(access = AccessLevel.PRIVATE) @Getter public enum PaintingType { @@ -61,7 +63,27 @@ public enum PaintingType { EARTH("Earth", 2, 2), WIND("Wind", 2, 2), WATER("Water", 2, 2), - FIRE("Fire", 2, 2); + FIRE("Fire", 2, 2), + MEDITATIVE("meditative", 1, 1), + PRAIRIE_RIDE("prairie_ride", 1, 2), + BAROQUE("baroque", 2, 2), + HUMBLE("humble", 2, 2), + UNPACKED("unpacked", 4, 4), + BACKYARD("backyard", 3, 4), + BOUQUET("bouquet", 3, 3), + CAVEBIRD("cavebird", 3, 3), + CHANGING("changing", 4, 2), + COTAN("cotan", 3, 3), + ENDBOSS("endboss", 3, 3), + FERN("fern", 3, 3), + FINDING("finding", 4, 2), + LOWMIST("lowmist", 4, 2), + ORB("orb", 4, 4), + OWLEMONS("owlemons", 3, 3), + PASSAGE("passage", 4, 2), + POND("pond", 3, 4), + SUNFLOWERS("sunflowers", 3, 3), + TIDES("tides", 3, 3); private static final PaintingType[] VALUES = values(); private final String bedrockName; @@ -70,12 +92,8 @@ public enum PaintingType { public static PaintingType getByName(String javaName) { for (PaintingType paintingName : VALUES) { - if (paintingName.name().equalsIgnoreCase(javaName)) return paintingName; + if (("minecraft:" + paintingName.name().toLowerCase(Locale.ROOT)).equals(javaName)) return paintingName; } - return KEBAB; - } - - public static PaintingType getByPaintingType(org.geysermc.mcprotocollib.protocol.data.game.entity.type.PaintingType paintingType) { - return getByName(paintingType.name()); + return null; } } diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion685_671.java b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion685_671.java index 3bb6b5faf..c96966927 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion685_671.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion685_671.java @@ -44,7 +44,7 @@ public class Conversion685_671 { private static final List MODIFIED_BLOCKS = Stream.of(NEW_BLOCKS, OMINOUS_BLOCKS).flatMap(List::stream).toList(); private static final List NEW_MUSIC_DISCS = List.of(Items.MUSIC_DISC_CREATOR, Items.MUSIC_DISC_CREATOR_MUSIC_BOX, Items.MUSIC_DISC_PRECIPICE); - static GeyserMappingItem remapItem(@SuppressWarnings("unused") Item item, GeyserMappingItem mapping) { + static GeyserMappingItem remapItem(Item item, GeyserMappingItem mapping) { String identifer = mapping.getBedrockIdentifier(); if (NEW_MUSIC_DISCS.contains(item)) { diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 17010e966..9543c7943 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -1302,22 +1302,28 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { } } + /** + * Convenience method to reduce amount of duplicate code. Sends ServerboundUseItemPacket. + */ + public void useItem(Hand hand) { + sendDownstreamGamePacket(new ServerboundUseItemPacket( + hand, worldCache.nextPredictionSequence(), playerEntity.getPitch(), playerEntity.getYaw())); + } + /** * Checks to see if a shield is in either hand to activate blocking. If so, it sets the Bedrock client to display * blocking and sends a packet to the Java server. */ private boolean attemptToBlock() { - ServerboundUseItemPacket useItemPacket; if (playerInventory.getItemInHand().asItem() == Items.SHIELD) { - useItemPacket = new ServerboundUseItemPacket(Hand.MAIN_HAND, worldCache.nextPredictionSequence()); + useItem(Hand.MAIN_HAND); } else if (playerInventory.getOffhand().asItem() == Items.SHIELD) { - useItemPacket = new ServerboundUseItemPacket(Hand.OFF_HAND, worldCache.nextPredictionSequence()); + useItem(Hand.OFF_HAND); } else { // No blocking return false; } - sendDownstreamGamePacket(useItemPacket); playerEntity.setFlag(EntityFlag.BLOCKING, true); // Metadata should be updated later return true; diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java index fa4503635..a9b14fdc0 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java @@ -38,7 +38,9 @@ import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.entity.type.living.animal.tameable.WolfEntity; import org.geysermc.geyser.inventory.item.BannerPattern; import org.geysermc.geyser.inventory.recipe.TrimRecipe; +import org.geysermc.geyser.item.Enchantment; import org.geysermc.geyser.level.JavaDimension; +import org.geysermc.geyser.level.PaintingType; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.registry.JavaRegistry; import org.geysermc.geyser.session.cache.registry.SimpleJavaRegistry; @@ -46,6 +48,7 @@ import org.geysermc.geyser.text.TextDecoration; import org.geysermc.geyser.translator.level.BiomeTranslator; import org.geysermc.mcprotocollib.protocol.MinecraftProtocol; import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; +import org.geysermc.mcprotocollib.protocol.data.game.chat.ChatType; import org.geysermc.mcprotocollib.protocol.packet.configuration.clientbound.ClientboundRegistryDataPacket; import java.util.ArrayList; @@ -72,11 +75,13 @@ public final class RegistryCache { static { register("chat_type", cache -> cache.chatTypes, ($, entry) -> TextDecoration.readChatType(entry)); register("dimension_type", cache -> cache.dimensions, ($, entry) -> JavaDimension.read(entry)); + register("enchantment", cache -> cache.enchantments, ($, entry) -> Enchantment.read(entry)); + register("painting_variant", cache -> cache.paintings, ($, entry) -> PaintingType.getByName(entry.getId())); register("trim_material", cache -> cache.trimMaterials, TrimRecipe::readTrimMaterial); register("trim_pattern", cache -> cache.trimPatterns, TrimRecipe::readTrimPattern); register("worldgen/biome", (cache, array) -> cache.biomeTranslations = array, BiomeTranslator::loadServerBiome); register("banner_pattern", cache -> cache.bannerPatterns, ($, entry) -> BannerPattern.getByJavaIdentifier(entry.getId())); - register("wolf_variant", cache -> cache.wolfVariants, ($, entry) -> WolfEntity.WolfVariant.getByJavaIdentifier(entry.getId())); + register("wolf_variant", cache -> cache.wolfVariants, ($, entry) -> WolfEntity.BuiltInWolfVariant.getByJavaIdentifier(entry.getId())); // Load from MCProtocolLib's classloader NbtMap tag = MinecraftProtocol.loadNetworkCodec(); @@ -104,16 +109,18 @@ public final class RegistryCache { * Java -> Bedrock biome network IDs. */ private int[] biomeTranslations; - private final JavaRegistry chatTypes = new SimpleJavaRegistry<>(); + private final JavaRegistry chatTypes = new SimpleJavaRegistry<>(); /** * All dimensions that the client could possibly connect to. */ private final JavaRegistry dimensions = new SimpleJavaRegistry<>(); + private final JavaRegistry enchantments = new SimpleJavaRegistry<>(); + private final JavaRegistry paintings = new SimpleJavaRegistry<>(); private final JavaRegistry trimMaterials = new SimpleJavaRegistry<>(); private final JavaRegistry trimPatterns = new SimpleJavaRegistry<>(); private final JavaRegistry bannerPatterns = new SimpleJavaRegistry<>(); - private final JavaRegistry wolfVariants = new SimpleJavaRegistry<>(); + private final JavaRegistry wolfVariants = new SimpleJavaRegistry<>(); public RegistryCache(GeyserSession session) { this.session = session; diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/registry/SimpleJavaRegistry.java b/core/src/main/java/org/geysermc/geyser/session/cache/registry/SimpleJavaRegistry.java index 9839a1568..7b79a40be 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/registry/SimpleJavaRegistry.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/registry/SimpleJavaRegistry.java @@ -57,4 +57,9 @@ public class SimpleJavaRegistry implements JavaRegistry { public List values() { return this.values; } + + @Override + public String toString() { + return this.values.toString(); + } } diff --git a/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java b/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java index b2222d3b9..cf2071173 100644 --- a/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java +++ b/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java @@ -30,21 +30,49 @@ import net.kyori.adventure.text.format.Style; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtType; import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; +import org.geysermc.mcprotocollib.protocol.data.game.chat.ChatType; +import org.geysermc.mcprotocollib.protocol.data.game.chat.ChatTypeDecoration; -import java.util.EnumSet; -import java.util.List; -import java.util.Locale; -import java.util.Set; +import java.util.*; -public final class TextDecoration { - private final String translationKey; - private final Style style; - private final Set parameters; +public record TextDecoration(String translationKey, List parameters, Style deserializedStyle) implements ChatTypeDecoration { - public TextDecoration(NbtMap tag) { - translationKey = tag.getString("translation_key"); + @Override + public NbtMap style() { + // Should not ever be called. + throw new UnsupportedOperationException(); + } - NbtMap styleTag = tag.getCompound("style"); + public static ChatType readChatType(RegistryEntry entry) { + // Note: The ID is NOT ALWAYS THE SAME! ViaVersion as of 1.19 adds two registry entries that do NOT match vanilla. + // (This note has been passed around through several classes and iterations. It stays as a warning + // to anyone that dares to try and hardcode registry IDs.) + NbtMap tag = entry.getData(); + NbtMap chat = tag.getCompound("chat", null); + if (chat != null) { + String translationKey = tag.getString("translation_key"); + + NbtMap styleTag = tag.getCompound("style"); + Style style = deserializeStyle(styleTag); + + List parameters = new ArrayList<>(); + List parametersNbt = tag.getList("parameters", NbtType.STRING); + for (String parameter : parametersNbt) { + parameters.add(ChatTypeDecoration.Parameter.valueOf(parameter.toUpperCase(Locale.ROOT))); + } + return new ChatType(new TextDecoration(translationKey, parameters, style), null); + } + return new ChatType(null, null); + } + + public static Style getStyle(ChatTypeDecoration decoration) { + if (decoration instanceof TextDecoration textDecoration) { + return textDecoration.deserializedStyle(); + } + return deserializeStyle(decoration.style()); + } + + private static Style deserializeStyle(NbtMap styleTag) { Style.Builder builder = Style.style(); if (!styleTag.isEmpty()) { String color = styleTag.getString("color", null); @@ -57,50 +85,6 @@ public final class TextDecoration { builder.decorate(net.kyori.adventure.text.format.TextDecoration.ITALIC); } } - style = builder.build(); - - this.parameters = EnumSet.noneOf(Parameter.class); - List parameters = tag.getList("parameters", NbtType.STRING); - for (String parameter : parameters) { - this.parameters.add(Parameter.valueOf(parameter.toUpperCase(Locale.ROOT))); - } - } - - public String translationKey() { - return translationKey; - } - - public Style style() { - return style; - } - - public Set parameters() { - return parameters; - } - - @Override - public String toString() { - return "TextDecoration{" + - "translationKey='" + translationKey + '\'' + - ", style=" + style + - ", parameters=" + parameters + - '}'; - } - - public static TextDecoration readChatType(RegistryEntry entry) { - // Note: The ID is NOT ALWAYS THE SAME! ViaVersion as of 1.19 adds two registry entries that do NOT match vanilla. - NbtMap tag = entry.getData(); - NbtMap chat = tag.getCompound("chat", null); - TextDecoration textDecoration = null; - if (chat != null) { - textDecoration = new TextDecoration(chat); - } - return textDecoration; - } - - public enum Parameter { - CONTENT, - SENDER, - TARGET + return builder.build(); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java index 878d326ac..534a89e23 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java @@ -394,8 +394,7 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator legacySlots = packet.getLegacySlots(); if (packet.getActions().size() == 1 && !legacySlots.isEmpty()) { @@ -639,8 +638,7 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator session.sendDownstreamGamePacket(new ServerboundUseItemPacket(Hand.MAIN_HAND, session.getWorldCache().nextPredictionSequence())), + session.scheduleInEventLoop(() -> session.useItem(Hand.MAIN_HAND), 50, TimeUnit.MILLISECONDS); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java index fe0868253..44ce51352 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java @@ -53,7 +53,7 @@ public class JavaRespawnTranslator extends PacketTranslator chatTypeHolder, Component targetName, Component sender) { TextPacket textPacket = new TextPacket(); textPacket.setPlatformChatId(""); textPacket.setSourceName(""); @@ -330,14 +333,15 @@ public class MessageTranslator { textPacket.setNeedsTranslation(false); - TextDecoration decoration = session.getRegistryCache().chatTypes().byId(chatType); - if (decoration != null) { + ChatType chatType = chatTypeHolder.getOrCompute(session.getRegistryCache().chatTypes()::byId); + if (chatType != null && chatType.chat() != null) { + var chat = chatType.chat(); // As of 1.19 - do this to apply all the styling for signed messages // Though, Bedrock cannot care about the signed stuff. TranslatableComponent.Builder withDecoration = Component.translatable() - .key(decoration.translationKey()) - .style(decoration.style()); - Set parameters = decoration.parameters(); + .key(chat.translationKey()) + .style(TextDecoration.getStyle(chat)); + List parameters = chat.parameters(); List args = new ArrayList<>(3); if (parameters.contains(TextDecoration.Parameter.TARGET)) { args.add(targetName); @@ -348,7 +352,7 @@ public class MessageTranslator { if (parameters.contains(TextDecoration.Parameter.CONTENT)) { args.add(message); } - withDecoration.args(args); + withDecoration.arguments(args); textPacket.setMessage(MessageTranslator.convertMessage(withDecoration.build(), session.locale())); } else { session.getGeyser().getLogger().debug("Likely illegal chat type detection found."); diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1995a6ada..f1b765e0f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,7 +13,7 @@ websocket = "1.5.1" protocol = "3.0.0.Beta2-20240520.153053-5" raknet = "1.0.0.CR3-20240416.144209-1" mcauthlib = "e5b0bcc" -mcprotocollib = "1.20.6-2-20240520.030045-8" +mcprotocollib = "1.21-SNAPSHOT" adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From 8ad10f8a9ea686043837d60057b70fdb83dc6321 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sun, 2 Jun 2024 23:36:44 -0400 Subject: [PATCH 207/272] Boats are leashable --- .../geyser/entity/type/BoatEntity.java | 23 +++++++++- .../geysermc/geyser/entity/type/Entity.java | 24 ++++++++++ .../geyser/entity/type/Leashable.java | 44 +++++++++++++++++++ .../entity/type/living/AmbientEntity.java | 2 +- .../entity/type/living/DolphinEntity.java | 2 +- .../geyser/entity/type/living/MobEntity.java | 27 +++++------- .../entity/type/living/SquidEntity.java | 2 +- .../entity/type/living/WaterEntity.java | 2 +- .../type/living/animal/AxolotlEntity.java | 2 +- .../type/living/animal/HoglinEntity.java | 2 +- .../type/living/animal/PandaEntity.java | 2 +- .../type/living/animal/TurtleEntity.java | 2 +- .../animal/tameable/TameableEntity.java | 2 +- .../living/animal/tameable/WolfEntity.java | 2 +- .../merchant/AbstractMerchantEntity.java | 2 +- .../type/living/monster/ZoglinEntity.java | 2 +- .../entity/JavaSetEntityLinkTranslator.java | 16 +++---- 17 files changed, 120 insertions(+), 38 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/entity/type/Leashable.java diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/BoatEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/BoatEntity.java index d9a64ccc6..47ae6777a 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/BoatEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/BoatEntity.java @@ -41,7 +41,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; -public class BoatEntity extends Entity implements Tickable { +public class BoatEntity extends Entity implements Leashable, Tickable { /** * Required when IS_BUOYANT is sent in order for boats to work in the water.
@@ -65,6 +65,8 @@ public class BoatEntity extends Entity implements Tickable { @Getter private int variant; + private long leashHolderBedrockId = -1; + // Looks too fast and too choppy with 0.1f, which is how I believe the Microsoftian client handles it private final float ROWING_SPEED = 0.1f; @@ -147,8 +149,18 @@ public class BoatEntity extends Entity implements Tickable { } } + @Override + public void setLeashHolderBedrockId(long bedrockId) { + this.leashHolderBedrockId = bedrockId; + dirtyMetadata.put(EntityDataTypes.LEASH_HOLDER, bedrockId); + } + @Override protected InteractiveTag testInteraction(Hand hand) { + InteractiveTag tag = super.testInteraction(hand); + if (tag != InteractiveTag.NONE) { + return tag; + } if (session.isSneaking()) { return InteractiveTag.NONE; } else if (passengers.size() < 2) { @@ -160,6 +172,10 @@ public class BoatEntity extends Entity implements Tickable { @Override public InteractionResult interact(Hand hand) { + InteractionResult result = super.interact(hand); + if (result != InteractionResult.PASS) { + return result; + } if (session.isSneaking()) { return InteractionResult.PASS; } else { @@ -191,6 +207,11 @@ public class BoatEntity extends Entity implements Tickable { } } + @Override + public long leashHolderBedrockId() { + return leashHolderBedrockId; + } + private void sendAnimationPacket(GeyserSession session, Entity rower, AnimatePacket.Action action, float rowTime) { AnimatePacket packet = new AnimatePacket(); packet.setRuntimeEntityId(rower.getGeyserId()); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java index 6267ee791..08e87dc03 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java @@ -40,6 +40,7 @@ import org.geysermc.geyser.api.entity.type.GeyserEntity; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.GeyserDirtyMetadata; import org.geysermc.geyser.entity.properties.GeyserEntityPropertyManager; +import org.geysermc.geyser.item.Items; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.util.EntityUtils; @@ -557,6 +558,17 @@ public class Entity implements GeyserEntity { * Should usually mirror {@link #interact(Hand)} without any side effects. */ protected InteractiveTag testInteraction(Hand hand) { + if (isAlive() && this instanceof Leashable leashable) { + if (leashable.leashHolderBedrockId() == session.getPlayerEntity().getGeyserId()) { + // Note this might be client side. Has yet to be an issue though, as of Java 1.21. + return InteractiveTag.REMOVE_LEASH; + } + if (session.getPlayerInventory().getItemInHand(hand).asItem() == Items.LEAD && leashable.canBeLeashed()) { + // We shall leash + return InteractiveTag.LEASH; + } + } + return InteractiveTag.NONE; } @@ -565,6 +577,18 @@ public class Entity implements GeyserEntity { * to ensure packet parity as well as functionality parity (such as sound effect responses). */ public InteractionResult interact(Hand hand) { + if (isAlive() && this instanceof Leashable leashable) { + if (leashable.leashHolderBedrockId() == session.getPlayerEntity().getGeyserId()) { + // Note this might also update client side (a theoretical Geyser/client desync and Java parity issue). + // Has yet to be an issue though, as of Java 1.21. + return InteractionResult.SUCCESS; + } + if (session.getPlayerInventory().getItemInHand(hand).asItem() == Items.LEAD && leashable.canBeLeashed()) { + // We shall leash + return InteractionResult.SUCCESS; + } + } + return InteractionResult.PASS; } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/Leashable.java b/core/src/main/java/org/geysermc/geyser/entity/type/Leashable.java new file mode 100644 index 000000000..64d95ba3c --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/entity/type/Leashable.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.entity.type; + +/** + * I can haz lead + * (The item, not the mineral) + */ +public interface Leashable { + void setLeashHolderBedrockId(long bedrockId); + + long leashHolderBedrockId(); + + default boolean canBeLeashed() { + return isNotLeashed(); + } + + default boolean isNotLeashed() { + return leashHolderBedrockId() == -1L; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/AmbientEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/AmbientEntity.java index 8f81125d0..f4b80edf1 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/AmbientEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/AmbientEntity.java @@ -38,7 +38,7 @@ public class AmbientEntity extends MobEntity { } @Override - protected boolean canBeLeashed() { + public boolean canBeLeashed() { return false; } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/DolphinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/DolphinEntity.java index 6182a27f4..a0ea79d67 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/DolphinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/DolphinEntity.java @@ -43,7 +43,7 @@ public class DolphinEntity extends WaterEntity { } @Override - protected boolean canBeLeashed() { + public boolean canBeLeashed() { return true; } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/MobEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/MobEntity.java index 95145ae60..9accf178f 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/MobEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/MobEntity.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.entity.type.living; -import lombok.Getter; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; +import org.geysermc.geyser.entity.type.Leashable; import org.geysermc.geyser.entity.type.LivingEntity; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; @@ -43,11 +43,10 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import java.util.UUID; -public class MobEntity extends LivingEntity { +public class MobEntity extends LivingEntity implements Leashable { /** * If another mob is holding this mob by a leash, this variable tracks their Bedrock entity ID. */ - @Getter private long leashHolderBedrockId; public MobEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { @@ -65,6 +64,7 @@ public class MobEntity extends LivingEntity { setFlag(EntityFlag.NO_AI, (xd & 0x01) == 0x01); } + @Override public void setLeashHolderBedrockId(long bedrockId) { this.leashHolderBedrockId = bedrockId; dirtyMetadata.put(EntityDataTypes.LEASH_HOLDER, bedrockId); @@ -79,10 +79,7 @@ public class MobEntity extends LivingEntity { return InteractiveTag.REMOVE_LEASH; } else { GeyserItemStack itemStack = session.getPlayerInventory().getItemInHand(hand); - if (itemStack.asItem() == Items.LEAD && canBeLeashed()) { - // We shall leash - return InteractiveTag.LEASH; - } else if (itemStack.asItem() == Items.NAME_TAG) { + if (itemStack.asItem() == Items.NAME_TAG) { InteractionResult result = checkInteractWithNameTag(itemStack); if (result.consumesAction()) { return InteractiveTag.NAME; @@ -99,9 +96,6 @@ public class MobEntity extends LivingEntity { if (!isAlive()) { // dead lol return InteractionResult.PASS; - } else if (leashHolderBedrockId == session.getPlayerEntity().getGeyserId()) { - // TODO looks like the client assumes it will go through and removes the attachment itself? - return InteractionResult.SUCCESS; } else { GeyserItemStack itemInHand = session.getPlayerInventory().getItemInHand(hand); InteractionResult result = checkPriorityInteractions(itemInHand); @@ -115,10 +109,7 @@ public class MobEntity extends LivingEntity { } private InteractionResult checkPriorityInteractions(GeyserItemStack itemInHand) { - if (itemInHand.asItem() == Items.LEAD && canBeLeashed()) { - // We shall leash - return InteractionResult.SUCCESS; - } else if (itemInHand.asItem() == Items.NAME_TAG) { + if (itemInHand.asItem() == Items.NAME_TAG) { InteractionResult result = checkInteractWithNameTag(itemInHand); if (result.consumesAction()) { return result; @@ -143,12 +134,14 @@ public class MobEntity extends LivingEntity { return InteractionResult.PASS; } - protected boolean canBeLeashed() { + @Override + public boolean canBeLeashed() { return isNotLeashed() && !isEnemy(); } - protected final boolean isNotLeashed() { - return leashHolderBedrockId == -1L; + @Override + public long leashHolderBedrockId() { + return leashHolderBedrockId; } /** diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/SquidEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/SquidEntity.java index 80a5af442..6285bd9a4 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/SquidEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/SquidEntity.java @@ -122,7 +122,7 @@ public class SquidEntity extends WaterEntity implements Tickable { } @Override - protected boolean canBeLeashed() { + public boolean canBeLeashed() { return isNotLeashed(); } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/WaterEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/WaterEntity.java index a847c4cd7..ae9d0d659 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/WaterEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/WaterEntity.java @@ -38,7 +38,7 @@ public class WaterEntity extends CreatureEntity { } @Override - protected boolean canBeLeashed() { + public boolean canBeLeashed() { return false; } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java index a87b1dd5e..a0ab56ead 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/AxolotlEntity.java @@ -72,7 +72,7 @@ public class AxolotlEntity extends AnimalEntity { } @Override - protected boolean canBeLeashed() { + public boolean canBeLeashed() { return true; } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java index 74c937417..cc23fc607 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java @@ -63,7 +63,7 @@ public class HoglinEntity extends AnimalEntity { } @Override - protected boolean canBeLeashed() { + public boolean canBeLeashed() { return isNotLeashed(); } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java index 79401f63f..aaa7c2d7e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/PandaEntity.java @@ -123,7 +123,7 @@ public class PandaEntity extends AnimalEntity { } @Override - protected boolean canBeLeashed() { + public boolean canBeLeashed() { return false; } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TurtleEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TurtleEntity.java index b3c1128e3..16901a844 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TurtleEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/TurtleEntity.java @@ -56,7 +56,7 @@ public class TurtleEntity extends AnimalEntity { } @Override - protected boolean canBeLeashed() { + public boolean canBeLeashed() { return false; } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/TameableEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/TameableEntity.java index e16823d37..ea347d193 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/TameableEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/TameableEntity.java @@ -84,7 +84,7 @@ public abstract class TameableEntity extends AnimalEntity { } @Override - protected boolean canBeLeashed() { + public boolean canBeLeashed() { return isNotLeashed(); } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java index 57fb901b4..c6b8051e7 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java @@ -127,7 +127,7 @@ public class WolfEntity extends TameableEntity { } @Override - protected boolean canBeLeashed() { + public boolean canBeLeashed() { return !getFlag(EntityFlag.ANGRY) && super.canBeLeashed(); } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/AbstractMerchantEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/AbstractMerchantEntity.java index 64e35e52e..2492aabd7 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/AbstractMerchantEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/AbstractMerchantEntity.java @@ -47,7 +47,7 @@ public class AbstractMerchantEntity extends AgeableEntity { } @Override - protected boolean canBeLeashed() { + public boolean canBeLeashed() { return false; } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java index 206746fb9..3d6e381c7 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/ZoglinEntity.java @@ -58,7 +58,7 @@ public class ZoglinEntity extends MonsterEntity { } @Override - protected boolean canBeLeashed() { + public boolean canBeLeashed() { return isNotLeashed(); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityLinkTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityLinkTranslator.java index d595e928f..15d47a285 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityLinkTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetEntityLinkTranslator.java @@ -25,15 +25,15 @@ package org.geysermc.geyser.translator.protocol.java.entity; -import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundSetEntityLinkPacket; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket; import org.geysermc.geyser.entity.type.Entity; -import org.geysermc.geyser.entity.type.living.MobEntity; +import org.geysermc.geyser.entity.type.Leashable; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundSetEntityLinkPacket; /** * Called when a leash is attached, removed or updated from an entity @@ -44,16 +44,16 @@ public class JavaSetEntityLinkTranslator extends PacketTranslator Date: Mon, 3 Jun 2024 21:00:08 +0200 Subject: [PATCH 208/272] Feature: Add API to show/hide GUI elements (#4705) * Add API to show/hide GUI elements * Bump version to 2.3.2 --------- Co-authored-by: Konicai <71294714+Konicai@users.noreply.github.com> --- .../geyser/api/bedrock/camera/CameraData.java | 34 +++++- .../geyser/api/bedrock/camera/GuiElement.java | 60 ++++++++++ .../geyser/impl/camera/GeyserCameraData.java | 109 +++++++++++++++++- .../geyser/session/GeyserSession.java | 7 +- gradle.properties | 2 +- 5 files changed, 203 insertions(+), 9 deletions(-) create mode 100644 api/src/main/java/org/geysermc/geyser/api/bedrock/camera/GuiElement.java diff --git a/api/src/main/java/org/geysermc/geyser/api/bedrock/camera/CameraData.java b/api/src/main/java/org/geysermc/geyser/api/bedrock/camera/CameraData.java index 2f715fa1e..f208879d1 100644 --- a/api/src/main/java/org/geysermc/geyser/api/bedrock/camera/CameraData.java +++ b/api/src/main/java/org/geysermc/geyser/api/bedrock/camera/CameraData.java @@ -145,4 +145,36 @@ public interface CameraData { * @return whether the camera is currently locked */ boolean isCameraLocked(); -} \ No newline at end of file + + /** + * Hides a {@link GuiElement} on the client's side. + * + * @param element the {@link GuiElement} to hide + */ + void hideElement(@NonNull GuiElement... element); + + /** + * Resets a {@link GuiElement} on the client's side. + * This makes the client decide on its own - e.g. based on client settings - + * whether to show or hide the gui element. + *

+ * If no elements are specified, this will reset all currently hidden elements + * + * @param element the {@link GuiElement} to reset + */ + void resetElement(@NonNull GuiElement @Nullable... element); + + /** + * Determines whether a {@link GuiElement} is currently hidden. + * + * @param element the {@link GuiElement} to check + */ + boolean isHudElementHidden(@NonNull GuiElement element); + + /** + * Returns the currently hidden {@link GuiElement}s. + * + * @return an unmodifiable view of all currently hidden {@link GuiElement}s + */ + @NonNull Set hiddenElements(); +} diff --git a/api/src/main/java/org/geysermc/geyser/api/bedrock/camera/GuiElement.java b/api/src/main/java/org/geysermc/geyser/api/bedrock/camera/GuiElement.java new file mode 100644 index 000000000..4d3653648 --- /dev/null +++ b/api/src/main/java/org/geysermc/geyser/api/bedrock/camera/GuiElement.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.api.bedrock.camera; + +/** + * Represent GUI elements on the players HUD display. + * These can be hidden using {@link CameraData#hideElement(GuiElement...)}, + * and one can reset their visibility using {@link CameraData#resetElement(GuiElement...)}. + */ +public class GuiElement { + public static final GuiElement PAPER_DOLL = new GuiElement(0); + public static final GuiElement ARMOR = new GuiElement(1); + public static final GuiElement TOOL_TIPS = new GuiElement(2); + public static final GuiElement TOUCH_CONTROLS = new GuiElement(3); + public static final GuiElement CROSSHAIR = new GuiElement(4); + public static final GuiElement HOTBAR = new GuiElement(5); + public static final GuiElement HEALTH = new GuiElement(6); + public static final GuiElement PROGRESS_BAR = new GuiElement(7); + public static final GuiElement FOOD_BAR = new GuiElement(8); + public static final GuiElement AIR_BUBBLES_BAR = new GuiElement(9); + public static final GuiElement VEHICLE_HEALTH = new GuiElement(10); + public static final GuiElement EFFECTS_BAR = new GuiElement(11); + public static final GuiElement ITEM_TEXT_POPUP = new GuiElement(12); + + private GuiElement(int id) { + this.id = id; + } + + private final int id; + + /** + * Internal use only; don't depend on these values being consistent. + */ + public int id() { + return this.id; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/impl/camera/GeyserCameraData.java b/core/src/main/java/org/geysermc/geyser/impl/camera/GeyserCameraData.java index 2a93c89e3..7582502b3 100644 --- a/core/src/main/java/org/geysermc/geyser/impl/camera/GeyserCameraData.java +++ b/core/src/main/java/org/geysermc/geyser/impl/camera/GeyserCameraData.java @@ -32,24 +32,50 @@ import org.cloudburstmc.math.vector.Vector2f; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.CameraShakeAction; import org.cloudburstmc.protocol.bedrock.data.CameraShakeType; +import org.cloudburstmc.protocol.bedrock.data.HudElement; +import org.cloudburstmc.protocol.bedrock.data.HudVisibility; import org.cloudburstmc.protocol.bedrock.data.camera.CameraEase; import org.cloudburstmc.protocol.bedrock.data.camera.CameraFadeInstruction; import org.cloudburstmc.protocol.bedrock.data.camera.CameraSetInstruction; import org.cloudburstmc.protocol.bedrock.packet.CameraInstructionPacket; import org.cloudburstmc.protocol.bedrock.packet.CameraShakePacket; import org.cloudburstmc.protocol.bedrock.packet.PlayerFogPacket; -import org.geysermc.geyser.api.bedrock.camera.*; +import org.cloudburstmc.protocol.bedrock.packet.SetHudPacket; +import org.geysermc.geyser.api.bedrock.camera.CameraData; +import org.geysermc.geyser.api.bedrock.camera.CameraEaseType; +import org.geysermc.geyser.api.bedrock.camera.CameraFade; +import org.geysermc.geyser.api.bedrock.camera.CameraPerspective; +import org.geysermc.geyser.api.bedrock.camera.CameraPosition; +import org.geysermc.geyser.api.bedrock.camera.CameraShake; +import org.geysermc.geyser.api.bedrock.camera.GuiElement; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; -import java.util.*; +import java.util.Collections; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; public class GeyserCameraData implements CameraData { + private static final HudElement[] HUD_ELEMENT_VALUES = HudElement.values(); + private static final Set ALL_HUD_ELEMENTS = Set.of(HUD_ELEMENT_VALUES); + + /** + * An array of elements to hide when the player is in spectator mode. + * Helps with tidying up the GUI; Java-style. + */ + private static final GuiElement[] SPECTATOR_HIDDEN_ELEMENTS = { + GuiElement.AIR_BUBBLES_BAR, + GuiElement.ARMOR, + GuiElement.HEALTH, + GuiElement.FOOD_BAR, + GuiElement.PROGRESS_BAR, + GuiElement.TOOL_TIPS + }; private final GeyserSession session; - @Getter - private CameraPerspective cameraPerspective; - /** * All fog effects that are currently applied to the client. */ @@ -57,6 +83,14 @@ public class GeyserCameraData implements CameraData { private final Set cameraLockOwners = new HashSet<>(); + /** + * All currently hidden HUD elements + */ + private final Set hiddenHudElements = new HashSet<>(); + + @Getter + private CameraPerspective cameraPerspective; + public GeyserCameraData(GeyserSession session) { this.session = session; } @@ -223,4 +257,67 @@ public class GeyserCameraData implements CameraData { public boolean isCameraLocked() { return !this.cameraLockOwners.isEmpty(); } -} \ No newline at end of file + + @Override + public void hideElement(GuiElement... elements) { + Objects.requireNonNull(elements); + SetHudPacket packet = new SetHudPacket(); + packet.setVisibility(HudVisibility.HIDE); + Set elementSet = packet.getElements(); + + for (GuiElement element : elements) { + this.hiddenHudElements.add(element); + elementSet.add(HUD_ELEMENT_VALUES[element.id()]); + } + + session.sendUpstreamPacket(packet); + } + + @Override + public void resetElement(GuiElement... elements) { + SetHudPacket packet = new SetHudPacket(); + packet.setVisibility(HudVisibility.RESET); + Set elementSet = packet.getElements(); + + if (elements != null && elements.length != 0) { + for (GuiElement element : elements) { + this.hiddenHudElements.remove(element); + elementSet.add(HUD_ELEMENT_VALUES[element.id()]); + } + } else { + this.hiddenHudElements.clear(); + elementSet.addAll(ALL_HUD_ELEMENTS); + } + + session.sendUpstreamPacket(packet); + } + + @Override + public boolean isHudElementHidden(@NonNull GuiElement element) { + Objects.requireNonNull(element); + return this.hiddenHudElements.contains(element); + } + + @Override + public @NonNull Set hiddenElements() { + return Collections.unmodifiableSet(hiddenHudElements); + } + + /** + * Deals with hiding hud elements while in spectator. + * + * @param currentlySpectator whether the player is currently in spectator mode + * @param newGameMode the new GameMode to switch to + */ + public void handleGameModeChange(boolean currentlySpectator, GameMode newGameMode) { + if (newGameMode == GameMode.SPECTATOR) { + if (!currentlySpectator) { + hideElement(SPECTATOR_HIDDEN_ELEMENTS); + } + } else { + if (currentlySpectator) { + resetElement(SPECTATOR_HIDDEN_ELEMENTS); + } + } + } +} diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 17010e966..fc000b95f 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -284,7 +284,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { */ private volatile boolean closed; - @Setter private GameMode gameMode = GameMode.SURVIVAL; /** @@ -1302,6 +1301,12 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { } } + public void setGameMode(GameMode newGamemode) { + boolean currentlySpectator = this.gameMode == GameMode.SPECTATOR; + this.gameMode = newGamemode; + this.cameraData.handleGameModeChange(currentlySpectator, newGamemode); + } + /** * Checks to see if a shield is in either hand to activate blocking. If so, it sets the Bedrock client to display * blocking and sends a packet to the Java server. diff --git a/gradle.properties b/gradle.properties index 40d8a36db..ea473906a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,5 +7,5 @@ org.gradle.vfs.watch=false group=org.geysermc id=geyser -version=2.3.1-SNAPSHOT +version=2.3.2-SNAPSHOT description=Allows for players from Minecraft: Bedrock Edition to join Minecraft: Java Edition servers. From 6c245a66e250bee57b98b5b3b07c08da44ea2afa Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 3 Jun 2024 23:43:35 -0400 Subject: [PATCH 209/272] Adapt for new enchantment changes --- .../living/animal/tameable/WolfEntity.java | 4 +- .../geyser/inventory/GeyserEnchantOption.java | 25 +- ...chantment.java => BedrockEnchantment.java} | 49 +--- .../updater/AnvilInventoryUpdater.java | 52 ++--- .../geyser/item/enchantment/Enchantment.java | 90 ++++++++ .../enchantment/EnchantmentComponent.java | 33 +++ .../geyser/item/type/EnchantedBookItem.java | 6 +- .../org/geysermc/geyser/item/type/Item.java | 36 ++- .../geysermc/geyser/registry/Registries.java | 25 +- .../loader/EnchantmentRegistryLoader.java | 86 ------- .../geyser/registry/type/EnchantmentData.java | 2 +- .../geyser/session/GeyserSession.java | 2 +- .../geyser/session/cache/RegistryCache.java | 2 +- .../geyser/session/cache/TagCache.java | 83 ++++--- .../geyser/session/cache/tags/BlockTag.java | 214 ++++++++++++++++-- .../session/cache/tags/EnchantmentTag.java | 89 ++++++++ .../geyser/session/cache/tags/ItemTag.java | 198 +++++++++++++--- .../EnchantingInventoryTranslator.java | 11 +- .../protocol/java/JavaCommandsTranslator.java | 23 +- .../org/geysermc/geyser/util/BlockUtils.java | 14 +- .../org/geysermc/geyser/util/ItemUtils.java | 45 +++- .../Enchantment.java => util/Ordered.java} | 22 +- core/src/main/resources/mappings | 2 +- 23 files changed, 775 insertions(+), 338 deletions(-) rename core/src/main/java/org/geysermc/geyser/inventory/item/{Enchantment.java => BedrockEnchantment.java} (69%) create mode 100644 core/src/main/java/org/geysermc/geyser/item/enchantment/Enchantment.java create mode 100644 core/src/main/java/org/geysermc/geyser/item/enchantment/EnchantmentComponent.java delete mode 100644 core/src/main/java/org/geysermc/geyser/registry/loader/EnchantmentRegistryLoader.java create mode 100644 core/src/main/java/org/geysermc/geyser/session/cache/tags/EnchantmentTag.java rename core/src/main/java/org/geysermc/geyser/{item/Enchantment.java => util/Ordered.java} (55%) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java index c6b8051e7..9c6c5e08d 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java @@ -33,8 +33,8 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.inventory.GeyserItemStack; -import org.geysermc.geyser.inventory.item.Enchantment; import org.geysermc.geyser.item.Items; +import org.geysermc.geyser.item.enchantment.EnchantmentComponent; import org.geysermc.geyser.item.type.DyeItem; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.ItemTag; @@ -123,7 +123,7 @@ public class WolfEntity extends TameableEntity { @Override public void setChestplate(ItemStack stack) { super.setChestplate(stack); - isCurseOfBinding = ItemUtils.getEnchantmentLevel(stack.getDataComponents(), Enchantment.JavaEnchantment.BINDING_CURSE) > 0; + isCurseOfBinding = ItemUtils.hasEffect(session, stack.getDataComponents(), EnchantmentComponent.PREVENT_ARMOR_CHANGE); // TODO test } @Override diff --git a/core/src/main/java/org/geysermc/geyser/inventory/GeyserEnchantOption.java b/core/src/main/java/org/geysermc/geyser/inventory/GeyserEnchantOption.java index 23365e392..de0bd7300 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/GeyserEnchantOption.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/GeyserEnchantOption.java @@ -25,12 +25,11 @@ package org.geysermc.geyser.inventory; +import lombok.Getter; import org.cloudburstmc.protocol.bedrock.data.inventory.EnchantData; import org.cloudburstmc.protocol.bedrock.data.inventory.EnchantOptionData; -import lombok.Getter; import org.geysermc.geyser.session.GeyserSession; -import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -44,13 +43,13 @@ public class GeyserEnchantOption { * is controlled by the server. * So, of course, we have to throw in some easter eggs. ;) */ - private static final List ENCHANT_NAMES = Arrays.asList("tougher armor", "lukeeey", "fall better", - "explode less", "camo toy", "breathe better", "rtm five one six", "armor stab", "water walk", "you are elsa", - "tim two zero three", "fast walk nether", "davchoo", "oof ouch owie", "enemy on fire", "spider sad", "aj ferguson", "redned", - "more items thx", "long sword reach", "fast tool", "give me block", "less breaky break", "cube craft", - "strong arrow", "fist arrow", "spicy arrow", "many many arrows", "geyser", "come here fish", "i like this", - "stabby stab", "supreme mortal", "avatar i guess", "more arrows", "fly finder seventeen", "in and out", - "xp heals tools", "dragon proxy waz here"); + private static final List ENCHANT_NAMES = List.of("tougher armor", "lukeeey", "fall better", + "explode less", "camo toy", "armor stab", "breathe better", "water walk", "rtm five one six", "oof ouch owie", + "enemy on fire", "spider sad", "aj ferguson", "redned", "more items thx", "fast tool", "give me block", + "less breaky break", "cube craft", "strong arrow", "fist arrow", "spicy arrow", "many many arrows", "geyser", + "come here fish", "you are elsa", "xp heals tools", "tim two zero three", "dragon proxy waz here", + "stabby stab", "supreme mortal", "i like this", "avatar i guess", "more arrows", "in and out", + "fly finder seventeen", "fast walk nether", "davchoo", "onechris", "death bringer thirteen", "kastle"); @Getter private final int javaIndex; @@ -62,7 +61,6 @@ public class GeyserEnchantOption { private boolean hasChanged; private int xpCost = 0; - private int javaEnchantIndex = -1; private int bedrockEnchantIndex = -1; private int enchantLevel = -1; @@ -74,7 +72,7 @@ public class GeyserEnchantOption { this.hasChanged = false; return new EnchantOptionData(xpCost, javaIndex + 16, EMPTY, enchantLevel == -1 ? EMPTY : Collections.singletonList(new EnchantData(bedrockEnchantIndex, enchantLevel)), EMPTY, - javaEnchantIndex == -1 ? "unknown" : ENCHANT_NAMES.get(javaEnchantIndex), enchantLevel == -1 ? 0 : session.getNextItemNetId()); + bedrockEnchantIndex == -1 ? "unknown" : ENCHANT_NAMES.get(bedrockEnchantIndex), enchantLevel == -1 ? 0 : session.getNextItemNetId()); } public boolean hasChanged() { @@ -88,10 +86,9 @@ public class GeyserEnchantOption { } } - public void setEnchantIndex(int javaEnchantIndex, int bedrockEnchantIndex) { - if (this.javaEnchantIndex != javaEnchantIndex) { + public void setEnchantIndex(int bedrockEnchantIndex) { + if (this.bedrockEnchantIndex != bedrockEnchantIndex) { hasChanged = true; - this.javaEnchantIndex = javaEnchantIndex; this.bedrockEnchantIndex = bedrockEnchantIndex; } } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/Enchantment.java b/core/src/main/java/org/geysermc/geyser/inventory/item/BedrockEnchantment.java similarity index 69% rename from core/src/main/java/org/geysermc/geyser/inventory/item/Enchantment.java rename to core/src/main/java/org/geysermc/geyser/inventory/item/BedrockEnchantment.java index 773de29b1..a9125421e 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/Enchantment.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/BedrockEnchantment.java @@ -25,13 +25,11 @@ package org.geysermc.geyser.inventory.item; -import lombok.Getter; import org.checkerframework.checker.nullness.qual.Nullable; import java.util.Locale; -@Getter -public enum Enchantment { +public enum BedrockEnchantment { PROTECTION, FIRE_PROTECTION, FEATHER_FALLING, @@ -69,18 +67,21 @@ public enum Enchantment { PIERCING, QUICK_CHARGE, SOUL_SPEED, - SWIFT_SNEAK; + SWIFT_SNEAK, + WIND_BURST, + DENSITY, + BREACH; - private static final Enchantment[] VALUES = values(); + private static final BedrockEnchantment[] VALUES = values(); private final String javaIdentifier; - Enchantment() { + BedrockEnchantment() { this.javaIdentifier = "minecraft:" + this.name().toLowerCase(Locale.ENGLISH); } - public static @Nullable Enchantment getByJavaIdentifier(String javaIdentifier) { - for (Enchantment enchantment : VALUES) { + public static @Nullable BedrockEnchantment getByJavaIdentifier(String javaIdentifier) { + for (BedrockEnchantment enchantment : VALUES) { if (enchantment.javaIdentifier.equals(javaIdentifier) || enchantment.name().toLowerCase(Locale.ENGLISH).equalsIgnoreCase(javaIdentifier)) { return enchantment; } @@ -88,7 +89,7 @@ public enum Enchantment { return null; } - public static @Nullable Enchantment getByBedrockId(int bedrockId) { + public static @Nullable BedrockEnchantment getByBedrockId(int bedrockId) { if (bedrockId >= 0 && bedrockId < VALUES.length) { return VALUES[bedrockId]; } @@ -141,35 +142,5 @@ public enum Enchantment { WIND_BURST, MENDING, VANISHING_CURSE; - - private static final JavaEnchantment[] VALUES = JavaEnchantment.values(); - - public static JavaEnchantment of(int index) { - return VALUES[index]; - } - - /** - * A list of all enchantment Java identifiers for use with command suggestions. - */ - public static final String[] ALL_JAVA_IDENTIFIERS; - - public static @Nullable JavaEnchantment getByJavaIdentifier(String javaIdentifier) { - if (!javaIdentifier.startsWith("minecraft:")) { - javaIdentifier = "minecraft:" + javaIdentifier; - } - for (int i = 0; i < ALL_JAVA_IDENTIFIERS.length; i++) { - if (ALL_JAVA_IDENTIFIERS[i].equalsIgnoreCase(javaIdentifier)) { - return VALUES[i]; - } - } - return null; - } - - static { - ALL_JAVA_IDENTIFIERS = new String[VALUES.length]; - for (int i = 0; i < ALL_JAVA_IDENTIFIERS.length; i++) { - ALL_JAVA_IDENTIFIERS[i] = "minecraft:" + VALUES[i].name().toLowerCase(Locale.ENGLISH); - } - } } } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java b/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java index d6a0d922b..c3ac73372 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java @@ -26,7 +26,6 @@ package org.geysermc.geyser.inventory.updater; import it.unimi.dsi.fastutil.objects.Object2IntMap; -import it.unimi.dsi.fastutil.objects.Object2IntMaps; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import net.kyori.adventure.text.Component; import org.cloudburstmc.nbt.NbtMap; @@ -38,10 +37,9 @@ import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.AnvilContainer; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.inventory.Inventory; -import org.geysermc.geyser.inventory.item.Enchantment.JavaEnchantment; +import org.geysermc.geyser.inventory.item.BedrockEnchantment; +import org.geysermc.geyser.item.enchantment.Enchantment; import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.registry.Registries; -import org.geysermc.geyser.registry.type.EnchantmentData; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.geyser.translator.text.MessageTranslator; @@ -307,22 +305,22 @@ public class AnvilInventoryUpdater extends InventoryUpdater { */ private int calcMergeEnchantmentCost(GeyserSession session, GeyserItemStack input, GeyserItemStack material, boolean bedrock) { boolean hasCompatible = false; - Object2IntMap combinedEnchantments = getEnchantments(input); + Object2IntMap combinedEnchantments = getEnchantments(session, input); int cost = 0; - for (Object2IntMap.Entry entry : getEnchantments(material).object2IntEntrySet()) { - JavaEnchantment enchantment = entry.getKey(); - EnchantmentData data = Registries.ENCHANTMENTS.get(enchantment); - if (data == null) { - GeyserImpl.getInstance().getLogger().debug("Java enchantment not in registry: " + enchantment); - continue; - } + for (Object2IntMap.Entry entry : getEnchantments(session, material).object2IntEntrySet()) { + Enchantment enchantment = entry.getKey(); - boolean canApply = isEnchantedBook(input) || data.validItems().contains(input.getJavaId()); - for (JavaEnchantment incompatible : data.incompatibleEnchantments()) { - if (combinedEnchantments.containsKey(incompatible)) { - canApply = false; - if (!bedrock) { - cost++; + boolean canApply = isEnchantedBook(input) || session.getTagCache().is(enchantment.supportedItems(), input); + var exclusiveSet = enchantment.exclusiveSet(); + if (exclusiveSet != null) { + int[] incompatibleEnchantments = session.getTagCache().get(exclusiveSet); + for (int i : incompatibleEnchantments) { + Enchantment incompatible = session.getRegistryCache().enchantments().byId(i); + if (combinedEnchantments.containsKey(incompatible)) { + canApply = false; + if (!bedrock) { + cost++; + } } } } @@ -334,12 +332,12 @@ public class AnvilInventoryUpdater extends InventoryUpdater { newLevel++; } newLevel = Math.max(currentLevel, newLevel); - if (newLevel > data.maxLevel()) { - newLevel = data.maxLevel(); + if (newLevel > enchantment.maxLevel()) { + newLevel = enchantment.maxLevel(); } combinedEnchantments.put(enchantment, newLevel); - int rarityMultiplier = data.rarityMultiplier(); + int rarityMultiplier = enchantment.anvilCost(); if (isEnchantedBook(material) && rarityMultiplier > 1) { rarityMultiplier /= 2; } @@ -347,11 +345,11 @@ public class AnvilInventoryUpdater extends InventoryUpdater { if (newLevel > currentLevel) { hasCompatible = true; } - if (enchantment == JavaEnchantment.IMPALING) { + if (enchantment.bedrockEnchantment() == BedrockEnchantment.IMPALING) { // Multiplier is halved on Bedrock for some reason rarityMultiplier /= 2; - } else if (enchantment == JavaEnchantment.SWEEPING_EDGE) { - // Doesn't exist on Bedrock + } else if (enchantment.bedrockEnchantment() == null) { + // Whatever this is, doesn't exist on Bedrock rarityMultiplier = 0; } cost += rarityMultiplier * (newLevel - currentLevel); @@ -368,7 +366,7 @@ public class AnvilInventoryUpdater extends InventoryUpdater { return cost; } - private Object2IntMap getEnchantments(GeyserItemStack itemStack) { + private Object2IntMap getEnchantments(GeyserSession session, GeyserItemStack itemStack) { ItemEnchantments enchantmentComponent; if (isEnchantedBook(itemStack)) { enchantmentComponent = itemStack.getComponent(DataComponentType.STORED_ENCHANTMENTS); @@ -376,9 +374,9 @@ public class AnvilInventoryUpdater extends InventoryUpdater { enchantmentComponent = itemStack.getComponent(DataComponentType.ENCHANTMENTS); } if (enchantmentComponent != null) { - Object2IntMap enchantments = new Object2IntOpenHashMap<>(); + Object2IntMap enchantments = new Object2IntOpenHashMap<>(); for (Map.Entry entry : enchantmentComponent.getEnchantments().entrySet()) { - JavaEnchantment enchantment = JavaEnchantment.of(entry.getKey()); + Enchantment enchantment = session.getRegistryCache().enchantments().byId(entry.getKey()); if (enchantment == null) { GeyserImpl.getInstance().getLogger().debug("Unknown Java enchantment in anvil: " + entry.getKey()); continue; diff --git a/core/src/main/java/org/geysermc/geyser/item/enchantment/Enchantment.java b/core/src/main/java/org/geysermc/geyser/item/enchantment/Enchantment.java new file mode 100644 index 000000000..41cc36894 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/item/enchantment/Enchantment.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.item.enchantment; + +import org.checkerframework.checker.nullness.qual.Nullable; +import org.cloudburstmc.nbt.NbtMap; +import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.inventory.item.BedrockEnchantment; +import org.geysermc.geyser.session.cache.tags.EnchantmentTag; +import org.geysermc.geyser.session.cache.tags.ItemTag; +import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; + +import java.util.*; + +/** + * @param description only populated if {@link #bedrockEnchantment()} is not null. + * @param anvilCost also as a rarity multiplier + */ +public record Enchantment(String identifier, + Set effects, + ItemTag supportedItems, + int maxLevel, + String description, + int anvilCost, + @Nullable EnchantmentTag exclusiveSet, + @Nullable BedrockEnchantment bedrockEnchantment) { + + // Implementation note: I have a feeling the tags can be a list of items, because in vanilla they're HolderSet classes. + // I'm not sure how that's wired over the network, so we'll put it off. + public static Enchantment read(RegistryEntry entry) { + NbtMap data = entry.getData(); + Set effects = readEnchantmentComponents(data.getCompound("effects")); + String supportedItems = data.getString("supported_items").substring(1); // Remove '#' at beginning that indicates tag + int maxLevel = data.getInt("max_level"); + int anvilCost = data.getInt("anvil_cost"); + String exclusiveSet = data.getString("exclusive_set", null); + EnchantmentTag exclusiveSetTag = exclusiveSet == null ? null : EnchantmentTag.ALL_ENCHANTMENT_TAGS.get(exclusiveSet.substring(1)); + BedrockEnchantment bedrockEnchantment = BedrockEnchantment.getByJavaIdentifier(entry.getId()); + String description = bedrockEnchantment == null ? readDescription(data) : null; + + return new Enchantment(entry.getId(), effects, ItemTag.ALL_ITEM_TAGS.get(supportedItems), maxLevel, + description, anvilCost, exclusiveSetTag, bedrockEnchantment); + } + + private static Set readEnchantmentComponents(NbtMap effects) { + if (effects.isEmpty()) { + return Collections.emptySet(); + } + Set components = new HashSet<>(); + for (Map.Entry entry : effects.entrySet()) { + switch (entry.getKey()) { + case "minecraft:prevent_armor_change" -> components.add(EnchantmentComponent.PREVENT_ARMOR_CHANGE); + } + } + return components; + } + + private static String readDescription(NbtMap tag) { + NbtMap description = tag.getCompound("description"); + String translate = description.getString("translate", null); + if (translate == null) { + GeyserImpl.getInstance().getLogger().debug("Don't know how to read description! " + tag); + return ""; + } + return translate; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/item/enchantment/EnchantmentComponent.java b/core/src/main/java/org/geysermc/geyser/item/enchantment/EnchantmentComponent.java new file mode 100644 index 000000000..66d110f98 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/item/enchantment/EnchantmentComponent.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.item.enchantment; + +public class EnchantmentComponent { + /** + * Singleton with no additional data + */ + public static final EnchantmentComponent PREVENT_ARMOR_CHANGE = new EnchantmentComponent(); +} diff --git a/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java index 98e98b4b8..540270555 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java @@ -31,7 +31,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.inventory.item.Enchantment; +import org.geysermc.geyser.inventory.item.BedrockEnchantment; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; @@ -78,11 +78,11 @@ public class EnchantedBookItem extends Item { for (NbtMap bedrockEnchantment : enchantmentTag) { short bedrockId = bedrockEnchantment.getShort("id"); - Enchantment enchantment = Enchantment.getByBedrockId(bedrockId); + BedrockEnchantment enchantment = BedrockEnchantment.getByBedrockId(bedrockId); if (enchantment != null) { int level = bedrockEnchantment.getShort("lvl", (short) 1); // TODO - javaEnchantments.put(Enchantment.JavaEnchantment.valueOf(enchantment.name()).ordinal(), level); + //javaEnchantments.put(BedrockEnchantment.JavaEnchantment.valueOf(enchantment.name()).ordinal(), level); } else { GeyserImpl.getInstance().getLogger().debug("Unknown bedrock enchantment: " + bedrockId); } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/Item.java b/core/src/main/java/org/geysermc/geyser/item/type/Item.java index 1ec410eaf..8c67d7d5f 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/Item.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/Item.java @@ -33,8 +33,9 @@ import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.GeyserItemStack; -import org.geysermc.geyser.inventory.item.Enchantment; +import org.geysermc.geyser.inventory.item.BedrockEnchantment; import org.geysermc.geyser.item.Items; +import org.geysermc.geyser.item.enchantment.Enchantment; import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; @@ -201,7 +202,7 @@ public class Item { // ShortTag bedrockId = tagValue.get("id"); // if (bedrockId == null) continue; // -// Enchantment enchantment = Enchantment.getByBedrockId(bedrockId.getValue()); +// BedrockEnchantment enchantment = BedrockEnchantment.getByBedrockId(bedrockId.getValue()); // if (enchantment != null) { // CompoundTag javaTag = new CompoundTag(""); // Map javaValue = javaTag.getValue(); @@ -226,33 +227,22 @@ public class Item { // } } - /** - * This is a map from Java-only enchantments to their translation keys so that we can - * map these enchantments to Bedrock clients, since they don't actually exist there. - */ - private static final Map ENCHANTMENT_TRANSLATION_KEYS = Map.of( - Enchantment.JavaEnchantment.SWEEPING_EDGE, "enchantment.minecraft.sweeping", - Enchantment.JavaEnchantment.DENSITY, "enchantment.minecraft.density", - Enchantment.JavaEnchantment.BREACH, "enchantment.minecraft.breach", - Enchantment.JavaEnchantment.WIND_BURST, "enchantment.minecraft.wind_burst"); - protected final @Nullable NbtMap remapEnchantment(GeyserSession session, int enchantId, int level, BedrockItemBuilder builder) { - // TODO verify - // TODO streamline Enchantment process - Enchantment.JavaEnchantment enchantment = Enchantment.JavaEnchantment.of(enchantId); - String translationKey = ENCHANTMENT_TRANSLATION_KEYS.get(enchantment); - if (translationKey != null) { - String enchantmentTranslation = MinecraftLocale.getLocaleString(translationKey, session.locale()); - addJavaOnlyEnchantment(session, builder, enchantmentTranslation, level); - return null; - } + Enchantment enchantment = session.getRegistryCache().enchantments().byId(enchantId); if (enchantment == null) { GeyserImpl.getInstance().getLogger().debug("Unknown Java enchantment while NBT item translating: " + enchantId); return null; } + BedrockEnchantment bedrockEnchantment = enchantment.bedrockEnchantment(); + if (bedrockEnchantment == null) { + String enchantmentTranslation = MinecraftLocale.getLocaleString(enchantment.description(), session.locale()); + addJavaOnlyEnchantment(session, builder, enchantmentTranslation, level); + return null; + } + return NbtMap.builder() - .putShort("id", (short) Enchantment.valueOf(enchantment.name()).ordinal()) + .putShort("id", (short) bedrockEnchantment.ordinal()) .putShort("lvl", (short) level) .build(); } @@ -260,7 +250,7 @@ public class Item { private void addJavaOnlyEnchantment(GeyserSession session, BedrockItemBuilder builder, String enchantmentName, int level) { String lvlTranslation = MinecraftLocale.getLocaleString("enchantment.level." + level, session.locale()); - builder.getOrCreateLore().add(ChatColor.RESET + ChatColor.GRAY + enchantmentName + " " + lvlTranslation); + builder.getOrCreateLore().add(0, ChatColor.RESET + ChatColor.GRAY + enchantmentName + " " + lvlTranslation); } /* Translation methods end */ diff --git a/core/src/main/java/org/geysermc/geyser/registry/Registries.java b/core/src/main/java/org/geysermc/geyser/registry/Registries.java index 54d013140..c6980efd1 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/Registries.java +++ b/core/src/main/java/org/geysermc/geyser/registry/Registries.java @@ -25,12 +25,6 @@ package org.geysermc.geyser.registry; -import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; -import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; -import org.geysermc.mcprotocollib.protocol.data.game.level.event.LevelEvent; -import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ParticleType; -import org.geysermc.mcprotocollib.protocol.data.game.recipe.RecipeType; -import org.geysermc.mcprotocollib.network.packet.Packet; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2IntMap; @@ -43,7 +37,6 @@ import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.pack.ResourcePack; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.inventory.item.Enchantment.JavaEnchantment; import org.geysermc.geyser.inventory.recipe.GeyserRecipe; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.registry.loader.*; @@ -51,7 +44,6 @@ import org.geysermc.geyser.registry.populator.ItemRegistryPopulator; import org.geysermc.geyser.registry.populator.PacketRegistryPopulator; import org.geysermc.geyser.registry.populator.RecipeRegistryPopulator; import org.geysermc.geyser.registry.provider.ProviderSupplier; -import org.geysermc.geyser.registry.type.EnchantmentData; import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.registry.type.ParticleMapping; import org.geysermc.geyser.registry.type.SoundMapping; @@ -59,6 +51,12 @@ import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator; import org.geysermc.geyser.translator.level.event.LevelEventTranslator; import org.geysermc.geyser.translator.sound.SoundInteractionTranslator; import org.geysermc.geyser.translator.sound.SoundTranslator; +import org.geysermc.mcprotocollib.network.packet.Packet; +import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.event.LevelEvent; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ParticleType; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.RecipeType; import java.util.*; @@ -102,11 +100,6 @@ public final class Registries { */ public static final VersionedRegistry>> CRAFTING_DATA = VersionedRegistry.create(RegistryLoaders.empty(Int2ObjectOpenHashMap::new)); - /** - * A registry holding data of all the known enchantments. - */ - public static final SimpleMappedRegistry ENCHANTMENTS; - /** * A map containing all entity types and their respective Geyser definitions */ @@ -127,7 +120,10 @@ public final class Registries { */ public static final PacketTranslatorRegistry JAVA_PACKET_TRANSLATORS = PacketTranslatorRegistry.create(); - public static final SimpleRegistry> JAVA_ITEMS = SimpleRegistry.create(RegistryLoaders.empty(ArrayList::new)); + /** + * A registry containing all Java items ordered by their network ID. + */ + public static final ListRegistry JAVA_ITEMS = ListRegistry.create(RegistryLoaders.empty(ArrayList::new)); public static final SimpleMappedRegistry JAVA_ITEM_IDENTIFIERS = SimpleMappedRegistry.create(RegistryLoaders.empty(Object2ObjectOpenHashMap::new)); @@ -190,7 +186,6 @@ public final class Registries { // Create registries that require other registries to load first POTION_MIXES = VersionedRegistry.create(PotionMixRegistryLoader::new); - ENCHANTMENTS = SimpleMappedRegistry.create("mappings/enchantments.json", EnchantmentRegistryLoader::new); // Remove unneeded client generation data from NbtMapBuilder NbtMapBuilder biomesNbt = NbtMap.builder(); diff --git a/core/src/main/java/org/geysermc/geyser/registry/loader/EnchantmentRegistryLoader.java b/core/src/main/java/org/geysermc/geyser/registry/loader/EnchantmentRegistryLoader.java deleted file mode 100644 index 8a0fb1f40..000000000 --- a/core/src/main/java/org/geysermc/geyser/registry/loader/EnchantmentRegistryLoader.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.geyser.registry.loader; - -import com.fasterxml.jackson.databind.JsonNode; -import it.unimi.dsi.fastutil.ints.IntOpenHashSet; -import it.unimi.dsi.fastutil.ints.IntSet; -import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.inventory.item.Enchantment.JavaEnchantment; -import org.geysermc.geyser.item.type.Item; -import org.geysermc.geyser.registry.Registries; -import org.geysermc.geyser.registry.type.EnchantmentData; - -import java.io.InputStream; -import java.util.EnumMap; -import java.util.EnumSet; -import java.util.Iterator; -import java.util.Map; - -public class EnchantmentRegistryLoader implements RegistryLoader> { - @Override - public Map load(String input) { - JsonNode enchantmentsNode; - try (InputStream enchantmentsStream = GeyserImpl.getInstance().getBootstrap().getResourceOrThrow(input)) { - enchantmentsNode = GeyserImpl.JSON_MAPPER.readTree(enchantmentsStream); - } catch (Exception e) { - throw new AssertionError("Unable to load enchantment data", e); - } - - Map enchantments = new EnumMap<>(JavaEnchantment.class); - Iterator> it = enchantmentsNode.fields(); - while (it.hasNext()) { - Map.Entry entry = it.next(); - JavaEnchantment key = JavaEnchantment.getByJavaIdentifier(entry.getKey()); - JsonNode node = entry.getValue(); - int rarityMultiplier = node.get("anvil_cost").asInt(); - int maxLevel = node.get("max_level").asInt(); - - EnumSet incompatibleEnchantments = EnumSet.noneOf(JavaEnchantment.class); - JsonNode incompatibleEnchantmentsNode = node.get("incompatible_enchantments"); - if (incompatibleEnchantmentsNode != null) { - for (JsonNode incompatibleNode : incompatibleEnchantmentsNode) { - incompatibleEnchantments.add(JavaEnchantment.getByJavaIdentifier(incompatibleNode.textValue())); - } - } - - IntSet validItems = new IntOpenHashSet(); - for (JsonNode itemNode : node.get("valid_items")) { - String javaIdentifier = itemNode.textValue(); - Item item = Registries.JAVA_ITEM_IDENTIFIERS.get(javaIdentifier); - if (item != null) { - validItems.add(item.javaId()); - } else { - throw new NullPointerException("No item entry exists for java identifier: " + javaIdentifier); - } - } - - EnchantmentData enchantmentData = new EnchantmentData(rarityMultiplier, maxLevel, incompatibleEnchantments, validItems); - enchantments.put(key, enchantmentData); - } - return enchantments; - } -} diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/EnchantmentData.java b/core/src/main/java/org/geysermc/geyser/registry/type/EnchantmentData.java index 970e128a4..d341cd9e3 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/type/EnchantmentData.java +++ b/core/src/main/java/org/geysermc/geyser/registry/type/EnchantmentData.java @@ -26,7 +26,7 @@ package org.geysermc.geyser.registry.type; import it.unimi.dsi.fastutil.ints.IntSet; -import org.geysermc.geyser.inventory.item.Enchantment.JavaEnchantment; +import org.geysermc.geyser.inventory.item.BedrockEnchantment.JavaEnchantment; import java.util.Set; diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 9543c7943..fc487b17e 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -1307,7 +1307,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { */ public void useItem(Hand hand) { sendDownstreamGamePacket(new ServerboundUseItemPacket( - hand, worldCache.nextPredictionSequence(), playerEntity.getPitch(), playerEntity.getYaw())); + hand, worldCache.nextPredictionSequence(), playerEntity.getYaw(), playerEntity.getPitch())); } /** diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java index a9b14fdc0..fe970ee2b 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java @@ -38,7 +38,7 @@ import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.entity.type.living.animal.tameable.WolfEntity; import org.geysermc.geyser.inventory.item.BannerPattern; import org.geysermc.geyser.inventory.recipe.TrimRecipe; -import org.geysermc.geyser.item.Enchantment; +import org.geysermc.geyser.item.enchantment.Enchantment; import org.geysermc.geyser.level.JavaDimension; import org.geysermc.geyser.level.PaintingType; import org.geysermc.geyser.session.GeyserSession; diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java index 95f5c1cc3..335e940f4 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java @@ -25,47 +25,40 @@ package org.geysermc.geyser.session.cache; -import it.unimi.dsi.fastutil.ints.IntList; +import it.unimi.dsi.fastutil.ints.IntArrays; +import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.BlockTag; +import org.geysermc.geyser.session.cache.tags.EnchantmentTag; import org.geysermc.geyser.session.cache.tags.ItemTag; +import org.geysermc.geyser.util.Ordered; import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundUpdateTagsPacket; import javax.annotation.ParametersAreNonnullByDefault; -import java.util.EnumMap; -import java.util.HashMap; +import java.util.Arrays; import java.util.Map; +import static org.geysermc.geyser.session.cache.tags.BlockTag.ALL_BLOCK_TAGS; +import static org.geysermc.geyser.session.cache.tags.EnchantmentTag.ALL_ENCHANTMENT_TAGS; +import static org.geysermc.geyser.session.cache.tags.ItemTag.ALL_ITEM_TAGS; + /** * Manages information sent from the {@link ClientboundUpdateTagsPacket}. If that packet is not sent, all lists here * will remain empty, matching Java Edition behavior. - * - * This system is designed for easy extensibility - just add an enum to {@link BlockTag} or {@link ItemTag}. */ @ParametersAreNonnullByDefault public final class TagCache { - // Put these here so the enums can load without a static map - public static final Map ALL_BLOCK_TAGS = new HashMap<>(); - public static final Map ALL_ITEM_TAGS = new HashMap<>(); - - private final Map blocks = new EnumMap<>(BlockTag.class); - private final Map items = new EnumMap<>(ItemTag.class); + private final int[][] blocks = new int[ALL_BLOCK_TAGS.size()][]; + private final int[][] items = new int[ALL_ITEM_TAGS.size()][]; + private final int[][] enchantments = new int[ALL_ENCHANTMENT_TAGS.size()][]; public void loadPacket(GeyserSession session, ClientboundUpdateTagsPacket packet) { Map blockTags = packet.getTags().get("minecraft:block"); - this.blocks.clear(); - ALL_BLOCK_TAGS.forEach((location, tag) -> { - int[] values = blockTags.get(location); - if (values != null) { - this.blocks.put(tag, IntList.of(values)); - } else { - session.getGeyser().getLogger().debug("Block tag not found from server: " + location); - } - }); + loadTags("Block", blockTags, ALL_BLOCK_TAGS, this.blocks); // Hack btw GeyserLogger logger = session.getGeyser().getLogger(); @@ -77,15 +70,7 @@ public final class TagCache { } Map itemTags = packet.getTags().get("minecraft:item"); - this.items.clear(); - ALL_ITEM_TAGS.forEach((location, tag) -> { - int[] values = itemTags.get(location); - if (values != null) { - this.items.put(tag, IntList.of(values)); - } else { - session.getGeyser().getLogger().debug("Item tag not found from server: " + location); - } - }); + loadTags("Item", itemTags, ALL_ITEM_TAGS, this.items); // Hack btw boolean emulatePost1_13Logic = itemTags.get("minecraft:signs").length > 1; @@ -93,17 +78,31 @@ public final class TagCache { if (logger.isDebug()) { logger.debug("Emulating post 1.13 villager logic for " + session.bedrockUsername() + "? " + emulatePost1_13Logic); } + + Map enchantmentTags = packet.getTags().get("minecraft:enchantment"); + loadTags("Enchantment", enchantmentTags, ALL_ENCHANTMENT_TAGS, this.enchantments); + } + + private void loadTags(String type, Map packetTags, Map allTags, int[][] localValues) { + Arrays.fill(localValues, IntArrays.EMPTY_ARRAY); + allTags.forEach((location, tag) -> { + int[] values = packetTags.get(location); + if (values != null) { + if (values.length != 0) { + localValues[tag.ordinal()] = values; + } + } else { + GeyserImpl.getInstance().getLogger().debug(type + " tag not found from server: " + location); + } + }); } /** * @return true if the block tag is present and contains this block mapping's Java ID. */ public boolean is(BlockTag tag, Block block) { - IntList values = this.blocks.get(tag); - if (values != null) { - return values.contains(block.javaId()); - } - return false; + int[] values = this.blocks[tag.ordinal()]; + return contains(values, block.javaId()); } /** @@ -117,9 +116,19 @@ public final class TagCache { * @return true if the item tag is present and contains this item's Java ID. */ public boolean is(ItemTag tag, Item item) { - IntList values = this.items.get(tag); - if (values != null) { - return values.contains(item.javaId()); + int[] values = this.items[tag.ordinal()]; + return contains(values, item.javaId()); + } + + public int[] get(EnchantmentTag tag) { + return this.enchantments[tag.ordinal()]; + } + + private static boolean contains(int[] array, int i) { + for (int item : array) { + if (item == i) { + return true; + } } return false; } diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/tags/BlockTag.java b/core/src/main/java/org/geysermc/geyser/session/cache/tags/BlockTag.java index 7017ad55c..32d708eca 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/tags/BlockTag.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/tags/BlockTag.java @@ -25,24 +25,212 @@ package org.geysermc.geyser.session.cache.tags; -import org.geysermc.geyser.session.cache.TagCache; +import org.geysermc.geyser.util.Ordered; -public enum BlockTag { - LEAVES("leaves"), - WOOL("wool"), - AXE_EFFECTIVE("mineable/axe"), - HOE_EFFECTIVE("mineable/hoe"), - PICKAXE_EFFECTIVE("mineable/pickaxe"), - SHOVEL_EFFECTIVE("mineable/shovel"), - NEEDS_STONE_TOOL("needs_stone_tool"), - NEEDS_IRON_TOOL("needs_iron_tool"), - NEEDS_DIAMOND_TOOL("needs_diamond_tool"); +import java.util.HashMap; +import java.util.Map; + +@SuppressWarnings("unused") +public final class BlockTag implements Ordered { + public static final Map ALL_BLOCK_TAGS = new HashMap<>(); + + public static final BlockTag WOOL = new BlockTag("wool"); + public static final BlockTag PLANKS = new BlockTag("planks"); + public static final BlockTag STONE_BRICKS = new BlockTag("stone_bricks"); + public static final BlockTag WOODEN_BUTTONS = new BlockTag("wooden_buttons"); + public static final BlockTag STONE_BUTTONS = new BlockTag("stone_buttons"); + public static final BlockTag BUTTONS = new BlockTag("buttons"); + public static final BlockTag WOOL_CARPETS = new BlockTag("wool_carpets"); + public static final BlockTag WOODEN_DOORS = new BlockTag("wooden_doors"); + public static final BlockTag WOODEN_STAIRS = new BlockTag("wooden_stairs"); + public static final BlockTag WOODEN_SLABS = new BlockTag("wooden_slabs"); + public static final BlockTag WOODEN_FENCES = new BlockTag("wooden_fences"); + public static final BlockTag PRESSURE_PLATES = new BlockTag("pressure_plates"); + public static final BlockTag WOODEN_PRESSURE_PLATES = new BlockTag("wooden_pressure_plates"); + public static final BlockTag STONE_PRESSURE_PLATES = new BlockTag("stone_pressure_plates"); + public static final BlockTag WOODEN_TRAPDOORS = new BlockTag("wooden_trapdoors"); + public static final BlockTag DOORS = new BlockTag("doors"); + public static final BlockTag SAPLINGS = new BlockTag("saplings"); + public static final BlockTag LOGS_THAT_BURN = new BlockTag("logs_that_burn"); + public static final BlockTag OVERWORLD_NATURAL_LOGS = new BlockTag("overworld_natural_logs"); + public static final BlockTag LOGS = new BlockTag("logs"); + public static final BlockTag DARK_OAK_LOGS = new BlockTag("dark_oak_logs"); + public static final BlockTag OAK_LOGS = new BlockTag("oak_logs"); + public static final BlockTag BIRCH_LOGS = new BlockTag("birch_logs"); + public static final BlockTag ACACIA_LOGS = new BlockTag("acacia_logs"); + public static final BlockTag CHERRY_LOGS = new BlockTag("cherry_logs"); + public static final BlockTag JUNGLE_LOGS = new BlockTag("jungle_logs"); + public static final BlockTag SPRUCE_LOGS = new BlockTag("spruce_logs"); + public static final BlockTag MANGROVE_LOGS = new BlockTag("mangrove_logs"); + public static final BlockTag CRIMSON_STEMS = new BlockTag("crimson_stems"); + public static final BlockTag WARPED_STEMS = new BlockTag("warped_stems"); + public static final BlockTag BAMBOO_BLOCKS = new BlockTag("bamboo_blocks"); + public static final BlockTag WART_BLOCKS = new BlockTag("wart_blocks"); + public static final BlockTag BANNERS = new BlockTag("banners"); + public static final BlockTag SAND = new BlockTag("sand"); + public static final BlockTag SMELTS_TO_GLASS = new BlockTag("smelts_to_glass"); + public static final BlockTag STAIRS = new BlockTag("stairs"); + public static final BlockTag SLABS = new BlockTag("slabs"); + public static final BlockTag WALLS = new BlockTag("walls"); + public static final BlockTag ANVIL = new BlockTag("anvil"); + public static final BlockTag RAILS = new BlockTag("rails"); + public static final BlockTag LEAVES = new BlockTag("leaves"); + public static final BlockTag TRAPDOORS = new BlockTag("trapdoors"); + public static final BlockTag SMALL_FLOWERS = new BlockTag("small_flowers"); + public static final BlockTag BEDS = new BlockTag("beds"); + public static final BlockTag FENCES = new BlockTag("fences"); + public static final BlockTag TALL_FLOWERS = new BlockTag("tall_flowers"); + public static final BlockTag FLOWERS = new BlockTag("flowers"); + public static final BlockTag PIGLIN_REPELLENTS = new BlockTag("piglin_repellents"); + public static final BlockTag GOLD_ORES = new BlockTag("gold_ores"); + public static final BlockTag IRON_ORES = new BlockTag("iron_ores"); + public static final BlockTag DIAMOND_ORES = new BlockTag("diamond_ores"); + public static final BlockTag REDSTONE_ORES = new BlockTag("redstone_ores"); + public static final BlockTag LAPIS_ORES = new BlockTag("lapis_ores"); + public static final BlockTag COAL_ORES = new BlockTag("coal_ores"); + public static final BlockTag EMERALD_ORES = new BlockTag("emerald_ores"); + public static final BlockTag COPPER_ORES = new BlockTag("copper_ores"); + public static final BlockTag CANDLES = new BlockTag("candles"); + public static final BlockTag DIRT = new BlockTag("dirt"); + public static final BlockTag TERRACOTTA = new BlockTag("terracotta"); + public static final BlockTag BADLANDS_TERRACOTTA = new BlockTag("badlands_terracotta"); + public static final BlockTag CONCRETE_POWDER = new BlockTag("concrete_powder"); + public static final BlockTag COMPLETES_FIND_TREE_TUTORIAL = new BlockTag("completes_find_tree_tutorial"); + public static final BlockTag FLOWER_POTS = new BlockTag("flower_pots"); + public static final BlockTag ENDERMAN_HOLDABLE = new BlockTag("enderman_holdable"); + public static final BlockTag ICE = new BlockTag("ice"); + public static final BlockTag VALID_SPAWN = new BlockTag("valid_spawn"); + public static final BlockTag IMPERMEABLE = new BlockTag("impermeable"); + public static final BlockTag UNDERWATER_BONEMEALS = new BlockTag("underwater_bonemeals"); + public static final BlockTag CORAL_BLOCKS = new BlockTag("coral_blocks"); + public static final BlockTag WALL_CORALS = new BlockTag("wall_corals"); + public static final BlockTag CORAL_PLANTS = new BlockTag("coral_plants"); + public static final BlockTag CORALS = new BlockTag("corals"); + public static final BlockTag BAMBOO_PLANTABLE_ON = new BlockTag("bamboo_plantable_on"); + public static final BlockTag STANDING_SIGNS = new BlockTag("standing_signs"); + public static final BlockTag WALL_SIGNS = new BlockTag("wall_signs"); + public static final BlockTag SIGNS = new BlockTag("signs"); + public static final BlockTag CEILING_HANGING_SIGNS = new BlockTag("ceiling_hanging_signs"); + public static final BlockTag WALL_HANGING_SIGNS = new BlockTag("wall_hanging_signs"); + public static final BlockTag ALL_HANGING_SIGNS = new BlockTag("all_hanging_signs"); + public static final BlockTag ALL_SIGNS = new BlockTag("all_signs"); + public static final BlockTag DRAGON_IMMUNE = new BlockTag("dragon_immune"); + public static final BlockTag DRAGON_TRANSPARENT = new BlockTag("dragon_transparent"); + public static final BlockTag WITHER_IMMUNE = new BlockTag("wither_immune"); + public static final BlockTag WITHER_SUMMON_BASE_BLOCKS = new BlockTag("wither_summon_base_blocks"); + public static final BlockTag BEEHIVES = new BlockTag("beehives"); + public static final BlockTag CROPS = new BlockTag("crops"); + public static final BlockTag BEE_GROWABLES = new BlockTag("bee_growables"); + public static final BlockTag PORTALS = new BlockTag("portals"); + public static final BlockTag FIRE = new BlockTag("fire"); + public static final BlockTag NYLIUM = new BlockTag("nylium"); + public static final BlockTag BEACON_BASE_BLOCKS = new BlockTag("beacon_base_blocks"); + public static final BlockTag SOUL_SPEED_BLOCKS = new BlockTag("soul_speed_blocks"); + public static final BlockTag WALL_POST_OVERRIDE = new BlockTag("wall_post_override"); + public static final BlockTag CLIMBABLE = new BlockTag("climbable"); + public static final BlockTag FALL_DAMAGE_RESETTING = new BlockTag("fall_damage_resetting"); + public static final BlockTag SHULKER_BOXES = new BlockTag("shulker_boxes"); + public static final BlockTag HOGLIN_REPELLENTS = new BlockTag("hoglin_repellents"); + public static final BlockTag SOUL_FIRE_BASE_BLOCKS = new BlockTag("soul_fire_base_blocks"); + public static final BlockTag STRIDER_WARM_BLOCKS = new BlockTag("strider_warm_blocks"); + public static final BlockTag CAMPFIRES = new BlockTag("campfires"); + public static final BlockTag GUARDED_BY_PIGLINS = new BlockTag("guarded_by_piglins"); + public static final BlockTag PREVENT_MOB_SPAWNING_INSIDE = new BlockTag("prevent_mob_spawning_inside"); + public static final BlockTag FENCE_GATES = new BlockTag("fence_gates"); + public static final BlockTag UNSTABLE_BOTTOM_CENTER = new BlockTag("unstable_bottom_center"); + public static final BlockTag MUSHROOM_GROW_BLOCK = new BlockTag("mushroom_grow_block"); + public static final BlockTag INFINIBURN_OVERWORLD = new BlockTag("infiniburn_overworld"); + public static final BlockTag INFINIBURN_NETHER = new BlockTag("infiniburn_nether"); + public static final BlockTag INFINIBURN_END = new BlockTag("infiniburn_end"); + public static final BlockTag BASE_STONE_OVERWORLD = new BlockTag("base_stone_overworld"); + public static final BlockTag STONE_ORE_REPLACEABLES = new BlockTag("stone_ore_replaceables"); + public static final BlockTag DEEPSLATE_ORE_REPLACEABLES = new BlockTag("deepslate_ore_replaceables"); + public static final BlockTag BASE_STONE_NETHER = new BlockTag("base_stone_nether"); + public static final BlockTag OVERWORLD_CARVER_REPLACEABLES = new BlockTag("overworld_carver_replaceables"); + public static final BlockTag NETHER_CARVER_REPLACEABLES = new BlockTag("nether_carver_replaceables"); + public static final BlockTag CANDLE_CAKES = new BlockTag("candle_cakes"); + public static final BlockTag CAULDRONS = new BlockTag("cauldrons"); + public static final BlockTag CRYSTAL_SOUND_BLOCKS = new BlockTag("crystal_sound_blocks"); + public static final BlockTag INSIDE_STEP_SOUND_BLOCKS = new BlockTag("inside_step_sound_blocks"); + public static final BlockTag COMBINATION_STEP_SOUND_BLOCKS = new BlockTag("combination_step_sound_blocks"); + public static final BlockTag CAMEL_SAND_STEP_SOUND_BLOCKS = new BlockTag("camel_sand_step_sound_blocks"); + public static final BlockTag OCCLUDES_VIBRATION_SIGNALS = new BlockTag("occludes_vibration_signals"); + public static final BlockTag DAMPENS_VIBRATIONS = new BlockTag("dampens_vibrations"); + public static final BlockTag DRIPSTONE_REPLACEABLE_BLOCKS = new BlockTag("dripstone_replaceable_blocks"); + public static final BlockTag CAVE_VINES = new BlockTag("cave_vines"); + public static final BlockTag MOSS_REPLACEABLE = new BlockTag("moss_replaceable"); + public static final BlockTag LUSH_GROUND_REPLACEABLE = new BlockTag("lush_ground_replaceable"); + public static final BlockTag AZALEA_ROOT_REPLACEABLE = new BlockTag("azalea_root_replaceable"); + public static final BlockTag SMALL_DRIPLEAF_PLACEABLE = new BlockTag("small_dripleaf_placeable"); + public static final BlockTag BIG_DRIPLEAF_PLACEABLE = new BlockTag("big_dripleaf_placeable"); + public static final BlockTag SNOW = new BlockTag("snow"); + public static final BlockTag MINEABLE_AXE = new BlockTag("mineable/axe"); + public static final BlockTag MINEABLE_HOE = new BlockTag("mineable/hoe"); + public static final BlockTag MINEABLE_PICKAXE = new BlockTag("mineable/pickaxe"); + public static final BlockTag MINEABLE_SHOVEL = new BlockTag("mineable/shovel"); + public static final BlockTag SWORD_EFFICIENT = new BlockTag("sword_efficient"); + public static final BlockTag NEEDS_DIAMOND_TOOL = new BlockTag("needs_diamond_tool"); + public static final BlockTag NEEDS_IRON_TOOL = new BlockTag("needs_iron_tool"); + public static final BlockTag NEEDS_STONE_TOOL = new BlockTag("needs_stone_tool"); + public static final BlockTag INCORRECT_FOR_NETHERITE_TOOL = new BlockTag("incorrect_for_netherite_tool"); + public static final BlockTag INCORRECT_FOR_DIAMOND_TOOL = new BlockTag("incorrect_for_diamond_tool"); + public static final BlockTag INCORRECT_FOR_IRON_TOOL = new BlockTag("incorrect_for_iron_tool"); + public static final BlockTag INCORRECT_FOR_STONE_TOOL = new BlockTag("incorrect_for_stone_tool"); + public static final BlockTag INCORRECT_FOR_GOLD_TOOL = new BlockTag("incorrect_for_gold_tool"); + public static final BlockTag INCORRECT_FOR_WOODEN_TOOL = new BlockTag("incorrect_for_wooden_tool"); + public static final BlockTag FEATURES_CANNOT_REPLACE = new BlockTag("features_cannot_replace"); + public static final BlockTag LAVA_POOL_STONE_CANNOT_REPLACE = new BlockTag("lava_pool_stone_cannot_replace"); + public static final BlockTag GEODE_INVALID_BLOCKS = new BlockTag("geode_invalid_blocks"); + public static final BlockTag FROG_PREFER_JUMP_TO = new BlockTag("frog_prefer_jump_to"); + public static final BlockTag SCULK_REPLACEABLE = new BlockTag("sculk_replaceable"); + public static final BlockTag SCULK_REPLACEABLE_WORLD_GEN = new BlockTag("sculk_replaceable_world_gen"); + public static final BlockTag ANCIENT_CITY_REPLACEABLE = new BlockTag("ancient_city_replaceable"); + public static final BlockTag VIBRATION_RESONATORS = new BlockTag("vibration_resonators"); + public static final BlockTag ANIMALS_SPAWNABLE_ON = new BlockTag("animals_spawnable_on"); + public static final BlockTag ARMADILLO_SPAWNABLE_ON = new BlockTag("armadillo_spawnable_on"); + public static final BlockTag AXOLOTLS_SPAWNABLE_ON = new BlockTag("axolotls_spawnable_on"); + public static final BlockTag GOATS_SPAWNABLE_ON = new BlockTag("goats_spawnable_on"); + public static final BlockTag MOOSHROOMS_SPAWNABLE_ON = new BlockTag("mooshrooms_spawnable_on"); + public static final BlockTag PARROTS_SPAWNABLE_ON = new BlockTag("parrots_spawnable_on"); + public static final BlockTag POLAR_BEARS_SPAWNABLE_ON_ALTERNATE = new BlockTag("polar_bears_spawnable_on_alternate"); + public static final BlockTag RABBITS_SPAWNABLE_ON = new BlockTag("rabbits_spawnable_on"); + public static final BlockTag FOXES_SPAWNABLE_ON = new BlockTag("foxes_spawnable_on"); + public static final BlockTag WOLVES_SPAWNABLE_ON = new BlockTag("wolves_spawnable_on"); + public static final BlockTag FROGS_SPAWNABLE_ON = new BlockTag("frogs_spawnable_on"); + public static final BlockTag AZALEA_GROWS_ON = new BlockTag("azalea_grows_on"); + public static final BlockTag CONVERTABLE_TO_MUD = new BlockTag("convertable_to_mud"); + public static final BlockTag MANGROVE_LOGS_CAN_GROW_THROUGH = new BlockTag("mangrove_logs_can_grow_through"); + public static final BlockTag MANGROVE_ROOTS_CAN_GROW_THROUGH = new BlockTag("mangrove_roots_can_grow_through"); + public static final BlockTag DEAD_BUSH_MAY_PLACE_ON = new BlockTag("dead_bush_may_place_on"); + public static final BlockTag SNAPS_GOAT_HORN = new BlockTag("snaps_goat_horn"); + public static final BlockTag REPLACEABLE_BY_TREES = new BlockTag("replaceable_by_trees"); + public static final BlockTag SNOW_LAYER_CANNOT_SURVIVE_ON = new BlockTag("snow_layer_cannot_survive_on"); + public static final BlockTag SNOW_LAYER_CAN_SURVIVE_ON = new BlockTag("snow_layer_can_survive_on"); + public static final BlockTag INVALID_SPAWN_INSIDE = new BlockTag("invalid_spawn_inside"); + public static final BlockTag SNIFFER_DIGGABLE_BLOCK = new BlockTag("sniffer_diggable_block"); + public static final BlockTag SNIFFER_EGG_HATCH_BOOST = new BlockTag("sniffer_egg_hatch_boost"); + public static final BlockTag TRAIL_RUINS_REPLACEABLE = new BlockTag("trail_ruins_replaceable"); + public static final BlockTag REPLACEABLE = new BlockTag("replaceable"); + public static final BlockTag ENCHANTMENT_POWER_PROVIDER = new BlockTag("enchantment_power_provider"); + public static final BlockTag ENCHANTMENT_POWER_TRANSMITTER = new BlockTag("enchantment_power_transmitter"); + public static final BlockTag MAINTAINS_FARMLAND = new BlockTag("maintains_farmland"); + public static final BlockTag BLOCKS_WIND_CHARGE_EXPLOSIONS = new BlockTag("blocks_wind_charge_explosions"); + public static final BlockTag DOES_NOT_BLOCK_HOPPERS = new BlockTag("does_not_block_hoppers"); + public static final BlockTag AIR = new BlockTag("air"); + + private final int id; - BlockTag(String identifier) { + private BlockTag(String identifier) { + this.id = ALL_BLOCK_TAGS.size(); register(identifier, this); } + @Override + public int ordinal() { + return id; + } + private static void register(String name, BlockTag tag) { - TagCache.ALL_BLOCK_TAGS.put("minecraft:" + name, tag); + ALL_BLOCK_TAGS.put(("minecraft:" + name).intern(), tag); } } diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/tags/EnchantmentTag.java b/core/src/main/java/org/geysermc/geyser/session/cache/tags/EnchantmentTag.java new file mode 100644 index 000000000..3c5446adc --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/session/cache/tags/EnchantmentTag.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.session.cache.tags; + +import org.geysermc.geyser.util.Ordered; + +import java.util.HashMap; +import java.util.Map; + +@SuppressWarnings("unused") +public final class EnchantmentTag implements Ordered { + public static final Map ALL_ENCHANTMENT_TAGS = new HashMap<>(); + + public static final EnchantmentTag TOOLTIP_ORDER = new EnchantmentTag("tooltip_order"); + public static final EnchantmentTag EXCLUSIVE_SET_ARMOR = new EnchantmentTag("exclusive_set/armor"); + public static final EnchantmentTag EXCLUSIVE_SET_BOOTS = new EnchantmentTag("exclusive_set/boots"); + public static final EnchantmentTag EXCLUSIVE_SET_BOW = new EnchantmentTag("exclusive_set/bow"); + public static final EnchantmentTag EXCLUSIVE_SET_CROSSBOW = new EnchantmentTag("exclusive_set/crossbow"); + public static final EnchantmentTag EXCLUSIVE_SET_DAMAGE = new EnchantmentTag("exclusive_set/damage"); + public static final EnchantmentTag EXCLUSIVE_SET_MINING = new EnchantmentTag("exclusive_set/mining"); + public static final EnchantmentTag EXCLUSIVE_SET_RIPTIDE = new EnchantmentTag("exclusive_set/riptide"); + public static final EnchantmentTag TRADEABLE = new EnchantmentTag("tradeable"); + public static final EnchantmentTag DOUBLE_TRADE_PRICE = new EnchantmentTag("double_trade_price"); + public static final EnchantmentTag IN_ENCHANTING_TABLE = new EnchantmentTag("in_enchanting_table"); + public static final EnchantmentTag ON_MOB_SPAWN_EQUIPMENT = new EnchantmentTag("on_mob_spawn_equipment"); + public static final EnchantmentTag ON_TRADED_EQUIPMENT = new EnchantmentTag("on_traded_equipment"); + public static final EnchantmentTag ON_RANDOM_LOOT = new EnchantmentTag("on_random_loot"); + public static final EnchantmentTag CURSE = new EnchantmentTag("curse"); + public static final EnchantmentTag SMELTS_LOOT = new EnchantmentTag("smelts_loot"); + public static final EnchantmentTag PREVENTS_BEE_SPAWNS_WHEN_MINING = new EnchantmentTag("prevents_bee_spawns_when_mining"); + public static final EnchantmentTag PREVENTS_DECORATED_POT_SHATTERING = new EnchantmentTag("prevents_decorated_pot_shattering"); + public static final EnchantmentTag PREVENTS_ICE_MELTING = new EnchantmentTag("prevents_ice_melting"); + public static final EnchantmentTag PREVENTS_INFESTED_SPAWNS = new EnchantmentTag("prevents_infested_spawns"); + public static final EnchantmentTag TREASURE = new EnchantmentTag("treasure"); + public static final EnchantmentTag NON_TREASURE = new EnchantmentTag("non_treasure"); + public static final EnchantmentTag TRADES_DESERT_COMMON = new EnchantmentTag("trades/desert_common"); + public static final EnchantmentTag TRADES_JUNGLE_COMMON = new EnchantmentTag("trades/jungle_common"); + public static final EnchantmentTag TRADES_PLAINS_COMMON = new EnchantmentTag("trades/plains_common"); + public static final EnchantmentTag TRADES_SAVANNA_COMMON = new EnchantmentTag("trades/savanna_common"); + public static final EnchantmentTag TRADES_SNOW_COMMON = new EnchantmentTag("trades/snow_common"); + public static final EnchantmentTag TRADES_SWAMP_COMMON = new EnchantmentTag("trades/swamp_common"); + public static final EnchantmentTag TRADES_TAIGA_COMMON = new EnchantmentTag("trades/taiga_common"); + public static final EnchantmentTag TRADES_DESERT_SPECIAL = new EnchantmentTag("trades/desert_special"); + public static final EnchantmentTag TRADES_JUNGLE_SPECIAL = new EnchantmentTag("trades/jungle_special"); + public static final EnchantmentTag TRADES_PLAINS_SPECIAL = new EnchantmentTag("trades/plains_special"); + public static final EnchantmentTag TRADES_SAVANNA_SPECIAL = new EnchantmentTag("trades/savanna_special"); + public static final EnchantmentTag TRADES_SNOW_SPECIAL = new EnchantmentTag("trades/snow_special"); + public static final EnchantmentTag TRADES_SWAMP_SPECIAL = new EnchantmentTag("trades/swamp_special"); + public static final EnchantmentTag TRADES_TAIGA_SPECIAL = new EnchantmentTag("trades/taiga_special"); + + private final int id; + + private EnchantmentTag(String identifier) { + this.id = ALL_ENCHANTMENT_TAGS.size(); + register(identifier, this); + } + + @Override + public int ordinal() { + return id; + } + + private static void register(String name, EnchantmentTag tag) { + ALL_ENCHANTMENT_TAGS.put(("minecraft:" + name).intern(), tag); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/tags/ItemTag.java b/core/src/main/java/org/geysermc/geyser/session/cache/tags/ItemTag.java index f064d0763..e1fbf4634 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/tags/ItemTag.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/tags/ItemTag.java @@ -25,44 +25,176 @@ package org.geysermc.geyser.session.cache.tags; -import org.geysermc.geyser.session.cache.TagCache; +import org.geysermc.geyser.util.Ordered; -public enum ItemTag { - AXOLOTL_FOOD("axolotl_food"), - CREEPER_IGNITERS("creeper_igniters"), - FISHES("fishes"), - FOX_FOOD("fox_food"), - PIGLIN_LOVED("piglin_loved"), - SMALL_FLOWERS("small_flowers"), - SNIFFER_FOOD("sniffer_food"), - PIGLIN_FOOD("piglin_food"), - COW_FOOD("cow_food"), - GOAT_FOOD("goat_food"), - SHEEP_FOOD("sheep_food"), - WOLF_FOOD("wolf_food"), - CAT_FOOD("cat_food"), - HORSE_FOOD("horse_food"), - CAMEL_FOOD("camel_food"), - ARMADILLO_FOOD("armadillo_food"), - BEE_FOOD("bee_food"), - CHICKEN_FOOD("chicken_food"), - FROG_FOOD("frog_food"), - HOGLIN_FOOD("hoglin_food"), - LLAMA_FOOD("llama_food"), - OCELOT_FOOD("ocelot_food"), - PANDA_FOOD("panda_food"), - PIG_FOOD("pig_food"), - RABBIT_FOOD("rabbit_food"), - STRIDER_FOOD("strider_food"), - TURTLE_FOOD("turtle_food"), - PARROT_FOOD("parrot_food"), - PARROT_POISONOUS_FOOD("parrot_poisonous_food"); +import java.util.HashMap; +import java.util.Map; + +@SuppressWarnings("unused") +public final class ItemTag implements Ordered { + public static final Map ALL_ITEM_TAGS = new HashMap<>(); + + public static final ItemTag WOOL = new ItemTag("wool"); + public static final ItemTag PLANKS = new ItemTag("planks"); + public static final ItemTag STONE_BRICKS = new ItemTag("stone_bricks"); + public static final ItemTag WOODEN_BUTTONS = new ItemTag("wooden_buttons"); + public static final ItemTag STONE_BUTTONS = new ItemTag("stone_buttons"); + public static final ItemTag BUTTONS = new ItemTag("buttons"); + public static final ItemTag WOOL_CARPETS = new ItemTag("wool_carpets"); + public static final ItemTag WOODEN_DOORS = new ItemTag("wooden_doors"); + public static final ItemTag WOODEN_STAIRS = new ItemTag("wooden_stairs"); + public static final ItemTag WOODEN_SLABS = new ItemTag("wooden_slabs"); + public static final ItemTag WOODEN_FENCES = new ItemTag("wooden_fences"); + public static final ItemTag FENCE_GATES = new ItemTag("fence_gates"); + public static final ItemTag WOODEN_PRESSURE_PLATES = new ItemTag("wooden_pressure_plates"); + public static final ItemTag WOODEN_TRAPDOORS = new ItemTag("wooden_trapdoors"); + public static final ItemTag DOORS = new ItemTag("doors"); + public static final ItemTag SAPLINGS = new ItemTag("saplings"); + public static final ItemTag LOGS_THAT_BURN = new ItemTag("logs_that_burn"); + public static final ItemTag LOGS = new ItemTag("logs"); + public static final ItemTag DARK_OAK_LOGS = new ItemTag("dark_oak_logs"); + public static final ItemTag OAK_LOGS = new ItemTag("oak_logs"); + public static final ItemTag BIRCH_LOGS = new ItemTag("birch_logs"); + public static final ItemTag ACACIA_LOGS = new ItemTag("acacia_logs"); + public static final ItemTag CHERRY_LOGS = new ItemTag("cherry_logs"); + public static final ItemTag JUNGLE_LOGS = new ItemTag("jungle_logs"); + public static final ItemTag SPRUCE_LOGS = new ItemTag("spruce_logs"); + public static final ItemTag MANGROVE_LOGS = new ItemTag("mangrove_logs"); + public static final ItemTag CRIMSON_STEMS = new ItemTag("crimson_stems"); + public static final ItemTag WARPED_STEMS = new ItemTag("warped_stems"); + public static final ItemTag BAMBOO_BLOCKS = new ItemTag("bamboo_blocks"); + public static final ItemTag WART_BLOCKS = new ItemTag("wart_blocks"); + public static final ItemTag BANNERS = new ItemTag("banners"); + public static final ItemTag SAND = new ItemTag("sand"); + public static final ItemTag SMELTS_TO_GLASS = new ItemTag("smelts_to_glass"); + public static final ItemTag STAIRS = new ItemTag("stairs"); + public static final ItemTag SLABS = new ItemTag("slabs"); + public static final ItemTag WALLS = new ItemTag("walls"); + public static final ItemTag ANVIL = new ItemTag("anvil"); + public static final ItemTag RAILS = new ItemTag("rails"); + public static final ItemTag LEAVES = new ItemTag("leaves"); + public static final ItemTag TRAPDOORS = new ItemTag("trapdoors"); + public static final ItemTag SMALL_FLOWERS = new ItemTag("small_flowers"); + public static final ItemTag BEDS = new ItemTag("beds"); + public static final ItemTag FENCES = new ItemTag("fences"); + public static final ItemTag TALL_FLOWERS = new ItemTag("tall_flowers"); + public static final ItemTag FLOWERS = new ItemTag("flowers"); + public static final ItemTag PIGLIN_REPELLENTS = new ItemTag("piglin_repellents"); + public static final ItemTag PIGLIN_LOVED = new ItemTag("piglin_loved"); + public static final ItemTag IGNORED_BY_PIGLIN_BABIES = new ItemTag("ignored_by_piglin_babies"); + public static final ItemTag MEAT = new ItemTag("meat"); + public static final ItemTag SNIFFER_FOOD = new ItemTag("sniffer_food"); + public static final ItemTag PIGLIN_FOOD = new ItemTag("piglin_food"); + public static final ItemTag FOX_FOOD = new ItemTag("fox_food"); + public static final ItemTag COW_FOOD = new ItemTag("cow_food"); + public static final ItemTag GOAT_FOOD = new ItemTag("goat_food"); + public static final ItemTag SHEEP_FOOD = new ItemTag("sheep_food"); + public static final ItemTag WOLF_FOOD = new ItemTag("wolf_food"); + public static final ItemTag CAT_FOOD = new ItemTag("cat_food"); + public static final ItemTag HORSE_FOOD = new ItemTag("horse_food"); + public static final ItemTag HORSE_TEMPT_ITEMS = new ItemTag("horse_tempt_items"); + public static final ItemTag CAMEL_FOOD = new ItemTag("camel_food"); + public static final ItemTag ARMADILLO_FOOD = new ItemTag("armadillo_food"); + public static final ItemTag BEE_FOOD = new ItemTag("bee_food"); + public static final ItemTag CHICKEN_FOOD = new ItemTag("chicken_food"); + public static final ItemTag FROG_FOOD = new ItemTag("frog_food"); + public static final ItemTag HOGLIN_FOOD = new ItemTag("hoglin_food"); + public static final ItemTag LLAMA_FOOD = new ItemTag("llama_food"); + public static final ItemTag LLAMA_TEMPT_ITEMS = new ItemTag("llama_tempt_items"); + public static final ItemTag OCELOT_FOOD = new ItemTag("ocelot_food"); + public static final ItemTag PANDA_FOOD = new ItemTag("panda_food"); + public static final ItemTag PIG_FOOD = new ItemTag("pig_food"); + public static final ItemTag RABBIT_FOOD = new ItemTag("rabbit_food"); + public static final ItemTag STRIDER_FOOD = new ItemTag("strider_food"); + public static final ItemTag STRIDER_TEMPT_ITEMS = new ItemTag("strider_tempt_items"); + public static final ItemTag TURTLE_FOOD = new ItemTag("turtle_food"); + public static final ItemTag PARROT_FOOD = new ItemTag("parrot_food"); + public static final ItemTag PARROT_POISONOUS_FOOD = new ItemTag("parrot_poisonous_food"); + public static final ItemTag AXOLOTL_FOOD = new ItemTag("axolotl_food"); + public static final ItemTag GOLD_ORES = new ItemTag("gold_ores"); + public static final ItemTag IRON_ORES = new ItemTag("iron_ores"); + public static final ItemTag DIAMOND_ORES = new ItemTag("diamond_ores"); + public static final ItemTag REDSTONE_ORES = new ItemTag("redstone_ores"); + public static final ItemTag LAPIS_ORES = new ItemTag("lapis_ores"); + public static final ItemTag COAL_ORES = new ItemTag("coal_ores"); + public static final ItemTag EMERALD_ORES = new ItemTag("emerald_ores"); + public static final ItemTag COPPER_ORES = new ItemTag("copper_ores"); + public static final ItemTag NON_FLAMMABLE_WOOD = new ItemTag("non_flammable_wood"); + public static final ItemTag SOUL_FIRE_BASE_BLOCKS = new ItemTag("soul_fire_base_blocks"); + public static final ItemTag CANDLES = new ItemTag("candles"); + public static final ItemTag DIRT = new ItemTag("dirt"); + public static final ItemTag TERRACOTTA = new ItemTag("terracotta"); + public static final ItemTag COMPLETES_FIND_TREE_TUTORIAL = new ItemTag("completes_find_tree_tutorial"); + public static final ItemTag BOATS = new ItemTag("boats"); + public static final ItemTag CHEST_BOATS = new ItemTag("chest_boats"); + public static final ItemTag FISHES = new ItemTag("fishes"); + public static final ItemTag SIGNS = new ItemTag("signs"); + public static final ItemTag CREEPER_DROP_MUSIC_DISCS = new ItemTag("creeper_drop_music_discs"); + public static final ItemTag COALS = new ItemTag("coals"); + public static final ItemTag ARROWS = new ItemTag("arrows"); + public static final ItemTag LECTERN_BOOKS = new ItemTag("lectern_books"); + public static final ItemTag BOOKSHELF_BOOKS = new ItemTag("bookshelf_books"); + public static final ItemTag BEACON_PAYMENT_ITEMS = new ItemTag("beacon_payment_items"); + public static final ItemTag STONE_TOOL_MATERIALS = new ItemTag("stone_tool_materials"); + public static final ItemTag STONE_CRAFTING_MATERIALS = new ItemTag("stone_crafting_materials"); + public static final ItemTag FREEZE_IMMUNE_WEARABLES = new ItemTag("freeze_immune_wearables"); + public static final ItemTag DAMPENS_VIBRATIONS = new ItemTag("dampens_vibrations"); + public static final ItemTag CLUSTER_MAX_HARVESTABLES = new ItemTag("cluster_max_harvestables"); + public static final ItemTag COMPASSES = new ItemTag("compasses"); + public static final ItemTag HANGING_SIGNS = new ItemTag("hanging_signs"); + public static final ItemTag CREEPER_IGNITERS = new ItemTag("creeper_igniters"); + public static final ItemTag NOTEBLOCK_TOP_INSTRUMENTS = new ItemTag("noteblock_top_instruments"); + public static final ItemTag FOOT_ARMOR = new ItemTag("foot_armor"); + public static final ItemTag LEG_ARMOR = new ItemTag("leg_armor"); + public static final ItemTag CHEST_ARMOR = new ItemTag("chest_armor"); + public static final ItemTag HEAD_ARMOR = new ItemTag("head_armor"); + public static final ItemTag SKULLS = new ItemTag("skulls"); + public static final ItemTag TRIMMABLE_ARMOR = new ItemTag("trimmable_armor"); + public static final ItemTag TRIM_MATERIALS = new ItemTag("trim_materials"); + public static final ItemTag TRIM_TEMPLATES = new ItemTag("trim_templates"); + public static final ItemTag DECORATED_POT_SHERDS = new ItemTag("decorated_pot_sherds"); + public static final ItemTag DECORATED_POT_INGREDIENTS = new ItemTag("decorated_pot_ingredients"); + public static final ItemTag SWORDS = new ItemTag("swords"); + public static final ItemTag AXES = new ItemTag("axes"); + public static final ItemTag HOES = new ItemTag("hoes"); + public static final ItemTag PICKAXES = new ItemTag("pickaxes"); + public static final ItemTag SHOVELS = new ItemTag("shovels"); + public static final ItemTag BREAKS_DECORATED_POTS = new ItemTag("breaks_decorated_pots"); + public static final ItemTag VILLAGER_PLANTABLE_SEEDS = new ItemTag("villager_plantable_seeds"); + public static final ItemTag DYEABLE = new ItemTag("dyeable"); + public static final ItemTag ENCHANTABLE_FOOT_ARMOR = new ItemTag("enchantable/foot_armor"); + public static final ItemTag ENCHANTABLE_LEG_ARMOR = new ItemTag("enchantable/leg_armor"); + public static final ItemTag ENCHANTABLE_CHEST_ARMOR = new ItemTag("enchantable/chest_armor"); + public static final ItemTag ENCHANTABLE_HEAD_ARMOR = new ItemTag("enchantable/head_armor"); + public static final ItemTag ENCHANTABLE_ARMOR = new ItemTag("enchantable/armor"); + public static final ItemTag ENCHANTABLE_SWORD = new ItemTag("enchantable/sword"); + public static final ItemTag ENCHANTABLE_FIRE_ASPECT = new ItemTag("enchantable/fire_aspect"); + public static final ItemTag ENCHANTABLE_SHARP_WEAPON = new ItemTag("enchantable/sharp_weapon"); + public static final ItemTag ENCHANTABLE_WEAPON = new ItemTag("enchantable/weapon"); + public static final ItemTag ENCHANTABLE_MINING = new ItemTag("enchantable/mining"); + public static final ItemTag ENCHANTABLE_MINING_LOOT = new ItemTag("enchantable/mining_loot"); + public static final ItemTag ENCHANTABLE_FISHING = new ItemTag("enchantable/fishing"); + public static final ItemTag ENCHANTABLE_TRIDENT = new ItemTag("enchantable/trident"); + public static final ItemTag ENCHANTABLE_DURABILITY = new ItemTag("enchantable/durability"); + public static final ItemTag ENCHANTABLE_BOW = new ItemTag("enchantable/bow"); + public static final ItemTag ENCHANTABLE_EQUIPPABLE = new ItemTag("enchantable/equippable"); + public static final ItemTag ENCHANTABLE_CROSSBOW = new ItemTag("enchantable/crossbow"); + public static final ItemTag ENCHANTABLE_VANISHING = new ItemTag("enchantable/vanishing"); + public static final ItemTag ENCHANTABLE_MACE = new ItemTag("enchantable/mace"); + + private final int id; - ItemTag(String identifier) { + private ItemTag(String identifier) { + this.id = ALL_ITEM_TAGS.size(); register(identifier, this); } + @Override + public int ordinal() { + return id; + } + private static void register(String name, ItemTag tag) { - TagCache.ALL_ITEM_TAGS.put("minecraft:" + name, tag); + ALL_ITEM_TAGS.put(("minecraft:" + name).intern(), tag); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/EnchantingInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/EnchantingInventoryTranslator.java index e1407346a..b51d86d13 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/EnchantingInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/EnchantingInventoryTranslator.java @@ -36,15 +36,14 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.response.ItemStackResponse; import org.cloudburstmc.protocol.bedrock.packet.PlayerEnchantOptionsPacket; import org.geysermc.geyser.inventory.*; -import org.geysermc.geyser.inventory.item.Enchantment; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; +import org.geysermc.geyser.item.enchantment.Enchantment; import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; import java.util.Arrays; -import java.util.Locale; public class EnchantingInventoryTranslator extends AbstractBlockInventoryTranslator { public EnchantingInventoryTranslator() { @@ -73,16 +72,16 @@ public class EnchantingInventoryTranslator extends AbstractBlockInventoryTransla // The Bedrock index might need changed, so let's look it up and see. int bedrockIndex = value; if (bedrockIndex != -1) { - Enchantment enchantment = Enchantment.getByJavaIdentifier("minecraft:" + Enchantment.JavaEnchantment.of(bedrockIndex).name().toLowerCase(Locale.ROOT)); - if (enchantment != null) { + Enchantment enchantment = session.getRegistryCache().enchantments().byId(value); + if (enchantment != null && enchantment.bedrockEnchantment() != null) { // Convert the Java enchantment index to Bedrock's - bedrockIndex = enchantment.ordinal(); + bedrockIndex = enchantment.bedrockEnchantment().ordinal(); } else { // There is no Bedrock enchantment equivalent bedrockIndex = -1; } } - enchantingInventory.getGeyserEnchantOptions()[slotToUpdate].setEnchantIndex(value, bedrockIndex); + enchantingInventory.getGeyserEnchantOptions()[slotToUpdate].setEnchantIndex(bedrockIndex); break; case 7: case 8: diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java index 89c50b12f..1ecc5bf82 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java @@ -26,11 +26,6 @@ package org.geysermc.geyser.translator.protocol.java; import com.google.common.base.Suppliers; -import org.geysermc.mcprotocollib.protocol.data.game.command.CommandNode; -import org.geysermc.mcprotocollib.protocol.data.game.command.CommandParser; -import org.geysermc.mcprotocollib.protocol.data.game.command.properties.ResourceProperties; -import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.AttributeType; -import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundCommandsPacket; import it.unimi.dsi.fastutil.Hash; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; @@ -46,13 +41,18 @@ import org.cloudburstmc.protocol.bedrock.packet.AvailableCommandsPacket; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.event.java.ServerDefineCommandsEvent; import org.geysermc.geyser.command.GeyserCommandManager; -import org.geysermc.geyser.inventory.item.Enchantment; +import org.geysermc.geyser.item.enchantment.Enchantment; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.EntityUtils; +import org.geysermc.mcprotocollib.protocol.data.game.command.CommandNode; +import org.geysermc.mcprotocollib.protocol.data.game.command.CommandParser; +import org.geysermc.mcprotocollib.protocol.data.game.command.properties.ResourceProperties; +import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.AttributeType; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundCommandsPacket; import java.util.*; import java.util.function.Supplier; @@ -267,7 +267,7 @@ public class JavaCommandsTranslator extends PacketTranslator ATTRIBUTES; - case "minecraft:enchantment" -> Enchantment.JavaEnchantment.ALL_JAVA_IDENTIFIERS; + case "minecraft:enchantment" -> context.getEnchantments(); case "minecraft:entity_type" -> context.getEntityTypes(); case "minecraft:mob_effect" -> ALL_EFFECT_IDENTIFIERS; case "minecraft:worldgen/biome" -> tags ? context.getBiomesWithTags() : context.getBiomes(); @@ -292,6 +292,7 @@ public class JavaCommandsTranslator extends PacketTranslator session.getTagCache().is(BlockTag.AXE_EFFECTIVE, block); - case "hoe" -> session.getTagCache().is(BlockTag.HOE_EFFECTIVE, block); - case "pickaxe" -> session.getTagCache().is(BlockTag.PICKAXE_EFFECTIVE, block); + case "axe" -> session.getTagCache().is(BlockTag.MINEABLE_AXE, block); + case "hoe" -> session.getTagCache().is(BlockTag.MINEABLE_HOE, block); + case "pickaxe" -> session.getTagCache().is(BlockTag.MINEABLE_PICKAXE, block); case "shears" -> session.getTagCache().is(BlockTag.LEAVES, block) || session.getTagCache().is(BlockTag.WOOL, block); - case "shovel" -> session.getTagCache().is(BlockTag.SHOVEL_EFFECTIVE, block); + case "shovel" -> session.getTagCache().is(BlockTag.MINEABLE_SHOVEL, block); case "sword" -> block == Blocks.COBWEB; default -> { session.getGeyser().getLogger().warning("Unknown tool type: " + itemToolType); @@ -145,7 +145,7 @@ public final class BlockUtils { toolCanBreak = canToolTierBreakBlock(session, block, toolTier); } - int toolEfficiencyLevel = ItemUtils.getEnchantmentLevel(components, Enchantment.JavaEnchantment.EFFICIENCY); + int toolEfficiencyLevel = ItemUtils.getEnchantmentLevel(session, components, BedrockEnchantment.EFFICIENCY); int hasteLevel = 0; int miningFatigueLevel = 0; @@ -160,7 +160,7 @@ public final class BlockUtils { boolean waterInEyes = session.getCollisionManager().isWaterInEyes(); boolean insideOfWaterWithoutAquaAffinity = waterInEyes && - ItemUtils.getEnchantmentLevel(session.getPlayerInventory().getItem(5).getComponents(), Enchantment.JavaEnchantment.AQUA_AFFINITY) < 1; + ItemUtils.getEnchantmentLevel(session, session.getPlayerInventory().getItem(5).getComponents(), BedrockEnchantment.AQUA_AFFINITY) < 1; return calculateBreakTime(block.destroyTime(), toolTier, canHarvestWithHand, correctTool, toolCanBreak, toolType, isShearsEffective, toolEfficiencyLevel, hasteLevel, miningFatigueLevel, insideOfWaterWithoutAquaAffinity, session.getPlayerEntity().isOnGround()); diff --git a/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java b/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java index c9d9903d4..bbb64a41e 100644 --- a/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java @@ -27,17 +27,26 @@ package org.geysermc.geyser.util; import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.Nullable; -import org.geysermc.geyser.inventory.item.Enchantment; +import org.geysermc.geyser.inventory.item.BedrockEnchantment; import org.geysermc.geyser.item.Items; +import org.geysermc.geyser.item.enchantment.Enchantment; +import org.geysermc.geyser.item.enchantment.EnchantmentComponent; import org.geysermc.geyser.item.type.FishingRodItem; import org.geysermc.geyser.item.type.Item; +import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments; -public class ItemUtils { +import java.util.Map; - public static int getEnchantmentLevel(@Nullable DataComponents components, Enchantment.JavaEnchantment enchantment) { +public final class ItemUtils { + + /** + * Cheap hack. Proper solution is to read the enchantment effects. + */ + @Deprecated + public static int getEnchantmentLevel(GeyserSession session, @Nullable DataComponents components, BedrockEnchantment bedrockEnchantment) { if (components == null) { return 0; } @@ -47,7 +56,32 @@ public class ItemUtils { return 0; } - return enchantmentData.getEnchantments().getOrDefault(enchantment.ordinal(), 0); + for (Map.Entry entry : enchantmentData.getEnchantments().entrySet()) { + Enchantment enchantment = session.getRegistryCache().enchantments().byId(entry.getKey()); + if (enchantment.bedrockEnchantment() == bedrockEnchantment) { + return entry.getValue(); + } + } + return 0; + } + + public static boolean hasEffect(GeyserSession session, @Nullable DataComponents components, EnchantmentComponent component) { + if (components == null) { + return false; + } + + ItemEnchantments enchantmentData = components.get(DataComponentType.ENCHANTMENTS); + if (enchantmentData == null) { + return false; + } + + for (Integer id : enchantmentData.getEnchantments().keySet()) { + Enchantment enchantment = session.getRegistryCache().enchantments().byId(id); + if (enchantment.effects().contains(component)) { + return true; + } + } + return false; } /** @@ -73,4 +107,7 @@ public class ItemUtils { } return components.get(DataComponentType.CUSTOM_NAME); } + + private ItemUtils() { + } } diff --git a/core/src/main/java/org/geysermc/geyser/item/Enchantment.java b/core/src/main/java/org/geysermc/geyser/util/Ordered.java similarity index 55% rename from core/src/main/java/org/geysermc/geyser/item/Enchantment.java rename to core/src/main/java/org/geysermc/geyser/util/Ordered.java index 506467afd..08ff5df72 100644 --- a/core/src/main/java/org/geysermc/geyser/item/Enchantment.java +++ b/core/src/main/java/org/geysermc/geyser/util/Ordered.java @@ -23,25 +23,11 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.geyser.item; - -import org.checkerframework.checker.nullness.qual.Nullable; -import org.cloudburstmc.nbt.NbtMap; -import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; +package org.geysermc.geyser.util; /** - * @param anvilCost also as a rarity multiplier + * Represents anything that could be tracked like a enum, without also creating a name and enum-wide array. */ -public record Enchantment(String supportedItemsTag, int maxLevel, int anvilCost, @Nullable String exclusiveSetTag) { - - // Implementation note: I have a feeling the tags can be a list of items, because in vanilla they're HolderSet classes. - // I'm not sure how that's wired over the network, so we'll put it off. - public static Enchantment read(RegistryEntry entry) { - NbtMap data = entry.getData(); - String supportedItems = data.getString("supported_items"); - int maxLevel = data.getInt("max_level"); - int anvilCost = data.getInt("anvil_cost"); - String exclusiveSet = data.getString("exclusive_set", null); - return new Enchantment(supportedItems, maxLevel, anvilCost, exclusiveSet); - } +public interface Ordered { + int ordinal(); } diff --git a/core/src/main/resources/mappings b/core/src/main/resources/mappings index 88e50df10..1f1d5ce8c 160000 --- a/core/src/main/resources/mappings +++ b/core/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 88e50df1008916c266428ac11f76f07dc24638c5 +Subproject commit 1f1d5ce8c482dac142f13e95e19368e3f36de144 From 3ead9e94aa3aefd35db170027f1c8eff240f30b6 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 3 Jun 2024 23:48:45 -0400 Subject: [PATCH 210/272] More unneeded classes --- .../inventory/item/BedrockEnchantment.java | 48 ------------------- .../geyser/registry/type/EnchantmentData.java | 35 -------------- 2 files changed, 83 deletions(-) delete mode 100644 core/src/main/java/org/geysermc/geyser/registry/type/EnchantmentData.java diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/BedrockEnchantment.java b/core/src/main/java/org/geysermc/geyser/inventory/item/BedrockEnchantment.java index a9125421e..6d3fdbc27 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/BedrockEnchantment.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/BedrockEnchantment.java @@ -95,52 +95,4 @@ public enum BedrockEnchantment { } return null; } - - /** - * Enchantments classified by their Java index - */ - public enum JavaEnchantment { - PROTECTION, - FIRE_PROTECTION, - FEATHER_FALLING, - BLAST_PROTECTION, - PROJECTILE_PROTECTION, - RESPIRATION, - AQUA_AFFINITY, - THORNS, - DEPTH_STRIDER, - FROST_WALKER, - BINDING_CURSE, - SOUL_SPEED, - SWIFT_SNEAK, - SHARPNESS, - SMITE, - BANE_OF_ARTHROPODS, - KNOCKBACK, - FIRE_ASPECT, - LOOTING, - SWEEPING_EDGE, - EFFICIENCY, - SILK_TOUCH, - UNBREAKING, - FORTUNE, - POWER, - PUNCH, - FLAME, - INFINITY, - LUCK_OF_THE_SEA, - LURE, - LOYALTY, - IMPALING, - RIPTIDE, - CHANNELING, - MULTISHOT, - QUICK_CHARGE, - PIERCING, - DENSITY, - BREACH, - WIND_BURST, - MENDING, - VANISHING_CURSE; - } } diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/EnchantmentData.java b/core/src/main/java/org/geysermc/geyser/registry/type/EnchantmentData.java deleted file mode 100644 index d341cd9e3..000000000 --- a/core/src/main/java/org/geysermc/geyser/registry/type/EnchantmentData.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.geyser.registry.type; - -import it.unimi.dsi.fastutil.ints.IntSet; -import org.geysermc.geyser.inventory.item.BedrockEnchantment.JavaEnchantment; - -import java.util.Set; - -public record EnchantmentData(int rarityMultiplier, int maxLevel, Set incompatibleEnchantments, - IntSet validItems) { -} From 087322f6cd9b2e61979c5561ab59a795e4ecd3a6 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 4 Jun 2024 00:01:59 -0400 Subject: [PATCH 211/272] Small set optimization --- .../org/geysermc/geyser/item/enchantment/Enchantment.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/enchantment/Enchantment.java b/core/src/main/java/org/geysermc/geyser/item/enchantment/Enchantment.java index 41cc36894..8d1d92f6c 100644 --- a/core/src/main/java/org/geysermc/geyser/item/enchantment/Enchantment.java +++ b/core/src/main/java/org/geysermc/geyser/item/enchantment/Enchantment.java @@ -66,16 +66,13 @@ public record Enchantment(String identifier, } private static Set readEnchantmentComponents(NbtMap effects) { - if (effects.isEmpty()) { - return Collections.emptySet(); - } Set components = new HashSet<>(); for (Map.Entry entry : effects.entrySet()) { switch (entry.getKey()) { case "minecraft:prevent_armor_change" -> components.add(EnchantmentComponent.PREVENT_ARMOR_CHANGE); } } - return components; + return Set.copyOf(components); // Also ensures any empty sets are consolidated } private static String readDescription(NbtMap tag) { From 688b642520fa8c14c09667003f0d61dd1c552044 Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 4 Jun 2024 22:14:42 +0200 Subject: [PATCH 212/272] Ignore PurchaseReceiptPacket (#4719) --- .../main/java/org/geysermc/geyser/network/CodecProcessor.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java b/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java index 6bd767fb7..b91f8d7dc 100644 --- a/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java +++ b/core/src/main/java/org/geysermc/geyser/network/CodecProcessor.java @@ -232,8 +232,8 @@ class CodecProcessor { .updateSerializer(CreatePhotoPacket.class, ILLEGAL_SERIALIZER) .updateSerializer(NpcRequestPacket.class, ILLEGAL_SERIALIZER) .updateSerializer(PhotoInfoRequestPacket.class, ILLEGAL_SERIALIZER) - // Illegal unused serverbound packets for featured servers - .updateSerializer(PurchaseReceiptPacket.class, ILLEGAL_SERIALIZER) + // Unused serverbound packets for featured servers, which is for some reason still occasionally sent + .updateSerializer(PurchaseReceiptPacket.class, IGNORED_SERIALIZER) // Illegal unused serverbound packets that are deprecated .updateSerializer(ClientCheatAbilityPacket.class, ILLEGAL_SERIALIZER) // Illegal unusued serverbound packets that relate to unused features From 42ae9eba559f947e1b4fdd15c2ff0f47f4cc26bb Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 4 Jun 2024 17:09:57 -0400 Subject: [PATCH 213/272] Fix air bubbles for Bedrock 1.21 --- .../entity/type/player/SessionPlayerEntity.java | 12 +++++++++++- .../geyser/network/UpstreamPacketHandler.java | 2 ++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java index 44b28ceaa..ad6729c42 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java @@ -31,9 +31,11 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.AttributeData; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; +import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket; import org.geysermc.geyser.entity.attribute.GeyserAttributeType; import org.geysermc.geyser.item.Items; +import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.AttributeUtils; import org.geysermc.geyser.util.DimensionUtils; @@ -65,6 +67,8 @@ public class SessionPlayerEntity extends PlayerEntity { @Getter private boolean isRidingInFront; + private int lastAirSupply = getMaxAir(); + public SessionPlayerEntity(GeyserSession session) { super(session, -1, 1, null, Vector3f.ZERO, Vector3f.ZERO, 0, 0, 0, null, null); @@ -159,7 +163,13 @@ public class SessionPlayerEntity extends PlayerEntity { @Override protected void setAirSupply(int amount) { - if (amount == getMaxAir()) { + // Seemingly required to be sent as of Bedrock 1.21. Otherwise, bubbles will appear as empty + // Also, this changes how the air bubble graphics/sounds are presented. Breathing on means sound effects and + // the bubbles visually pop + setFlag(EntityFlag.BREATHING, amount >= this.lastAirSupply); + this.lastAirSupply = amount; + + if (amount == getMaxAir() && GameProtocol.isPre1_21_0(session)) { super.setAirSupply(0); // Hide the bubble counter from the UI for the player } else { super.setAirSupply(amount); diff --git a/core/src/main/java/org/geysermc/geyser/network/UpstreamPacketHandler.java b/core/src/main/java/org/geysermc/geyser/network/UpstreamPacketHandler.java index 23ab1697f..c7aabb806 100644 --- a/core/src/main/java/org/geysermc/geyser/network/UpstreamPacketHandler.java +++ b/core/src/main/java/org/geysermc/geyser/network/UpstreamPacketHandler.java @@ -132,6 +132,8 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { } session.getUpstream().getSession().setCodec(packetCodec); + // FIXME temporary until 1.20.80 is dropped + session.getPlayerEntity().resetAir(); return true; } From fcdd1b91a1bcf3b9277927d13c09bf0959e3ad23 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 4 Jun 2024 22:47:31 -0400 Subject: [PATCH 214/272] New banner patterns --- .../org/geysermc/geyser/inventory/item/BannerPattern.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java b/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java index 442690d7d..b6cc2c206 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java @@ -72,7 +72,9 @@ public enum BannerPattern { SKULL("sku"), FLOWER("flo"), MOJANG("moj"), - PIGLIN("pig"); + PIGLIN("pig"), + FLOW("flw"), + GUSTER("gus"); private static final BannerPattern[] VALUES = values(); From 4ee9dd5d1708858c7842068b55187d7cba36fe4e Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Wed, 5 Jun 2024 16:45:11 -0400 Subject: [PATCH 215/272] New potions and merge potion enums --- .../geyser/entity/type/ArrowEntity.java | 9 +- .../geyser/inventory/item/Potion.java | 137 +++++++++++----- .../inventory/item/TippedArrowPotion.java | 153 ------------------ .../geysermc/geyser/item/type/ArrowItem.java | 10 +- .../geyser/item/type/TippedArrowItem.java | 8 +- 5 files changed, 104 insertions(+), 213 deletions(-) delete mode 100644 core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ArrowEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ArrowEntity.java index 1ee706811..ba1241434 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ArrowEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ArrowEntity.java @@ -28,7 +28,7 @@ package org.geysermc.geyser.entity.type; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.geysermc.geyser.entity.EntityDefinition; -import org.geysermc.geyser.inventory.item.TippedArrowPotion; +import org.geysermc.geyser.inventory.item.Potion; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; @@ -46,12 +46,7 @@ public class ArrowEntity extends AbstractArrowEntity { if (potionColor == -1) { dirtyMetadata.put(EntityDataTypes.CUSTOM_DISPLAY, (byte) 0); } else { - TippedArrowPotion potion = TippedArrowPotion.getByJavaColor(potionColor); - if (potion != null && potion.getJavaColor() != -1) { - dirtyMetadata.put(EntityDataTypes.CUSTOM_DISPLAY, (byte) potion.getBedrockId()); - } else { - dirtyMetadata.put(EntityDataTypes.CUSTOM_DISPLAY, (byte) 0); - } + dirtyMetadata.put(EntityDataTypes.CUSTOM_DISPLAY, Potion.toTippedArrowId(potionColor)); } } } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java b/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java index 86c19de80..c4d20c623 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java @@ -34,57 +34,68 @@ import java.util.Locale; @Getter public enum Potion { - WATER(0), - MUNDANE(1), - THICK(3), - AWKWARD(4), - NIGHT_VISION(5), - LONG_NIGHT_VISION(6), - INVISIBILITY(7), - LONG_INVISIBILITY(8), - LEAPING(9), - LONG_LEAPING(10), - STRONG_LEAPING(11), - FIRE_RESISTANCE(12), - LONG_FIRE_RESISTANCE(13), - SWIFTNESS(14), - LONG_SWIFTNESS(15), - STRONG_SWIFTNESS(16), - SLOWNESS(17), - LONG_SLOWNESS(18), - STRONG_SLOWNESS(42), - TURTLE_MASTER(37), - LONG_TURTLE_MASTER(38), - STRONG_TURTLE_MASTER(39), - WATER_BREATHING(19), - LONG_WATER_BREATHING(20), - HEALING(21), - STRONG_HEALING(22), - HARMING(23), - STRONG_HARMING(24), - POISON(25), - LONG_POISON(26), - STRONG_POISON(27), - REGENERATION(28), - LONG_REGENERATION(29), - STRONG_REGENERATION(30), - STRENGTH(31), - LONG_STRENGTH(32), - STRONG_STRENGTH(33), - WEAKNESS(34), - LONG_WEAKNESS(35), - LUCK(2), //does not exist - SLOW_FALLING(40), - LONG_SLOW_FALLING(41); + WATER(0, ArrowParticleColors.NONE), + MUNDANE(1, ArrowParticleColors.NONE), // 2 is extended? + THICK(3, ArrowParticleColors.NONE), + AWKWARD(4, ArrowParticleColors.NONE), + NIGHT_VISION(5, ArrowParticleColors.NIGHT_VISION), + LONG_NIGHT_VISION(6, ArrowParticleColors.NIGHT_VISION), + INVISIBILITY(7, ArrowParticleColors.INVISIBILITY), + LONG_INVISIBILITY(8, ArrowParticleColors.INVISIBILITY), + LEAPING(9, ArrowParticleColors.LEAPING), + LONG_LEAPING(10, ArrowParticleColors.LEAPING), + STRONG_LEAPING(11, ArrowParticleColors.LEAPING), + FIRE_RESISTANCE(12, ArrowParticleColors.FIRE_RESISTANCE), + LONG_FIRE_RESISTANCE(13, ArrowParticleColors.FIRE_RESISTANCE), + SWIFTNESS(14, ArrowParticleColors.SWIFTNESS), + LONG_SWIFTNESS(15, ArrowParticleColors.SWIFTNESS), + STRONG_SWIFTNESS(16, ArrowParticleColors.SWIFTNESS), + SLOWNESS(17, ArrowParticleColors.SLOWNESS), + LONG_SLOWNESS(18, ArrowParticleColors.SLOWNESS), + STRONG_SLOWNESS(42, ArrowParticleColors.SLOWNESS), + TURTLE_MASTER(37, ArrowParticleColors.TURTLE_MASTER), + LONG_TURTLE_MASTER(38, ArrowParticleColors.TURTLE_MASTER), + STRONG_TURTLE_MASTER(39, ArrowParticleColors.TURTLE_MASTER), + WATER_BREATHING(19, ArrowParticleColors.WATER_BREATHING), + LONG_WATER_BREATHING(20, ArrowParticleColors.WATER_BREATHING), + HEALING(21, ArrowParticleColors.HEALING), + STRONG_HEALING(22, ArrowParticleColors.HEALING), + HARMING(23, ArrowParticleColors.HARMING), + STRONG_HARMING(24, ArrowParticleColors.HARMING), + POISON(25, ArrowParticleColors.POISON), + LONG_POISON(26, ArrowParticleColors.POISON), + STRONG_POISON(27, ArrowParticleColors.POISON), + REGENERATION(28, ArrowParticleColors.REGENERATION), + LONG_REGENERATION(29, ArrowParticleColors.REGENERATION), + STRONG_REGENERATION(30, ArrowParticleColors.REGENERATION), + STRENGTH(31, ArrowParticleColors.STRENGTH), + LONG_STRENGTH(32, ArrowParticleColors.STRENGTH), + STRONG_STRENGTH(33, ArrowParticleColors.STRENGTH), + WEAKNESS(34, ArrowParticleColors.WEAKNESS), + LONG_WEAKNESS(35, ArrowParticleColors.WEAKNESS), + LUCK(2, ArrowParticleColors.NONE), // does not exist in Bedrock + SLOW_FALLING(40, ArrowParticleColors.SLOW_FALLING), + LONG_SLOW_FALLING(41, ArrowParticleColors.SLOW_FALLING), + WIND_CHARGING(43, ArrowParticleColors.WIND_CHARGING), + WEAVING(44, ArrowParticleColors.WEAVING), + OOZING(45, ArrowParticleColors.OOZING), + INFESTATION(46, ArrowParticleColors.INFESTATION); public static final Potion[] VALUES = values(); private final String javaIdentifier; private final short bedrockId; + private final int javaColor; - Potion(int bedrockId) { + Potion(int bedrockId, int javaColor) { this.javaIdentifier = "minecraft:" + this.name().toLowerCase(Locale.ENGLISH); this.bedrockId = (short) bedrockId; + this.javaColor = javaColor; + } + + public int tippedArrowId() { + // +1 likely to offset 0 as nothing? + return this.bedrockId + 1; } public PotionContents toComponent() { @@ -106,4 +117,44 @@ public enum Potion { } return null; } + + public static @Nullable Potion getByTippedArrowDamage(int bedrockId) { + return getByBedrockId(bedrockId - 1); + } + + public static byte toTippedArrowId(int javaParticleColor) { + for (Potion potion : VALUES) { + if (potion.javaColor == javaParticleColor) { + return (byte) (potion.bedrockId + 1); + } + } + return (byte) 0; + } + + /** + * For tipped arrow usage + */ + private static final class ArrowParticleColors { + static final int NONE = 1; + static final int NIGHT_VISION = 2039713; + static final int INVISIBILITY = 8356754; + static final int LEAPING = 2293580; + static final int FIRE_RESISTANCE = 14981690; + static final int SWIFTNESS = 8171462; + static final int SLOWNESS = 5926017; + static final int TURTLE_MASTER = 7691106; + static final int WATER_BREATHING = 3035801; + static final int HEALING = 16262179; + static final int HARMING = 4393481; + static final int POISON = 5149489; + static final int REGENERATION = 13458603; + static final int STRENGTH = 9643043; + static final int WEAKNESS = 4738376; + static final int LUCK = 3381504; + static final int SLOW_FALLING = 16773073; + static final int WIND_CHARGING = 12438015; + static final int WEAVING = 7891290; + static final int OOZING = 10092451; + static final int INFESTATION = 9214860; + } } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java b/core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java deleted file mode 100644 index b849e07e2..000000000 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/TippedArrowPotion.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.geyser.inventory.item; - -import lombok.Getter; -import org.checkerframework.checker.nullness.qual.Nullable; - -import java.util.Locale; - -/** - * Potion identifiers and their respective Bedrock IDs used with arrows. - * See here - */ -@Getter -public enum TippedArrowPotion { - WATER(-1, ArrowParticleColors.NONE), // Guessing this based off of the Potion enum. TODO merge? - MUNDANE(2, ArrowParticleColors.NONE), // 3 is extended? - THICK(4, ArrowParticleColors.NONE), - AWKWARD(5, ArrowParticleColors.NONE), - NIGHT_VISION(6, ArrowParticleColors.NIGHT_VISION), - LONG_NIGHT_VISION(7, ArrowParticleColors.NIGHT_VISION), - INVISIBILITY(8, ArrowParticleColors.INVISIBILITY), - LONG_INVISIBILITY(9, ArrowParticleColors.INVISIBILITY), - LEAPING(10, ArrowParticleColors.LEAPING), - LONG_LEAPING(11, ArrowParticleColors.LEAPING), - STRONG_LEAPING(12, ArrowParticleColors.LEAPING), - FIRE_RESISTANCE(13, ArrowParticleColors.FIRE_RESISTANCE), - LONG_FIRE_RESISTANCE(14, ArrowParticleColors.FIRE_RESISTANCE), - SWIFTNESS(15, ArrowParticleColors.SWIFTNESS), - LONG_SWIFTNESS(16, ArrowParticleColors.SWIFTNESS), - STRONG_SWIFTNESS(17, ArrowParticleColors.SWIFTNESS), - SLOWNESS(18, ArrowParticleColors.SLOWNESS), - LONG_SLOWNESS(19, ArrowParticleColors.SLOWNESS), - STRONG_SLOWNESS(43, ArrowParticleColors.SLOWNESS), - WATER_BREATHING(20, ArrowParticleColors.WATER_BREATHING), - LONG_WATER_BREATHING(21, ArrowParticleColors.WATER_BREATHING), - HEALING(22, ArrowParticleColors.HEALING), - STRONG_HEALING(23, ArrowParticleColors.HEALING), - HARMING(24, ArrowParticleColors.HARMING), - STRONG_HARMING(25, ArrowParticleColors.HARMING), - POISON(26, ArrowParticleColors.POISON), - LONG_POISON(27, ArrowParticleColors.POISON), - STRONG_POISON(28, ArrowParticleColors.POISON), - REGENERATION(29, ArrowParticleColors.REGENERATION), - LONG_REGENERATION(30, ArrowParticleColors.REGENERATION), - STRONG_REGENERATION(31, ArrowParticleColors.REGENERATION), - STRENGTH(32, ArrowParticleColors.STRENGTH), - LONG_STRENGTH(33, ArrowParticleColors.STRENGTH), - STRONG_STRENGTH(34, ArrowParticleColors.STRENGTH), - WEAKNESS(35, ArrowParticleColors.WEAKNESS), - LONG_WEAKNESS(36, ArrowParticleColors.WEAKNESS), - LUCK(2, ArrowParticleColors.NONE), // does not exist in Bedrock - TURTLE_MASTER(38, ArrowParticleColors.TURTLE_MASTER), - LONG_TURTLE_MASTER(39, ArrowParticleColors.TURTLE_MASTER), - STRONG_TURTLE_MASTER(40, ArrowParticleColors.TURTLE_MASTER), - SLOW_FALLING(41, ArrowParticleColors.SLOW_FALLING), - LONG_SLOW_FALLING(42, ArrowParticleColors.SLOW_FALLING); - - private static final TippedArrowPotion[] VALUES = values(); - - private final String javaIdentifier; - private final short bedrockId; - /** - * The Java color associated with this ID. - * Used for looking up Java arrow color entity metadata as Bedrock potion IDs, which is what is used for entities in Bedrock - */ - private final int javaColor; - - TippedArrowPotion(int bedrockId, ArrowParticleColors arrowParticleColor) { - this.javaIdentifier = "minecraft:" + this.name().toLowerCase(Locale.ENGLISH); - this.bedrockId = (short) bedrockId; - this.javaColor = arrowParticleColor.getColor(); - } - - public static @Nullable TippedArrowPotion of(int id) { - if (id >= 0 && id < VALUES.length) { - return VALUES[id]; - } - return null; - } - - public static @Nullable TippedArrowPotion getByBedrockId(int bedrockId) { - for (TippedArrowPotion potion : VALUES) { - if (potion.bedrockId == bedrockId) { - return potion; - } - } - return null; - } - - /** - * @param color the potion color to look up - * @return the tipped arrow potion that most closely resembles that color. - */ - public static @Nullable TippedArrowPotion getByJavaColor(int color) { - for (TippedArrowPotion potion : VALUES) { - if (potion.javaColor == color) { - return potion; - } - } - return null; - } - - private enum ArrowParticleColors { - NONE(-1), - NIGHT_VISION(2039713), - INVISIBILITY(8356754), - LEAPING(2293580), - FIRE_RESISTANCE(14981690), - SWIFTNESS(8171462), - SLOWNESS(5926017), - TURTLE_MASTER(7691106), - WATER_BREATHING(3035801), - HEALING(16262179), - HARMING(4393481), - POISON(5149489), - REGENERATION(13458603), - STRENGTH(9643043), - WEAKNESS(4738376), - LUCK(3381504), - SLOW_FALLING(16773073); - - @Getter - private final int color; - - ArrowParticleColors(int color) { - this.color = color; - } - } -} diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java index 84c3b1a39..c06a143ac 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java @@ -28,15 +28,13 @@ package org.geysermc.geyser.item.type; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.inventory.GeyserItemStack; -import org.geysermc.geyser.inventory.item.TippedArrowPotion; +import org.geysermc.geyser.inventory.item.Potion; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.PotionContents; -import java.util.Collections; - public class ArrowItem extends Item { public ArrowItem(String javaIdentifier, Builder builder) { super(javaIdentifier, builder); @@ -44,11 +42,11 @@ public class ArrowItem extends Item { @Override public @NonNull GeyserItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { - TippedArrowPotion tippedArrowPotion = TippedArrowPotion.getByBedrockId(itemData.getDamage()); + Potion potion = Potion.getByTippedArrowDamage(itemData.getDamage()); GeyserItemStack itemStack = super.translateToJava(itemData, mapping, mappings); - if (tippedArrowPotion != null) { + if (potion != null) { itemStack = Items.TIPPED_ARROW.newItemStack(itemStack.getAmount(), itemStack.getComponents()); - PotionContents contents = new PotionContents(tippedArrowPotion.ordinal(), -1, Collections.emptyList()); + PotionContents contents = potion.toComponent(); itemStack.getOrCreateComponents().put(DataComponentType.POTION_CONTENTS, contents); } return itemStack; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java index db33bb584..d9e58eaf9 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/TippedArrowItem.java @@ -27,7 +27,7 @@ package org.geysermc.geyser.item.type; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.inventory.item.TippedArrowPotion; +import org.geysermc.geyser.inventory.item.Potion; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; @@ -44,11 +44,11 @@ public class TippedArrowItem extends ArrowItem { if (components != null) { PotionContents potionContents = components.get(DataComponentType.POTION_CONTENTS); if (potionContents != null) { - TippedArrowPotion tippedArrowPotion = TippedArrowPotion.of(potionContents.getPotionId()); - if (tippedArrowPotion != null) { + Potion potion = Potion.getByJavaId(potionContents.getPotionId()); + if (potion != null) { return ItemData.builder() .definition(mapping.getBedrockDefinition()) - .damage(tippedArrowPotion.getBedrockId()) + .damage(potion.tippedArrowId()) .count(count); } GeyserImpl.getInstance().getLogger().debug("Unknown Java potion (tipped arrow): " + potionContents.getPotionId()); From 3f8739a88fe3b00d8d54a9208fe4239d26dd710f Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Wed, 5 Jun 2024 16:56:44 -0400 Subject: [PATCH 216/272] New effects --- .../src/main/java/org/geysermc/geyser/util/EntityUtils.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/src/main/java/org/geysermc/geyser/util/EntityUtils.java b/core/src/main/java/org/geysermc/geyser/util/EntityUtils.java index d11c1f9e4..bfb70a4ed 100644 --- a/core/src/main/java/org/geysermc/geyser/util/EntityUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/EntityUtils.java @@ -77,6 +77,12 @@ public final class EntityUtils { case BAD_OMEN -> 28; case HERO_OF_THE_VILLAGE -> 29; case DARKNESS -> 30; + case TRIAL_OMEN -> 31; + case WIND_CHARGED -> 32; + case WEAVING -> 33; + case OOZING -> 34; + case INFESTED -> 35; + case RAID_OMEN -> 36; default -> effect.ordinal() + 1; }; } From 8f5d1560a22bab61dea004b2d355c4d4e4e7f0fa Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Thu, 6 Jun 2024 18:20:24 -0400 Subject: [PATCH 217/272] Implement Bogged entity --- .../geyser/entity/EntityDefinitions.java | 6 ++ .../type/living/monster/BoggedEntity.java | 73 ++++++++++++++++++ .../type/living/monster/BreezeEntity.java | 44 +++++++++++ .../resources/bedrock/entity_identifiers.dat | Bin 8314 -> 8314 bytes 4 files changed, 123 insertions(+) create mode 100644 core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BoggedEntity.java create mode 100644 core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BreezeEntity.java diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index 21cc526dd..76c65e9c8 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -63,6 +63,7 @@ public final class EntityDefinitions { public static final EntityDefinition BEE; public static final EntityDefinition BLAZE; public static final EntityDefinition BOAT; + public static final EntityDefinition BOGGED; public static final EntityDefinition CAMEL; public static final EntityDefinition CAT; public static final EntityDefinition CAVE_SPIDER; @@ -503,6 +504,11 @@ public final class EntityDefinitions { .height(0.9f).width(0.5f) .addTranslator(MetadataType.BYTE, BatEntity::setBatFlags) .build(); + BOGGED = EntityDefinition.inherited(BoggedEntity::new, mobEntityBase) + .type(EntityType.BOGGED) + .height(1.99f).width(0.6f) + .addTranslator(MetadataType.BOOLEAN, BoggedEntity::setSheared) + .build(); BLAZE = EntityDefinition.inherited(BlazeEntity::new, mobEntityBase) .type(EntityType.BLAZE) .height(1.8f).width(0.6f) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BoggedEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BoggedEntity.java new file mode 100644 index 000000000..806d58ed1 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BoggedEntity.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.entity.type.living.monster; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.cloudburstmc.math.vector.Vector3f; +import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; +import org.geysermc.geyser.entity.EntityDefinition; +import org.geysermc.geyser.inventory.GeyserItemStack; +import org.geysermc.geyser.item.Items; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.util.InteractionResult; +import org.geysermc.geyser.util.InteractiveTag; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; + +import java.util.UUID; + +public class BoggedEntity extends AbstractSkeletonEntity { + private boolean sheared = false; + + public BoggedEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { + super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); + } + + public void setSheared(BooleanEntityMetadata entityMetadata) { + this.sheared = entityMetadata.getPrimitiveValue(); + setFlag(EntityFlag.SHEARED, this.sheared); + } + + @Override + protected @NonNull InteractiveTag testMobInteraction(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) { + if (itemInHand.asItem() == Items.SHEARS && readyForShearing()) { + return InteractiveTag.SHEAR; + } + return super.testMobInteraction(hand, itemInHand); + } + + @Override + protected @NonNull InteractionResult mobInteract(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) { + if (itemInHand.asItem() == Items.SHEARS && readyForShearing()) { + return InteractionResult.SUCCESS; + } + return super.mobInteract(hand, itemInHand); + } + + private boolean readyForShearing() { + return !this.sheared && this.isAlive(); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BreezeEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BreezeEntity.java new file mode 100644 index 000000000..25d466aaf --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BreezeEntity.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.entity.type.living.monster; + +import org.cloudburstmc.math.vector.Vector3f; +import org.geysermc.geyser.entity.EntityDefinition; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; + +import java.util.UUID; + +public class BreezeEntity extends MonsterEntity { + public BreezeEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { + super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); + } + + @Override + public void setPose(Pose pose) { + super.setPose(pose); + } +} diff --git a/core/src/main/resources/bedrock/entity_identifiers.dat b/core/src/main/resources/bedrock/entity_identifiers.dat index e7cdeb08e65d446bef173af7cea4bc56d5023df3..95d00c246abac44e32f992549d970a3e650fa440 100644 GIT binary patch delta 890 zcmX|9OGuPa6n5T^`~NflJe;?VlojFYpBWvSmouX?rm0~I3koVo7eZiQ8=;1T7OkS; z10yLCf@tMFvd9qH2t`D-ilJI&M9@aWI`>$v&b{ZJ`+eW}&e<+)msDqy!#X>Cd3OG) z^M(-fi6^lf8$rz>(B9h1xwDkJ5X<3wi@=rW z06xVBuo_L#{TZ%@1TMAa@tJDnpNACPMuEHWK?K|4Xn1{C@d$KAGtBoZ(t{_FEG9h` zye0nmNFO>Qc{IY~s5u25gojWFPuANkxMmjEiY2&o%`adLC;z86LVT1Bs39FsgB3J9 z8fw8bS9b(Q&=C~)5h!3eFp4$5g6TjSt3GNlkmLBVIfpyVc_y7`9>T7_LUn^!@DH)z zqCd+5|M>c-{uCA{rhLQL^-94CUU?Ik^B$*v0%>oCF@Jh;^tXyB&lrN90esNPjCEhj z;_@d`wZAIO9sA+b$4xx$s3jBELU37xCLN%;Q_M=+K0Md#cXkcGx=i z6)akFoLf>73^k>c5vKE|807nsNE4R88PQ7^d2Bi>EM?r;wMRn(a>~uf;9^vR-NET@ zdzG1YZ8}%4+X}c9O5mib;3l0bmL$yT30gV@?~O+#lG`{28>Qv0*6b;XR$ooYm8#F{ zB&Eziw@pcsChGd0Axp-tfBqGD`G&0>5=(kAVM?PADskiIj5^C%G4S(_NyQ6GKR?YF mbW&9$TG|e4fzcXaX=Ryw$unuyCUs<~Nu|D(M9JK4X!;8-wi;dl delta 925 zcmX|AOK1~e5N^^WP4e$1n`iTG)Psn&+07=g-8`G5r7xtV2T#R7oD9-56k>J^M5n*&3yk}ZLcP~J6w*r za~I|om)uva@Wmq7jyLcyAwiF4(6$Qvis^Xc7dV{Ou^Scm){{XsBycFD;YUQ^QSvzM zI_#KDRBJs>xDDa)9@hsh zJi#5Atk!z=S>>Y@ypEJ{Eu!K|K%f*cINdX1ZL%_a^#jb`?q2q7$O0B$j{W9j-gft~ ze_a`5pV{v9Zi-W#A;u_}S1KI)6K*n%cVUfaRk^>RaDk>S&>23-vG*a0g(fgY*35C+ zpT*IKO)J}1kLqIBOZ< z`K213on>cmMzZ From c3994a677be4fb3065db2151c71c24f53faa7308 Mon Sep 17 00:00:00 2001 From: RK_01 <50594595+RaphiMC@users.noreply.github.com> Date: Fri, 7 Jun 2024 00:54:33 +0200 Subject: [PATCH 218/272] Override forward-hostname setting if ViaProxy wildcard domain handling is enabled (#4720) --- .../viaproxy/GeyserViaProxyConfiguration.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyConfiguration.java b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyConfiguration.java index bf9d6816c..1b82e9f67 100644 --- a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyConfiguration.java +++ b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyConfiguration.java @@ -27,6 +27,7 @@ package org.geysermc.geyser.platform.viaproxy; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import net.raphimc.vialegacy.api.LegacyProtocolVersion; import net.raphimc.viaproxy.ViaProxy; +import net.raphimc.viaproxy.protocoltranslator.viaproxy.ViaProxyConfig; import org.geysermc.geyser.configuration.GeyserJacksonConfiguration; import java.io.File; @@ -50,4 +51,16 @@ public class GeyserViaProxyConfiguration extends GeyserJacksonConfiguration { return interval; } + @Override + public RemoteConfiguration getRemote() { + return new RemoteConfiguration() { + + @Override + public boolean isForwardHost() { + return super.isForwardHost() || !ViaProxy.getConfig().getWildcardDomainHandling().equals(ViaProxyConfig.WildcardDomainHandling.NONE); + } + + }; + } + } From 29c9515d55b1bf4dc734b935f905806ca0463414 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Thu, 6 Jun 2024 20:28:38 -0400 Subject: [PATCH 219/272] Re-implement jukebox songs --- .../geyser/item/enchantment/Enchantment.java | 18 ++-- .../geysermc/geyser/level/JukeboxSong.java | 40 +++++++++ .../geyser/session/cache/RegistryCache.java | 3 + .../geyser/session/cache/WorldCache.java | 16 ++++ .../java/level/JavaLevelEventTranslator.java | 90 +++++++++++++------ .../translator/text/MessageTranslator.java | 15 ++++ .../org/geysermc/geyser/util/SoundUtils.java | 3 +- 7 files changed, 141 insertions(+), 44 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/level/JukeboxSong.java diff --git a/core/src/main/java/org/geysermc/geyser/item/enchantment/Enchantment.java b/core/src/main/java/org/geysermc/geyser/item/enchantment/Enchantment.java index 8d1d92f6c..468b88e87 100644 --- a/core/src/main/java/org/geysermc/geyser/item/enchantment/Enchantment.java +++ b/core/src/main/java/org/geysermc/geyser/item/enchantment/Enchantment.java @@ -27,13 +27,15 @@ package org.geysermc.geyser.item.enchantment; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMap; -import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.item.BedrockEnchantment; import org.geysermc.geyser.session.cache.tags.EnchantmentTag; import org.geysermc.geyser.session.cache.tags.ItemTag; +import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; -import java.util.*; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; /** * @param description only populated if {@link #bedrockEnchantment()} is not null. @@ -59,7 +61,7 @@ public record Enchantment(String identifier, String exclusiveSet = data.getString("exclusive_set", null); EnchantmentTag exclusiveSetTag = exclusiveSet == null ? null : EnchantmentTag.ALL_ENCHANTMENT_TAGS.get(exclusiveSet.substring(1)); BedrockEnchantment bedrockEnchantment = BedrockEnchantment.getByJavaIdentifier(entry.getId()); - String description = bedrockEnchantment == null ? readDescription(data) : null; + String description = bedrockEnchantment == null ? MessageTranslator.deserializeDescription(data) : null; return new Enchantment(entry.getId(), effects, ItemTag.ALL_ITEM_TAGS.get(supportedItems), maxLevel, description, anvilCost, exclusiveSetTag, bedrockEnchantment); @@ -74,14 +76,4 @@ public record Enchantment(String identifier, } return Set.copyOf(components); // Also ensures any empty sets are consolidated } - - private static String readDescription(NbtMap tag) { - NbtMap description = tag.getCompound("description"); - String translate = description.getString("translate", null); - if (translate == null) { - GeyserImpl.getInstance().getLogger().debug("Don't know how to read description! " + tag); - return ""; - } - return translate; - } } diff --git a/core/src/main/java/org/geysermc/geyser/level/JukeboxSong.java b/core/src/main/java/org/geysermc/geyser/level/JukeboxSong.java new file mode 100644 index 000000000..fd6ce693d --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/level/JukeboxSong.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.level; + +import org.cloudburstmc.nbt.NbtMap; +import org.geysermc.geyser.translator.text.MessageTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; + +public record JukeboxSong(String soundEvent, String description) { + + public static JukeboxSong read(RegistryEntry entry) { + NbtMap data = entry.getData(); + String soundEvent = data.getString("sound_event"); + String description = MessageTranslator.deserializeDescription(data); + return new JukeboxSong(soundEvent, description); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java index fe970ee2b..266a0a418 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java @@ -40,6 +40,7 @@ import org.geysermc.geyser.inventory.item.BannerPattern; import org.geysermc.geyser.inventory.recipe.TrimRecipe; import org.geysermc.geyser.item.enchantment.Enchantment; import org.geysermc.geyser.level.JavaDimension; +import org.geysermc.geyser.level.JukeboxSong; import org.geysermc.geyser.level.PaintingType; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.registry.JavaRegistry; @@ -76,6 +77,7 @@ public final class RegistryCache { register("chat_type", cache -> cache.chatTypes, ($, entry) -> TextDecoration.readChatType(entry)); register("dimension_type", cache -> cache.dimensions, ($, entry) -> JavaDimension.read(entry)); register("enchantment", cache -> cache.enchantments, ($, entry) -> Enchantment.read(entry)); + register("jukebox_song", cache -> cache.jukeboxSongs, ($, entry) -> JukeboxSong.read(entry)); register("painting_variant", cache -> cache.paintings, ($, entry) -> PaintingType.getByName(entry.getId())); register("trim_material", cache -> cache.trimMaterials, TrimRecipe::readTrimMaterial); register("trim_pattern", cache -> cache.trimPatterns, TrimRecipe::readTrimPattern); @@ -115,6 +117,7 @@ public final class RegistryCache { */ private final JavaRegistry dimensions = new SimpleJavaRegistry<>(); private final JavaRegistry enchantments = new SimpleJavaRegistry<>(); + private final JavaRegistry jukeboxSongs = new SimpleJavaRegistry<>(); private final JavaRegistry paintings = new SimpleJavaRegistry<>(); private final JavaRegistry trimMaterials = new SimpleJavaRegistry<>(); private final JavaRegistry trimPatterns = new SimpleJavaRegistry<>(); diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/WorldCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/WorldCache.java index 44ec7a6b9..8eb715560 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/WorldCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/WorldCache.java @@ -28,8 +28,10 @@ package org.geysermc.geyser.session.cache; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntMaps; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import lombok.Getter; import lombok.Setter; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.packet.SetTitlePacket; import org.geysermc.geyser.scoreboard.Scoreboard; @@ -39,6 +41,7 @@ import org.geysermc.geyser.util.ChunkUtils; import org.geysermc.mcprotocollib.protocol.data.game.setting.Difficulty; import java.util.Iterator; +import java.util.Map; public final class WorldCache { private final GeyserSession session; @@ -61,6 +64,8 @@ public final class WorldCache { private int currentSequence; private final Object2IntMap unverifiedPredictions = new Object2IntOpenHashMap<>(1); + private final Map activeRecords = new Object2ObjectOpenHashMap<>(1); // Assume the average player won't be listening to many records + @Getter @Setter private boolean editingSignOnFront; @@ -185,4 +190,15 @@ public final class WorldCache { } } } + + public void addActiveRecord(Vector3i pos, String bedrockPlaySound) { + this.activeRecords.put(pos, bedrockPlaySound); + } + + // Implementation note: positions aren't removed unless the server calls, but this seems to match 1.21 Java + // client behavior. + @Nullable + public String removeActiveRecord(Vector3i pos) { + return this.activeRecords.remove(pos); + } } \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelEventTranslator.java index cb8a8e60f..ef0329209 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelEventTranslator.java @@ -25,28 +25,27 @@ package org.geysermc.geyser.translator.protocol.java.level; -import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; -import org.geysermc.mcprotocollib.protocol.data.game.level.event.*; -import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLevelEventPacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.protocol.bedrock.data.ParticleType; import org.cloudburstmc.protocol.bedrock.data.SoundEvent; -import org.cloudburstmc.protocol.bedrock.packet.LevelEventGenericPacket; -import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; -import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket; -import org.cloudburstmc.protocol.bedrock.packet.TextPacket; +import org.cloudburstmc.protocol.bedrock.packet.*; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.level.JukeboxSong; import org.geysermc.geyser.registry.Registries; +import org.geysermc.geyser.registry.type.SoundMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.level.event.LevelEventTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.geyser.util.SoundUtils; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; +import org.geysermc.mcprotocollib.protocol.data.game.level.event.*; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLevelEventPacket; import java.util.Collections; -import java.util.Locale; import java.util.Set; @Translator(packet = ClientboundLevelEventPacket.class) @@ -60,23 +59,48 @@ public class JavaLevelEventTranslator extends PacketTranslator { - LevelSoundEventPacket levelSoundEvent = new LevelSoundEventPacket(); - levelSoundEvent.setIdentifier(""); - levelSoundEvent.setSound(SoundEvent.STOP_RECORD); - levelSoundEvent.setPosition(pos); - levelSoundEvent.setRelativeVolumeDisabled(false); - levelSoundEvent.setExtraData(-1); - levelSoundEvent.setBabySound(false); - session.sendUpstreamPacket(levelSoundEvent); + String bedrockSound = session.getWorldCache().removeActiveRecord(origin); + if (bedrockSound == null) { + // Vanilla record + LevelSoundEventPacket levelSoundEvent = new LevelSoundEventPacket(); + levelSoundEvent.setIdentifier(""); + levelSoundEvent.setSound(SoundEvent.STOP_RECORD); + levelSoundEvent.setPosition(pos); + levelSoundEvent.setRelativeVolumeDisabled(false); + levelSoundEvent.setExtraData(-1); + levelSoundEvent.setBabySound(false); + session.sendUpstreamPacket(levelSoundEvent); + } else { + // Custom record + StopSoundPacket stopSound = new StopSoundPacket(); + stopSound.setSoundName(bedrockSound); + session.sendUpstreamPacket(stopSound); + } return; } default -> { diff --git a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java index 3507567be..152bf4160 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java @@ -35,6 +35,7 @@ import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.kyori.adventure.text.serializer.legacy.CharacterAndFormat; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; +import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.protocol.bedrock.packet.TextPacket; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.session.GeyserSession; @@ -424,6 +425,20 @@ public class MessageTranslator { return new String(newChars, 0, count - (whitespacesCount > 0 ? 1 : 0)).trim(); } + /** + * Deserialize an NbtMap provided from a registry into a string. + */ + // This may be a Component in the future. + public static String deserializeDescription(NbtMap tag) { + NbtMap description = tag.getCompound("description"); + String translate = description.getString("translate", null); + if (translate == null) { + GeyserImpl.getInstance().getLogger().debug("Don't know how to read description! " + tag); + return ""; + } + return translate; + } + public static void init() { // no-op } diff --git a/core/src/main/java/org/geysermc/geyser/util/SoundUtils.java b/core/src/main/java/org/geysermc/geyser/util/SoundUtils.java index 7559347e9..524d241db 100644 --- a/core/src/main/java/org/geysermc/geyser/util/SoundUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/SoundUtils.java @@ -33,7 +33,6 @@ import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket; import org.cloudburstmc.protocol.bedrock.packet.PlaySoundPacket; import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.Registries; @@ -52,7 +51,7 @@ public final class SoundUtils { * @param sound the sound name * @return a sound event from the given sound */ - private static @Nullable SoundEvent toSoundEvent(String sound) { + public static @Nullable SoundEvent toSoundEvent(String sound) { try { return SoundEvent.valueOf(sound.toUpperCase(Locale.ROOT).replace(".", "_")); } catch (Exception ex) { From 79bcc790ce6c4670569f78a819a7eab4f3c613eb Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Thu, 6 Jun 2024 20:30:55 -0400 Subject: [PATCH 220/272] Remove Registries.RECORDS --- .../geyser/registry/IntMappedRegistry.java | 122 ------------------ .../geysermc/geyser/registry/Registries.java | 6 - .../populator/ItemRegistryPopulator.java | 5 - 3 files changed, 133 deletions(-) delete mode 100644 core/src/main/java/org/geysermc/geyser/registry/IntMappedRegistry.java diff --git a/core/src/main/java/org/geysermc/geyser/registry/IntMappedRegistry.java b/core/src/main/java/org/geysermc/geyser/registry/IntMappedRegistry.java deleted file mode 100644 index 981ed0f8c..000000000 --- a/core/src/main/java/org/geysermc/geyser/registry/IntMappedRegistry.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.geyser.registry; - -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.geysermc.geyser.registry.loader.RegistryLoader; - -import java.util.function.Supplier; - -/** - * A mapped registry with an integer as the key. This class is designed to minimize the need for boxing/unboxing keys. - * - * @param the value - */ -public class IntMappedRegistry extends AbstractMappedRegistry> { - protected IntMappedRegistry(I input, RegistryLoader> registryLoader) { - super(input, registryLoader); - } - - /** - * Returns the value registered by the given integer. - * - * @param i the integer - * @return the value registered by the given integer. - */ - public V get(int i) { - return this.mappings.get(i); - } - - @Nullable - @Override - @Deprecated - public V get(Integer key) { - return super.get(key); - } - - /** - * Returns the value registered by the given key or the default value - * specified if null. - * - * @param i the key - * @param defaultValue the default value - * @return the value registered by the given key or the default value - * specified if null. - */ - public V getOrDefault(int i, V defaultValue) { - return this.mappings.getOrDefault(i, defaultValue); - } - - @Override - @Deprecated - public V getOrDefault(Integer key, V defaultValue) { - return super.getOrDefault(key, defaultValue); - } - - /** - * Registers a new value into this registry with the given key. - * - * @param i the key - * @param value the value - * @return a new value into this registry with the given key. - */ - public V register(int i, V value) { - return this.mappings.put(i, value); - } - - @Override - @Deprecated - public V register(Integer key, V value) { - return super.register(key, value); - } - - /** - * Creates a new integer mapped registry with the given {@link RegistryLoader}. The - * input type is not specified here, meaning the loader return type is either - * predefined, or the registry is populated at a later point. - * - * @param registryLoader the registry loader - * @param the input - * @param the map value - * @return a new registry with the given RegistryLoader - */ - public static IntMappedRegistry create(RegistryLoader> registryLoader) { - return new IntMappedRegistry<>(null, registryLoader); - } - - /** - * Creates a new integer mapped registry with the given {@link RegistryLoader} and input. - * - * @param registryLoader the registry loader - * @param the input - * @param the map value - * @return a new registry with the given RegistryLoader supplier - */ - public static IntMappedRegistry create(I input, Supplier>> registryLoader) { - return new IntMappedRegistry<>(input, registryLoader.get()); - } -} diff --git a/core/src/main/java/org/geysermc/geyser/registry/Registries.java b/core/src/main/java/org/geysermc/geyser/registry/Registries.java index c6980efd1..7815768ef 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/Registries.java +++ b/core/src/main/java/org/geysermc/geyser/registry/Registries.java @@ -149,12 +149,6 @@ public final class Registries { */ public static final VersionedRegistry> RECIPES = VersionedRegistry.create(RegistryLoaders.empty(Int2ObjectOpenHashMap::new)); - /** - * A mapped registry holding the available records, with the ID of the record being the key, and the {@link org.cloudburstmc.protocol.bedrock.data.SoundEvent} - * as the value. - */ - public static final IntMappedRegistry RECORDS = IntMappedRegistry.create(RegistryLoaders.empty(Int2ObjectOpenHashMap::new)); - /** * A mapped registry holding {@link ResourcePack}'s with the pack uuid as keys. */ diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java index 8f515c1cb..e19066462 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java @@ -41,7 +41,6 @@ import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.nbt.NbtUtils; import org.cloudburstmc.protocol.bedrock.codec.v671.Bedrock_v671; import org.cloudburstmc.protocol.bedrock.codec.v685.Bedrock_v685; -import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; import org.cloudburstmc.protocol.bedrock.data.definitions.SimpleItemDefinition; @@ -458,10 +457,6 @@ public class ItemRegistryPopulator { if (javaItem.javaIdentifier().contains("bucket") && !javaItem.javaIdentifier().contains("milk")) { buckets.add(definition); - } else if (javaItem.javaIdentifier().startsWith("minecraft:music_disc_")) { - // The Java record level event uses the item ID as the "key" to play the record - Registries.RECORDS.register(javaItem.javaId(), SoundEvent.valueOf("RECORD_" + - mapping.getBedrockIdentifier().replace("minecraft:music_disc_", "").toUpperCase(Locale.ENGLISH))); } mappings.add(mapping); From b7931f8d704f638273bb13215df0077fd144e049 Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Thu, 6 Jun 2024 23:34:06 +0200 Subject: [PATCH 221/272] Update protocol to suppress packet warnings --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1995a6ada..9ff1f3afd 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -10,7 +10,7 @@ netty-io-uring = "0.0.25.Final-SNAPSHOT" guava = "29.0-jre" gson = "2.3.1" # Provided by Spigot 1.8.8 websocket = "1.5.1" -protocol = "3.0.0.Beta2-20240520.153053-5" +protocol = "3.0.0.Beta2-20240606.172607-7" raknet = "1.0.0.CR3-20240416.144209-1" mcauthlib = "e5b0bcc" mcprotocollib = "1.20.6-2-20240520.030045-8" From 9b776b5321b0f98bd5ccbda9a692770f0c52e85f Mon Sep 17 00:00:00 2001 From: RK_01 <50594595+RaphiMC@users.noreply.github.com> Date: Fri, 7 Jun 2024 19:26:59 +0200 Subject: [PATCH 222/272] Fixed remote config being reset everytime when accessed on Geyser-ViaProxy (#4722) --- .../viaproxy/GeyserViaProxyConfiguration.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyConfiguration.java b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyConfiguration.java index 1b82e9f67..afc46fa6a 100644 --- a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyConfiguration.java +++ b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyConfiguration.java @@ -34,8 +34,16 @@ import java.io.File; import java.nio.file.Path; @JsonIgnoreProperties(ignoreUnknown = true) +@SuppressWarnings("FieldMayBeFinal") // Jackson requires that the fields are not final public class GeyserViaProxyConfiguration extends GeyserJacksonConfiguration { + private RemoteConfiguration remote = new RemoteConfiguration() { + @Override + public boolean isForwardHost() { + return super.isForwardHost() || !ViaProxy.getConfig().getWildcardDomainHandling().equals(ViaProxyConfig.WildcardDomainHandling.NONE); + } + }; + @Override public Path getFloodgateKeyPath() { return new File(GeyserViaProxyPlugin.ROOT_FOLDER, this.getFloodgateKeyFile()).toPath(); @@ -53,14 +61,7 @@ public class GeyserViaProxyConfiguration extends GeyserJacksonConfiguration { @Override public RemoteConfiguration getRemote() { - return new RemoteConfiguration() { - - @Override - public boolean isForwardHost() { - return super.isForwardHost() || !ViaProxy.getConfig().getWildcardDomainHandling().equals(ViaProxyConfig.WildcardDomainHandling.NONE); - } - - }; + return this.remote; } } From 8ae1150c8026af625bd39143b50f3b9a08acdfed Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Fri, 7 Jun 2024 19:47:21 +0200 Subject: [PATCH 223/272] Remove unused lectern code in ModWorldManager, fix spelling error in SessionLoginEvent --- .../api/event/bedrock/SessionLoginEvent.java | 6 +-- .../mod/world/GeyserModWorldManager.java | 38 ------------------- 2 files changed, 3 insertions(+), 41 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/event/bedrock/SessionLoginEvent.java b/api/src/main/java/org/geysermc/geyser/api/event/bedrock/SessionLoginEvent.java index 522562d11..86a5ec6f8 100644 --- a/api/src/main/java/org/geysermc/geyser/api/event/bedrock/SessionLoginEvent.java +++ b/api/src/main/java/org/geysermc/geyser/api/event/bedrock/SessionLoginEvent.java @@ -36,7 +36,7 @@ import java.util.Map; import java.util.Objects; /** - * Called when a session has logged in, and is about to connect to a remote java server. + * Called when a session has logged in, and is about to connect to a remote Java server. * This event is cancellable, and can be used to prevent the player from connecting to the remote server. */ public final class SessionLoginEvent extends ConnectionEvent implements Cancellable { @@ -99,9 +99,9 @@ public final class SessionLoginEvent extends ConnectionEvent implements Cancella } /** - * Gets the {@link RemoteServer} the section will attempt to connect to. + * Gets the {@link RemoteServer} the session will attempt to connect to. * - * @return the {@link RemoteServer} the section will attempt to connect to. + * @return the {@link RemoteServer} the session will attempt to connect to. */ public @NonNull RemoteServer remoteServer() { return this.remoteServer; diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java index 7aac684bb..5543dbcee 100644 --- a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java @@ -26,7 +26,6 @@ package org.geysermc.geyser.platform.mod.world; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; -import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import net.minecraft.SharedConstants; import net.minecraft.core.BlockPos; import net.minecraft.core.RegistryAccess; @@ -34,10 +33,7 @@ import net.minecraft.core.component.DataComponents; import net.minecraft.network.chat.Component; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.network.Filterable; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.component.WritableBookContent; -import net.minecraft.world.item.component.WrittenBookContent; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BannerBlockEntity; @@ -63,7 +59,6 @@ import java.util.concurrent.CompletableFuture; public class GeyserModWorldManager extends GeyserWorldManager { private static final GsonComponentSerializer GSON_SERIALIZER = GsonComponentSerializer.gson(); - private static final LegacyComponentSerializer LEGACY_SERIALIZER = LegacyComponentSerializer.legacySection(); private final MinecraftServer server; public GeyserModWorldManager(MinecraftServer server) { @@ -169,39 +164,6 @@ public class GeyserModWorldManager extends GeyserWorldManager { return server.getPlayerList().getPlayer(session.getPlayerEntity().getUuid()); } - private static int getPageCount(ItemStack itemStack) { - WrittenBookContent writtenBookContent = itemStack.get(DataComponents.WRITTEN_BOOK_CONTENT); - if (writtenBookContent != null) { - return writtenBookContent.pages().size(); - } else { - WritableBookContent writableBookContent = itemStack.get(DataComponents.WRITABLE_BOOK_CONTENT); - return writableBookContent != null ? writableBookContent.pages().size() : 0; - } - } - - private static List getPages(ItemStack itemStack) { - WrittenBookContent writtenBookContent = itemStack.get(DataComponents.WRITTEN_BOOK_CONTENT); - if (writtenBookContent != null) { - return writtenBookContent.pages().stream() - .map(Filterable::raw) - .map(GeyserModWorldManager::fromComponent) - .toList(); - } else { - WritableBookContent writableBookContent = itemStack.get(DataComponents.WRITABLE_BOOK_CONTENT); - if (writableBookContent == null) { - return List.of(); - } - return writableBookContent.pages().stream() - .map(Filterable::raw) - .toList(); - } - } - - private static String fromComponent(Component component) { - String json = Component.Serializer.toJson(component, RegistryAccess.EMPTY); - return LEGACY_SERIALIZER.serialize(GSON_SERIALIZER.deserializeOr(json, net.kyori.adventure.text.Component.empty())); - } - private static net.kyori.adventure.text.Component toKyoriComponent(Component component) { String json = Component.Serializer.toJson(component, RegistryAccess.EMPTY); return GSON_SERIALIZER.deserializeOr(json, net.kyori.adventure.text.Component.empty()); From 007ecb4363dcb7ca0f396732b4440f274d5b9842 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sun, 9 Jun 2024 15:06:39 -0400 Subject: [PATCH 224/272] Ensure custom blocks can be represented at any index --- .../java/org/geysermc/geyser/item/Items.java | 8 +------- .../geyser/registry/ListRegistry.java | 20 +++++++++++++++++++ .../geysermc/geyser/registry/Registries.java | 5 ++++- .../populator/BlockRegistryPopulator.java | 3 +-- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/Items.java b/core/src/main/java/org/geysermc/geyser/item/Items.java index 8c271a7bb..03f044068 100644 --- a/core/src/main/java/org/geysermc/geyser/item/Items.java +++ b/core/src/main/java/org/geysermc/geyser/item/Items.java @@ -30,8 +30,6 @@ import org.geysermc.geyser.item.type.*; import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.registry.Registries; -import java.util.Collections; - import static org.geysermc.geyser.item.type.Item.builder; /** @@ -1378,11 +1376,7 @@ public final class Items { public static T register(T item, int id) { item.setJavaId(id); - // This makes sure that the array is large enough to put the java item at the correct location - if (Registries.JAVA_ITEMS.get().size() <= id) { - Registries.JAVA_ITEMS.get().addAll(Collections.nCopies(id - Registries.JAVA_ITEMS.get().size() + 1, AIR)); - } - Registries.JAVA_ITEMS.get().set(id, item); + Registries.JAVA_ITEMS.registerWithAnyIndex(id, item, AIR); Registries.JAVA_ITEM_IDENTIFIERS.register(item.javaIdentifier(), item); return item; } diff --git a/core/src/main/java/org/geysermc/geyser/registry/ListRegistry.java b/core/src/main/java/org/geysermc/geyser/registry/ListRegistry.java index 34a78c370..2070d67ae 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/ListRegistry.java +++ b/core/src/main/java/org/geysermc/geyser/registry/ListRegistry.java @@ -29,6 +29,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.registry.loader.RegistryLoader; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.function.Supplier; @@ -94,6 +95,25 @@ public class ListRegistry extends Registry> { return this.mappings.set(index, value); } + /** + * Registers a new value into this registry with the given index, even if this value would normally be outside + * the range of a list. + * + * @param index the index + * @param value the value + * @param defaultValue the default value to fill empty spaces in the registry with. + * @return a new value into this registry with the given index. + */ + public M registerWithAnyIndex(int index, M value, M defaultValue) { + if (this.frozen) { + throw new IllegalStateException("Registry should not be modified after frozen!"); + } + if (this.mappings.size() <= index) { + this.mappings.addAll(Collections.nCopies(index - this.mappings.size() + 1, defaultValue)); + } + return this.mappings.set(index, value); + } + /** * Mark this registry as unsuitable for new additions. The backing list will then be optimized for storage. */ diff --git a/core/src/main/java/org/geysermc/geyser/registry/Registries.java b/core/src/main/java/org/geysermc/geyser/registry/Registries.java index 54d013140..b509d6ac0 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/Registries.java +++ b/core/src/main/java/org/geysermc/geyser/registry/Registries.java @@ -127,7 +127,10 @@ public final class Registries { */ public static final PacketTranslatorRegistry JAVA_PACKET_TRANSLATORS = PacketTranslatorRegistry.create(); - public static final SimpleRegistry> JAVA_ITEMS = SimpleRegistry.create(RegistryLoaders.empty(ArrayList::new)); + /** + * A registry containing all Java items ordered by their network ID. + */ + public static final ListRegistry JAVA_ITEMS = ListRegistry.create(RegistryLoaders.empty(ArrayList::new)); public static final SimpleMappedRegistry JAVA_ITEM_IDENTIFIERS = SimpleMappedRegistry.create(RegistryLoaders.empty(Object2ObjectOpenHashMap::new)); diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java index 6b856c509..a8fb0001d 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java @@ -213,7 +213,6 @@ public final class BlockRegistryPopulator { GeyserBedrockBlock[] javaToBedrockBlocks = new GeyserBedrockBlock[JAVA_BLOCKS_SIZE]; GeyserBedrockBlock[] javaToVanillaBedrockBlocks = new GeyserBedrockBlock[JAVA_BLOCKS_SIZE]; - //List javaToBedrockIdentifiers = new ArrayList<>(BlockRegistries.JAVA_BLOCKS.get().size()); var javaToBedrockIdentifiers = new Int2ObjectOpenHashMap(); Block lastBlockSeen = null; @@ -456,7 +455,7 @@ public final class BlockRegistryPopulator { }; block.setJavaId(javaBlockState.stateGroupId()); - BlockRegistries.JAVA_BLOCKS.get().add(javaBlockState.stateGroupId(), block); //TODO don't allow duplicates, allow blanks + BlockRegistries.JAVA_BLOCKS.registerWithAnyIndex(javaBlockState.stateGroupId(), block, Blocks.AIR); BlockRegistries.JAVA_IDENTIFIER_TO_ID.register(javaId, stateRuntimeId); BlockRegistries.BLOCK_STATES.register(stateRuntimeId, new BlockState(block, stateRuntimeId)); } From e9e364636a8774cdbe1244b46a81eec52e6700ee Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sun, 9 Jun 2024 15:44:29 -0400 Subject: [PATCH 225/272] New potion effects --- .../geyser/registry/loader/PotionMixRegistryLoader.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/registry/loader/PotionMixRegistryLoader.java b/core/src/main/java/org/geysermc/geyser/registry/loader/PotionMixRegistryLoader.java index 0eec7cdb6..eae4e2bea 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/loader/PotionMixRegistryLoader.java +++ b/core/src/main/java/org/geysermc/geyser/registry/loader/PotionMixRegistryLoader.java @@ -27,7 +27,6 @@ package org.geysermc.geyser.registry.loader; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.PotionMixData; import org.geysermc.geyser.inventory.item.Potion; import org.geysermc.geyser.item.Items; @@ -75,6 +74,11 @@ public class PotionMixRegistryLoader implements RegistryLoader inputs = List.of( getNonNull(mappings, Items.POTION), From ae6059bdc3c467f39d7c8a7094d897c0e08a1263 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sun, 9 Jun 2024 16:57:51 -0400 Subject: [PATCH 226/272] Implement wind charges --- .../geyser/entity/EntityDefinitions.java | 16 ++++++ .../entity/type/AbstractWindChargeEntity.java | 53 ++++++++++++++++++ .../geyser/session/GeyserSession.java | 1 + .../java/level/JavaExplodeTranslator.java | 56 ++++++++++++------- .../level/JavaLevelParticlesTranslator.java | 5 +- 5 files changed, 108 insertions(+), 23 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/entity/type/AbstractWindChargeEntity.java diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index 76c65e9c8..a7c2d6ca6 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -25,6 +25,8 @@ package org.geysermc.geyser.entity; +import org.geysermc.geyser.entity.type.AbstractWindChargeEntity; +import org.geysermc.geyser.entity.factory.EntityFactory; import org.geysermc.geyser.entity.type.living.monster.raid.RavagerEntity; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.MetadataType; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; @@ -64,6 +66,7 @@ public final class EntityDefinitions { public static final EntityDefinition BLAZE; public static final EntityDefinition BOAT; public static final EntityDefinition BOGGED; + public static final EntityDefinition BREEZE_WIND_CHARGE; public static final EntityDefinition CAMEL; public static final EntityDefinition CAT; public static final EntityDefinition CAVE_SPIDER; @@ -166,6 +169,7 @@ public final class EntityDefinitions { public static final EntityDefinition VINDICATOR; public static final EntityDefinition WANDERING_TRADER; public static final EntityDefinition WARDEN; + public static final EntityDefinition WIND_CHARGE; public static final EntityDefinition WITCH; public static final EntityDefinition WITHER; public static final EntityDefinition WITHER_SKELETON; @@ -376,6 +380,18 @@ public final class EntityDefinitions { .heightAndWidth(0.25f) .build(); + EntityFactory windChargeSupplier = AbstractWindChargeEntity::new; + BREEZE_WIND_CHARGE = EntityDefinition.inherited(windChargeSupplier, entityBase) + .type(EntityType.BREEZE_WIND_CHARGE) + .identifier("minecraft:breeze_wind_charge_projectile") + .heightAndWidth(0.3125f) + .build(); + WIND_CHARGE = EntityDefinition.inherited(windChargeSupplier, entityBase) + .type(EntityType.WIND_CHARGE) + .identifier("minecraft:wind_charge_projectile") + .heightAndWidth(0.3125f) + .build(); + EntityDefinition abstractArrowBase = EntityDefinition.inherited(AbstractArrowEntity::new, entityBase) .addTranslator(MetadataType.BYTE, AbstractArrowEntity::setArrowFlags) .addTranslator(null) // "Piercing level" diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/AbstractWindChargeEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/AbstractWindChargeEntity.java new file mode 100644 index 000000000..5678c3af4 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/entity/type/AbstractWindChargeEntity.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.entity.type; + +import org.cloudburstmc.math.vector.Vector3f; +import org.geysermc.geyser.entity.EntityDefinition; +import org.geysermc.geyser.session.GeyserSession; + +import java.util.UUID; + +/** + * Note that, as of 1.21, a wind charge entity does not actually implement the thrown item. We're just reusing + * the "hide until far away" aspect. + */ +public class AbstractWindChargeEntity extends ThrowableItemEntity { + public AbstractWindChargeEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { + super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); + } + + @Override + public void tick() { + super.tick(); + } + + @Override + protected float getDrag() { + // Always, even in water. As of 1.21. + return 1f; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index ae5e1d338..b8e617fbb 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -1047,6 +1047,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { @Override public void packetReceived(Session session, Packet packet) { + System.out.println(packet); Registries.JAVA_PACKET_TRANSLATORS.translate(packet.getClass(), packet, GeyserSession.this); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaExplodeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaExplodeTranslator.java index 496f5982d..85107d637 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaExplodeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaExplodeTranslator.java @@ -25,22 +25,24 @@ package org.geysermc.geyser.translator.protocol.java.level; -import org.geysermc.geyser.level.block.type.Block; -import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundExplodePacket; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; -import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.packet.LevelEventGenericPacket; -import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket; import org.cloudburstmc.protocol.bedrock.packet.SetEntityMotionPacket; -import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.ChunkUtils; +import org.geysermc.geyser.util.SoundUtils; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.ExplosionInteraction; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.Particle; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundExplodePacket; + +import java.util.concurrent.ThreadLocalRandom; @Translator(packet = ClientboundExplodePacket.class) public class JavaExplodeTranslator extends PacketTranslator { @@ -56,27 +58,39 @@ public class JavaExplodeTranslator extends PacketTranslator createParticle(GeyserSession session, Particle particle) { + public static @Nullable Function createParticle(GeyserSession session, Particle particle) { switch (particle.getType()) { case BLOCK -> { int blockState = session.getBlockMappings().getBedrockBlockId(((BlockParticleData) particle.getData()).getBlockState()); @@ -177,6 +177,7 @@ public class JavaLevelParticlesTranslator extends PacketTranslator { ParticleMapping particleMapping = Registries.PARTICLES.get(particle.getType()); + System.out.println(particle.getType() + " " + particleMapping); if (particleMapping == null) { //TODO ensure no particle can be null return null; } @@ -205,7 +206,7 @@ public class JavaLevelParticlesTranslator extends PacketTranslator Date: Sun, 9 Jun 2024 16:58:26 -0400 Subject: [PATCH 227/272] oooops --- .../src/main/java/org/geysermc/geyser/session/GeyserSession.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index b8e617fbb..ae5e1d338 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -1047,7 +1047,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { @Override public void packetReceived(Session session, Packet packet) { - System.out.println(packet); Registries.JAVA_PACKET_TRANSLATORS.translate(packet.getClass(), packet, GeyserSession.this); } From edee5e7a8e61b818c506428f6f9e2da942285fa5 Mon Sep 17 00:00:00 2001 From: RK_01 <50594595+RaphiMC@users.noreply.github.com> Date: Mon, 10 Jun 2024 01:43:10 +0200 Subject: [PATCH 228/272] Add builtin server transfer support for ViaProxy (#4723) --- .../viaproxy/GeyserViaProxyPlugin.java | 5 +- .../GeyserServerTransferListener.java | 62 +++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/listener/GeyserServerTransferListener.java diff --git a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyPlugin.java b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyPlugin.java index 30404e705..bdc80335a 100644 --- a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyPlugin.java +++ b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/GeyserViaProxyPlugin.java @@ -37,6 +37,7 @@ import org.apache.logging.log4j.LogManager; import org.geysermc.geyser.GeyserBootstrap; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserLogger; +import org.geysermc.geyser.api.event.EventRegistrar; import org.geysermc.geyser.api.network.AuthType; import org.geysermc.geyser.api.util.PlatformType; import org.geysermc.geyser.command.GeyserCommandManager; @@ -44,6 +45,7 @@ import org.geysermc.geyser.configuration.GeyserConfiguration; import org.geysermc.geyser.dump.BootstrapDumpInfo; import org.geysermc.geyser.ping.GeyserLegacyPingPassthrough; import org.geysermc.geyser.ping.IGeyserPingPassthrough; +import org.geysermc.geyser.platform.viaproxy.listener.GeyserServerTransferListener; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.GeyserLocale; import org.geysermc.geyser.util.FileUtils; @@ -57,7 +59,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.UUID; -public class GeyserViaProxyPlugin extends ViaProxyPlugin implements GeyserBootstrap { +public class GeyserViaProxyPlugin extends ViaProxyPlugin implements GeyserBootstrap, EventRegistrar { public static final File ROOT_FOLDER = new File(PluginManager.PLUGINS_DIR, "Geyser"); @@ -120,6 +122,7 @@ public class GeyserViaProxyPlugin extends ViaProxyPlugin implements GeyserBootst } this.geyser = GeyserImpl.load(PlatformType.VIAPROXY, this); + this.geyser.eventBus().register(this, new GeyserServerTransferListener()); LoopbackUtil.checkAndApplyLoopback(this.logger); } diff --git a/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/listener/GeyserServerTransferListener.java b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/listener/GeyserServerTransferListener.java new file mode 100644 index 000000000..64b3cc56e --- /dev/null +++ b/bootstrap/viaproxy/src/main/java/org/geysermc/geyser/platform/viaproxy/listener/GeyserServerTransferListener.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.platform.viaproxy.listener; + +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.net.HostAndPort; +import org.geysermc.event.PostOrder; +import org.geysermc.event.subscribe.Subscribe; +import org.geysermc.geyser.api.event.bedrock.SessionLoginEvent; +import org.geysermc.geyser.api.event.java.ServerTransferEvent; +import org.geysermc.geyser.session.GeyserSession; + +import java.util.Map; +import java.util.concurrent.TimeUnit; + +public class GeyserServerTransferListener { + + private final Cache> cookieStorages = CacheBuilder.newBuilder().expireAfterWrite(1, TimeUnit.MINUTES).build(); + + @Subscribe(postOrder = PostOrder.FIRST) + private void onServerTransfer(final ServerTransferEvent event) { + this.cookieStorages.put(event.connection().xuid(), event.cookies()); + final GeyserSession geyserSession = (GeyserSession) event.connection(); + final HostAndPort hostAndPort = HostAndPort.fromString(geyserSession.getClientData().getServerAddress()).withDefaultPort(19132); + event.bedrockHost(hostAndPort.getHost()); + event.bedrockPort(hostAndPort.getPort()); + } + + @Subscribe(postOrder = PostOrder.FIRST) + private void onSessionLogin(final SessionLoginEvent event) { + final Map cookies = this.cookieStorages.asMap().remove(event.connection().xuid()); + if (cookies != null) { + event.cookies(cookies); + event.transferring(true); + } + } + +} From 02179a798f12eaf5791e6d89cc95cfa0bf68d99a Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 10 Jun 2024 16:53:14 -0400 Subject: [PATCH 229/272] You shall compile! --- .../translator/protocol/java/level/JavaExplodeTranslator.java | 2 +- .../protocol/java/level/JavaLevelEventTranslator.java | 1 - .../protocol/java/level/JavaLevelParticlesTranslator.java | 1 - core/src/main/resources/mappings | 2 +- gradle/libs.versions.toml | 4 ++-- 5 files changed, 4 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaExplodeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaExplodeTranslator.java index 85107d637..f840b8143 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaExplodeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaExplodeTranslator.java @@ -74,7 +74,7 @@ public class JavaExplodeTranslator extends PacketTranslator { ParticleMapping particleMapping = Registries.PARTICLES.get(particle.getType()); - System.out.println(particle.getType() + " " + particleMapping); if (particleMapping == null) { //TODO ensure no particle can be null return null; } diff --git a/core/src/main/resources/mappings b/core/src/main/resources/mappings index 1f1d5ce8c..54705bcd2 160000 --- a/core/src/main/resources/mappings +++ b/core/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 1f1d5ce8c482dac142f13e95e19368e3f36de144 +Subproject commit 54705bcd2bcba830267efbb1fbfd4e52972c40f7 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 089cab44f..afd001220 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,7 +13,7 @@ websocket = "1.5.1" protocol = "3.0.0.Beta2-20240606.172607-7" raknet = "1.0.0.CR3-20240416.144209-1" mcauthlib = "e5b0bcc" -mcprotocollib = "1.21-SNAPSHOT" +mcprotocollib = "784e91c" adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" @@ -107,7 +107,7 @@ guava = { group = "com.google.guava", name = "guava", version.ref = "guava" } gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" } junit = { group = "org.junit.jupiter", name = "junit-jupiter", version.ref = "junit" } mcauthlib = { group = "com.github.GeyserMC", name = "MCAuthLib", version.ref = "mcauthlib" } -mcprotocollib = { group = "org.geysermc.mcprotocollib", name = "protocol", version.ref = "mcprotocollib" } +mcprotocollib = { group = "com.github.GeyserMC", name = "mcprotocollib", version.ref = "mcprotocollib" } raknet = { group = "org.cloudburstmc.netty", name = "netty-transport-raknet", version.ref = "raknet" } terminalconsoleappender = { group = "net.minecrell", name = "terminalconsoleappender", version.ref = "terminalconsoleappender" } velocity-api = { group = "com.velocitypowered", name = "velocity-api", version.ref = "velocity" } From 538e9f4dd6bb2d7d9e00fae73e834f9a93b572c1 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 10 Jun 2024 17:04:43 -0400 Subject: [PATCH 230/272] Properly remove SnowCollision --- .../translator/collision/BlockCollision.java | 2 +- .../translator/collision/SnowCollision.java | 89 ------------------- 2 files changed, 1 insertion(+), 90 deletions(-) delete mode 100644 core/src/main/java/org/geysermc/geyser/translator/collision/SnowCollision.java diff --git a/core/src/main/java/org/geysermc/geyser/translator/collision/BlockCollision.java b/core/src/main/java/org/geysermc/geyser/translator/collision/BlockCollision.java index a2615deb1..2481028a4 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/collision/BlockCollision.java +++ b/core/src/main/java/org/geysermc/geyser/translator/collision/BlockCollision.java @@ -61,7 +61,7 @@ public class BlockCollision { } /** - * Overridden in classes like SnowCollision and GrassPathCollision when correction code needs to be run before the + * Overridden in classes like GrassPathCollision when correction code needs to be run before the * main correction */ public void beforeCorrectPosition(int x, int y, int z, BoundingBox playerCollision) {} diff --git a/core/src/main/java/org/geysermc/geyser/translator/collision/SnowCollision.java b/core/src/main/java/org/geysermc/geyser/translator/collision/SnowCollision.java deleted file mode 100644 index af2bcb7ea..000000000 --- a/core/src/main/java/org/geysermc/geyser/translator/collision/SnowCollision.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.geyser.translator.collision; - -import lombok.EqualsAndHashCode; -import org.geysermc.geyser.level.physics.BoundingBox; -import org.geysermc.geyser.session.GeyserSession; - -@EqualsAndHashCode(callSuper = true) -//@CollisionRemapper(regex = "^snow$", passDefaultBoxes = true, usesParams = true) TODO remove if no bugs are found. Seems fine with Bedrock 1.20.80 and 1.20.5 -public class SnowCollision extends BlockCollision { - private final int layers; - - public SnowCollision(String params, BoundingBox[] defaultBoxes) { - super(defaultBoxes); - int layerCharIndex = params.indexOf("=") + 1; - layers = Integer.parseInt(params.substring(layerCharIndex, layerCharIndex + 1)); - - pushUpTolerance = 0.125; - } - - // Needs to run before the main correction code or it can move the player into blocks - // This is counteracted by the main collision code pushing them out - @Override - public void beforeCorrectPosition(int x, int y, int z, BoundingBox playerCollision) { - // In Bedrock, snow layers round down to half blocks but you can't sink into them at all - // This means the collision each half block reaches above where it should be on Java so the player has to be - // pushed down - if (layers == 4 || layers == 8) { - double playerMinY = playerCollision.getMiddleY() - (playerCollision.getSizeY() / 2); - double boxMaxY = (boundingBoxes[0].getMiddleY() + y) + (boundingBoxes[0].getSizeY() / 2); - // If the player is in the buggy area, push them down - if (playerMinY > boxMaxY && - playerMinY <= (boxMaxY + 0.125)) { - playerCollision.translate(0, boxMaxY - playerMinY, 0); - } - } - } - - @Override - public boolean correctPosition(GeyserSession session, int x, int y, int z, BoundingBox playerCollision) { - if (layers == 1) { - // 1 layer of snow does not have collision - return true; - } - // Hack to prevent false positives - playerCollision.setSizeX(playerCollision.getSizeX() - 0.0001); - playerCollision.setSizeY(playerCollision.getSizeY() - 0.0001); - playerCollision.setSizeZ(playerCollision.getSizeZ() - 0.0001); - - if (this.checkIntersection(x, y, z, playerCollision)) { - double playerMinY = playerCollision.getMiddleY() - (playerCollision.getSizeY() / 2); - double boxMaxY = (boundingBoxes[0].getMiddleY() + y) + (boundingBoxes[0].getSizeY() / 2); - // If the player actually can't step onto it (they can step onto it from other snow layers) - if ((boxMaxY - playerMinY) > 0.5) { - // Cancel the movement - return false; - } - } - - playerCollision.setSizeX(playerCollision.getSizeX() + 0.0001); - playerCollision.setSizeY(playerCollision.getSizeY() + 0.0001); - playerCollision.setSizeZ(playerCollision.getSizeZ() + 0.0001); - return super.correctPosition(session, x, y, z, playerCollision); - } -} From 9a310f248b265460c14fe944ac42696f056343ff Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 10 Jun 2024 21:59:03 -0400 Subject: [PATCH 231/272] 1.21-pre4 updated block tags --- .../java/org/geysermc/geyser/session/cache/tags/BlockTag.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/tags/BlockTag.java b/core/src/main/java/org/geysermc/geyser/session/cache/tags/BlockTag.java index 32d708eca..5a85efc84 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/tags/BlockTag.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/tags/BlockTag.java @@ -42,6 +42,7 @@ public final class BlockTag implements Ordered { public static final BlockTag BUTTONS = new BlockTag("buttons"); public static final BlockTag WOOL_CARPETS = new BlockTag("wool_carpets"); public static final BlockTag WOODEN_DOORS = new BlockTag("wooden_doors"); + public static final BlockTag MOB_INTERACTABLE_DOORS = new BlockTag("mob_interactable_doors"); public static final BlockTag WOODEN_STAIRS = new BlockTag("wooden_stairs"); public static final BlockTag WOODEN_SLABS = new BlockTag("wooden_slabs"); public static final BlockTag WOODEN_FENCES = new BlockTag("wooden_fences"); From d19807170df1b95a8856df4a86e7fc1d7f72b88f Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 10 Jun 2024 22:40:14 -0400 Subject: [PATCH 232/272] Properly show dyed wolf armor --- .../living/animal/tameable/WolfEntity.java | 2 +- .../java/org/geysermc/geyser/item/Items.java | 4 +- .../geyser/item/type/DyeableArmorItem.java | 7 +-- .../org/geysermc/geyser/item/type/Item.java | 8 ++++ .../geyser/item/type/WolfArmorItem.java | 46 +++++++++++++++++++ .../org/geysermc/geyser/util/ItemUtils.java | 7 ++- 6 files changed, 64 insertions(+), 10 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/item/type/WolfArmorItem.java diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java index 9c6c5e08d..e7fde2be8 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/tameable/WolfEntity.java @@ -123,7 +123,7 @@ public class WolfEntity extends TameableEntity { @Override public void setChestplate(ItemStack stack) { super.setChestplate(stack); - isCurseOfBinding = ItemUtils.hasEffect(session, stack.getDataComponents(), EnchantmentComponent.PREVENT_ARMOR_CHANGE); // TODO test + isCurseOfBinding = ItemUtils.hasEffect(session, stack, EnchantmentComponent.PREVENT_ARMOR_CHANGE); // TODO test } @Override diff --git a/core/src/main/java/org/geysermc/geyser/item/Items.java b/core/src/main/java/org/geysermc/geyser/item/Items.java index 82bef33dc..5ae69fa4e 100644 --- a/core/src/main/java/org/geysermc/geyser/item/Items.java +++ b/core/src/main/java/org/geysermc/geyser/item/Items.java @@ -834,7 +834,7 @@ public final class Items { public static final Item TURTLE_HELMET = register(new ArmorItem("turtle_helmet", ArmorMaterial.TURTLE, builder().stackSize(1).maxDamage(275))); public static final Item TURTLE_SCUTE = register(new Item("turtle_scute", builder())); public static final Item ARMADILLO_SCUTE = register(new Item("armadillo_scute", builder())); - public static final Item WOLF_ARMOR = register(new ArmorItem("wolf_armor", ArmorMaterial.ARMADILLO, builder().stackSize(1).maxDamage(64))); + public static final Item WOLF_ARMOR = register(new WolfArmorItem("wolf_armor", ArmorMaterial.ARMADILLO, builder().stackSize(1).maxDamage(64))); public static final Item FLINT_AND_STEEL = register(new Item("flint_and_steel", builder().stackSize(1).maxDamage(64))); public static final Item BOWL = register(new Item("bowl", builder())); public static final Item APPLE = register(new Item("apple", builder())); @@ -1042,7 +1042,7 @@ public final class Items { public static final Item BLAZE_POWDER = register(new Item("blaze_powder", builder())); public static final Item MAGMA_CREAM = register(new Item("magma_cream", builder())); public static final Item BREWING_STAND = register(new BlockItem(builder(), Blocks.BREWING_STAND)); - public static final Item CAULDRON = register(new BlockItem(builder(), Blocks.CAULDRON, Blocks.LAVA_CAULDRON, Blocks.WATER_CAULDRON, Blocks.POWDER_SNOW_CAULDRON)); + public static final Item CAULDRON = register(new BlockItem(builder(), Blocks.CAULDRON, Blocks.WATER_CAULDRON, Blocks.LAVA_CAULDRON, Blocks.POWDER_SNOW_CAULDRON)); public static final Item ENDER_EYE = register(new Item("ender_eye", builder())); public static final Item GLISTERING_MELON_SLICE = register(new Item("glistering_melon_slice", builder())); public static final Item ARMADILLO_SPAWN_EGG = register(new SpawnEggItem("armadillo_spawn_egg", builder())); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java index b2dbb95e5..8c63eaeb0 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/DyeableArmorItem.java @@ -29,9 +29,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.item.ArmorMaterial; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.DyedItemColor; public class DyeableArmorItem extends ArmorItem { public DyeableArmorItem(String javaIdentifier, ArmorMaterial material, Builder builder) { @@ -44,9 +42,6 @@ public class DyeableArmorItem extends ArmorItem { // Note that this is handled as of 1.20.5 in the ItemColors class. // But horse leather armor and body leather armor are now both armor items. So it works! - DyedItemColor dyedItemColor = components.get(DataComponentType.DYED_COLOR); - if (dyedItemColor != null) { - builder.putInt("customColor", dyedItemColor.getRgb()); - } + translateDyedColor(components, builder); } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/Item.java b/core/src/main/java/org/geysermc/geyser/item/type/Item.java index 8c67d7d5f..2caa65dac 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/Item.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/Item.java @@ -48,6 +48,7 @@ import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.mcprotocollib.protocol.data.game.Identifier; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DyedItemColor; import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments; import java.util.ArrayList; @@ -253,6 +254,13 @@ public class Item { builder.getOrCreateLore().add(0, ChatColor.RESET + ChatColor.GRAY + enchantmentName + " " + lvlTranslation); } + protected final void translateDyedColor(DataComponents components, BedrockItemBuilder builder) { + DyedItemColor dyedItemColor = components.get(DataComponentType.DYED_COLOR); + if (dyedItemColor != null) { + builder.putInt("customColor", dyedItemColor.getRgb()); + } + } + /* Translation methods end */ public GeyserItemStack newItemStack(int count, DataComponents components) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/WolfArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/WolfArmorItem.java new file mode 100644 index 000000000..bd97a6a7d --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/item/type/WolfArmorItem.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.item.type; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.geysermc.geyser.item.ArmorMaterial; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; + +public class WolfArmorItem extends ArmorItem { + public WolfArmorItem(String javaIdentifier, ArmorMaterial material, Builder builder) { + super(javaIdentifier, material, builder); + } + + @Override + public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { + super.translateComponentsToBedrock(session, components, builder); + + // Note that this is handled as of 1.21 in the ItemColors class. + translateDyedColor(components, builder); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java b/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java index bbb64a41e..eec0d173d 100644 --- a/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/ItemUtils.java @@ -34,6 +34,7 @@ import org.geysermc.geyser.item.enchantment.EnchantmentComponent; import org.geysermc.geyser.item.type.FishingRodItem; import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments; @@ -65,7 +66,11 @@ public final class ItemUtils { return 0; } - public static boolean hasEffect(GeyserSession session, @Nullable DataComponents components, EnchantmentComponent component) { + public static boolean hasEffect(GeyserSession session, @Nullable ItemStack itemStack, EnchantmentComponent component) { + if (itemStack == null) { + return false; + } + DataComponents components = itemStack.getDataComponents(); if (components == null) { return false; } From 956a84a3fbbcc04bade20448e3d5009a07ea086e Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 11 Jun 2024 10:47:26 -0400 Subject: [PATCH 233/272] Enchantment tag can be null --- .../java/org/geysermc/geyser/session/cache/TagCache.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java index 335e940f4..933b57db7 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.session.cache; import it.unimi.dsi.fastutil.ints.IntArrays; +import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.inventory.GeyserItemStack; @@ -83,8 +84,12 @@ public final class TagCache { loadTags("Enchantment", enchantmentTags, ALL_ENCHANTMENT_TAGS, this.enchantments); } - private void loadTags(String type, Map packetTags, Map allTags, int[][] localValues) { + private void loadTags(String type, @Nullable Map packetTags, Map allTags, int[][] localValues) { Arrays.fill(localValues, IntArrays.EMPTY_ARRAY); + if (packetTags == null) { + GeyserImpl.getInstance().getLogger().debug("Not loading " + type + " tags; they do not exist here."); + return; + } allTags.forEach((location, tag) -> { int[] values = packetTags.get(location); if (values != null) { From b78c7b2bd3dd94dc45c91e2a4cabfb4b77cabe7c Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 11 Jun 2024 10:54:57 -0400 Subject: [PATCH 234/272] Fix #4729 --- .../level/block/entity/DoubleChestBlockEntityTranslator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java index 102f4a0e6..988d94073 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java @@ -38,7 +38,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType * Chests have more block entity properties in Bedrock, which is solved by implementing the BedrockChunkWantsBlockEntityTag */ @BlockEntity(type = { BlockEntityType.CHEST, BlockEntityType.TRAPPED_CHEST }) -public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator { +public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) { From 29dacd2397e9e3688141dbf61874daab9776c343 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 11 Jun 2024 14:26:53 -0400 Subject: [PATCH 235/272] Properly remap coral blocks on 1.20.80 --- .../registry/populator/Conversion685_671.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion685_671.java b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion685_671.java index 250fd9d9f..0b0731707 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion685_671.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion685_671.java @@ -51,16 +51,16 @@ public class Conversion685_671 { if (NEW_CORAL_BLOCKS.contains(identifer)) { switch (identifer) { - case "minecraft:tube_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(0); } - case "minecraft:brain_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(1); } - case "minecraft:bubble_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(2); } - case "minecraft:fire_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(3); } - case "minecraft:horn_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(4); } - case "minecraft:dead_tube_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(8); } - case "minecraft:dead_brain_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(9); } - case "minecraft:dead_bubble_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(10); } - case "minecraft:dead_fire_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(11); } - case "minecraft:dead_horn_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(12); } + case "minecraft:tube_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:coral_block").withBedrockData(0); } + case "minecraft:brain_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:coral_block").withBedrockData(1); } + case "minecraft:bubble_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:coral_block").withBedrockData(2); } + case "minecraft:fire_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:coral_block").withBedrockData(3); } + case "minecraft:horn_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:coral_block").withBedrockData(4); } + case "minecraft:dead_tube_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:coral_block").withBedrockData(8); } + case "minecraft:dead_brain_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:coral_block").withBedrockData(9); } + case "minecraft:dead_bubble_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:coral_block").withBedrockData(10); } + case "minecraft:dead_fire_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:coral_block").withBedrockData(11); } + case "minecraft:dead_horn_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:coral_block").withBedrockData(12); } } } From a42c979abb0a9b20588f60e7b0d6be254021f9f2 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Wed, 12 Jun 2024 00:12:15 -0400 Subject: [PATCH 236/272] This variant of tag loading should be slightly more efficient --- .../java/org/geysermc/geyser/session/cache/TagCache.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java index 933b57db7..656a16cf4 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java @@ -85,8 +85,8 @@ public final class TagCache { } private void loadTags(String type, @Nullable Map packetTags, Map allTags, int[][] localValues) { - Arrays.fill(localValues, IntArrays.EMPTY_ARRAY); if (packetTags == null) { + Arrays.fill(localValues, IntArrays.EMPTY_ARRAY); GeyserImpl.getInstance().getLogger().debug("Not loading " + type + " tags; they do not exist here."); return; } @@ -95,8 +95,11 @@ public final class TagCache { if (values != null) { if (values.length != 0) { localValues[tag.ordinal()] = values; + } else { + localValues[tag.ordinal()] = IntArrays.EMPTY_ARRAY; } } else { + localValues[tag.ordinal()] = IntArrays.EMPTY_ARRAY; GeyserImpl.getInstance().getLogger().debug(type + " tag not found from server: " + location); } }); From 82d68bfe9bee47dcd90723044d22841c5ca9f60f Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Thu, 13 Jun 2024 00:14:10 +0200 Subject: [PATCH 237/272] Bump fabric/neoforge dependencies to 1.21, update README.md, bump Geyser version to 2.4.0 --- README.md | 2 +- .../src/main/resources/META-INF/neoforge.mods.toml | 2 +- .../main/kotlin/geyser.modded-conventions.gradle.kts | 11 ++++++++--- gradle.properties | 2 +- gradle/libs.versions.toml | 8 ++++---- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index dd2d096ec..c45af73ed 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here! -### Currently supporting Minecraft Bedrock 1.20.80 - 1.21.0 and Minecraft Java 1.20.5/1.20.6 +### Currently supporting Minecraft Bedrock 1.20.80 - 1.21.0 and Minecraft Java 1.21 ## Setting Up Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser. diff --git a/bootstrap/mod/neoforge/src/main/resources/META-INF/neoforge.mods.toml b/bootstrap/mod/neoforge/src/main/resources/META-INF/neoforge.mods.toml index ff2823aa2..3a25f6119 100644 --- a/bootstrap/mod/neoforge/src/main/resources/META-INF/neoforge.mods.toml +++ b/bootstrap/mod/neoforge/src/main/resources/META-INF/neoforge.mods.toml @@ -20,6 +20,6 @@ config = "geyser.mixins.json" [[dependencies.geyser_neoforge]] modId="minecraft" type="required" - versionRange="[1.20.5,1.21)" + versionRange="[1.20.5,)" ordering="NONE" side="BOTH" \ No newline at end of file diff --git a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts index b75e9c5be..6472e4312 100644 --- a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts @@ -110,18 +110,23 @@ afterEvaluate { } dependencies { - minecraft("com.mojang:minecraft:1.20.5") + minecraft("com.mojang:minecraft:1.21-rc1") mappings(loom.officialMojangMappings()) } repositories { // mavenLocal() - maven("https://repo.opencollab.dev/maven-releases/") - maven("https://repo.opencollab.dev/maven-snapshots/") + maven("https://repo.opencollab.dev/main") maven("https://jitpack.io") maven("https://oss.sonatype.org/content/repositories/snapshots/") maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") maven("https://maven.neoforged.net/releases") + maven("https://prmaven.neoforged.net/NeoForge/pr1076") { + name = "Maven for 1.21 PR" + content { + includeModule("net.neoforged", "neoforge") + } + } } modrinth { diff --git a/gradle.properties b/gradle.properties index ea473906a..a222b1d99 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,5 +7,5 @@ org.gradle.vfs.watch=false group=org.geysermc id=geyser -version=2.3.2-SNAPSHOT +version=2.4.0-SNAPSHOT description=Allows for players from Minecraft: Bedrock Edition to join Minecraft: Java Edition servers. diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index afd001220..11851a5cd 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -28,11 +28,11 @@ commodore = "2.2" bungeecord = "a7c6ede" velocity = "3.3.0-SNAPSHOT" viaproxy = "3.2.1" -fabric-minecraft = "1.20.5" -fabric-loader = "0.15.10" -fabric-api = "0.97.6+1.20.5" +fabric-minecraft = "1.21-rc1" +fabric-loader = "0.15.11" +fabric-api = "0.100.1+1.21" fabric-permissions = "0.2-SNAPSHOT" -neoforge-minecraft = "20.5.0-beta" +neoforge-minecraft = "21.0.0-alpha.1.21-rc1.20240611.001314" mixin = "0.8.5" # plugin versions From ecffb564ed568babe1e73af2f7b3c806a2f3f49b Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Wed, 12 Jun 2024 20:34:42 -0400 Subject: [PATCH 238/272] Refactor static recipe loading The only recipes added should be the ones that are sent on Bedrock, so it appears in the recipe book. Every other recipe will be handled through our fallback system. --- .../geyser/inventory/recipe/GeyserRecipe.java | 6 + .../geysermc/geyser/item/type/BannerItem.java | 15 +- .../geyser/item/type/EnchantedBookItem.java | 16 +- .../geyser/item/type/FireworkRocketItem.java | 4 +- .../geyser/item/type/FireworkStarItem.java | 4 +- .../org/geysermc/geyser/item/type/Item.java | 37 +-- .../geysermc/geyser/registry/Registries.java | 13 +- .../registry/loader/RecipeRegistryLoader.java | 149 ++++++++++ .../populator/RecipeRegistryPopulator.java | 233 --------------- .../geyser/session/GeyserSession.java | 3 +- .../inventory/PlayerInventoryTranslator.java | 2 +- .../translator/item/ItemTranslator.java | 13 +- .../java/JavaUpdateRecipesTranslator.java | 270 +++++++++++------- core/src/main/resources/mappings | 2 +- 14 files changed, 360 insertions(+), 407 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/registry/loader/RecipeRegistryLoader.java delete mode 100644 core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java diff --git a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserRecipe.java b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserRecipe.java index 9d98e9fb3..8b7fa9522 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserRecipe.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/recipe/GeyserRecipe.java @@ -25,6 +25,9 @@ package org.geysermc.geyser.inventory.recipe; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; + /** * A more compact version of {@link org.geysermc.mcprotocollib.protocol.data.game.recipe.Recipe}. */ @@ -33,4 +36,7 @@ public interface GeyserRecipe { * Whether the recipe is flexible or not in which items can be placed where. */ boolean isShaped(); + + @Nullable + ItemStack result(); } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index cf0105622..4af2b4630 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -60,9 +60,6 @@ public class BannerItem extends BlockItem { */ private static final List> OMINOUS_BANNER_PATTERN; - // TODO fix - we somehow need to be able to get the sessions banner pattern registry, which we don't have where we need this :/ - private static final int[] ominousBannerPattern = new int[] { 21, 29, 30, 1, 34, 15, 3, 1 }; - static { // Construct what an ominous banner is supposed to look like OMINOUS_BANNER_PATTERN = List.of( @@ -215,20 +212,22 @@ public class BannerItem extends BlockItem { } @Override - public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) { - super.translateNbtToJava(bedrockTag, components, mapping); + public void translateNbtToJava(@NonNull GeyserSession session, @NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) { + super.translateNbtToJava(session, bedrockTag, components, mapping); if (bedrockTag.getInt("Type") == 1) { // Ominous banner pattern List patternLayers = new ArrayList<>(); - for (int i = 0; i < ominousBannerPattern.length; i++) { - patternLayers.add(new BannerPatternLayer(Holder.ofId(ominousBannerPattern[i]), OMINOUS_BANNER_PATTERN.get(i).right().ordinal())); + for (int i = 0; i < OMINOUS_BANNER_PATTERN.size(); i++) { + var pair = OMINOUS_BANNER_PATTERN.get(i); + patternLayers.add(new BannerPatternLayer(Holder.ofId(session.getRegistryCache().bannerPatterns().byValue(pair.left())), + pair.right().ordinal())); } components.put(DataComponentType.BANNER_PATTERNS, patternLayers); components.put(DataComponentType.HIDE_ADDITIONAL_TOOLTIP, Unit.INSTANCE); components.put(DataComponentType.ITEM_NAME, Component - .translatable("block.minecraft.ominous_banner") // thank god this works + .translatable("block.minecraft.ominous_banner") .style(Style.style(TextColor.color(16755200))) ); } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java b/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java index 540270555..8b0f3e22e 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/EnchantedBookItem.java @@ -32,6 +32,7 @@ import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.item.BedrockEnchantment; +import org.geysermc.geyser.item.enchantment.Enchantment; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; @@ -69,8 +70,8 @@ public class EnchantedBookItem extends Item { } @Override - public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) { - super.translateNbtToJava(bedrockTag, components, mapping); + public void translateNbtToJava(@NonNull GeyserSession session, @NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) { + super.translateNbtToJava(session, bedrockTag, components, mapping); List enchantmentTag = bedrockTag.getList("ench", NbtType.COMPOUND); if (enchantmentTag != null) { @@ -80,9 +81,14 @@ public class EnchantedBookItem extends Item { BedrockEnchantment enchantment = BedrockEnchantment.getByBedrockId(bedrockId); if (enchantment != null) { - int level = bedrockEnchantment.getShort("lvl", (short) 1); - // TODO - //javaEnchantments.put(BedrockEnchantment.JavaEnchantment.valueOf(enchantment.name()).ordinal(), level); + List enchantments = session.getRegistryCache().enchantments().values(); + for (int i = 0; i < enchantments.size(); i++) { + if (enchantments.get(i).bedrockEnchantment() == enchantment) { + int level = bedrockEnchantment.getShort("lvl", (short) 1); + javaEnchantments.put(i, level); + break; + } + } } else { GeyserImpl.getInstance().getLogger().debug("Unknown bedrock enchantment: " + bedrockId); } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java index c70467b4c..9c637afde 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkRocketItem.java @@ -70,8 +70,8 @@ public class FireworkRocketItem extends Item { } @Override - public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) { - super.translateNbtToJava(bedrockTag, components, mapping); + public void translateNbtToJava(@NonNull GeyserSession session, @NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) { + super.translateNbtToJava(session, bedrockTag, components, mapping); NbtMap fireworksTag = bedrockTag.getCompound("Fireworks"); if (!fireworksTag.isEmpty()) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java index 18234975d..2ba9b4258 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java @@ -78,8 +78,8 @@ public class FireworkStarItem extends Item { } @Override - public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) { - super.translateNbtToJava(bedrockTag, components, mapping); + public void translateNbtToJava(@NonNull GeyserSession session, @NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) { + super.translateNbtToJava(session, bedrockTag, components, mapping); NbtMap explosion = bedrockTag.getCompound("FireworksItem"); if (!explosion.isEmpty()) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/Item.java b/core/src/main/java/org/geysermc/geyser/item/type/Item.java index 2caa65dac..1ebf85065 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/Item.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/Item.java @@ -172,7 +172,7 @@ public class Item { * * Therefore, if translation cannot be achieved for a certain item, it is not necessarily bad. */ - public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) { + public void translateNbtToJava(@NonNull GeyserSession session, @NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) { // TODO see if any items from the creative menu need this // CompoundTag displayTag = tag.get("display"); // if (displayTag != null) { @@ -190,41 +190,6 @@ public class Item { // } // displayTag.put(new ListTag("Lore", lore)); // } -// } - - // TODO no creative item should have enchantments *except* enchanted books -// List enchantmentTag = bedrockTag.getList("ench", NbtType.COMPOUND); -// if (enchantmentTag != null) { -// List enchantments = new ArrayList<>(); -// for (Tag value : enchantmentTag.getValue()) { -// if (!(value instanceof CompoundTag tagValue)) -// continue; -// -// ShortTag bedrockId = tagValue.get("id"); -// if (bedrockId == null) continue; -// -// BedrockEnchantment enchantment = BedrockEnchantment.getByBedrockId(bedrockId.getValue()); -// if (enchantment != null) { -// CompoundTag javaTag = new CompoundTag(""); -// Map javaValue = javaTag.getValue(); -// javaValue.put("id", new StringTag("id", enchantment.getJavaIdentifier())); -// ShortTag levelTag = tagValue.get("lvl"); -// javaValue.put("lvl", new IntTag("lvl", levelTag != null ? levelTag.getValue() : 1)); -// javaTag.setValue(javaValue); -// -// enchantments.add(javaTag); -// } else { -// GeyserImpl.getInstance().getLogger().debug("Unknown bedrock enchantment: " + bedrockId); -// } -// } -// if (!enchantments.isEmpty()) { -// if ((this instanceof EnchantedBookItem)) { -// bedrockTag.put(new ListTag("StoredEnchantments", enchantments)); -// components.put(DataComponentType.STORED_ENCHANTMENTS, enchantments); -// } else { -// components.put(DataComponentType.ENCHANTMENTS, enchantments); -// } -// } // } } diff --git a/core/src/main/java/org/geysermc/geyser/registry/Registries.java b/core/src/main/java/org/geysermc/geyser/registry/Registries.java index 7815768ef..deafbdf7e 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/Registries.java +++ b/core/src/main/java/org/geysermc/geyser/registry/Registries.java @@ -25,14 +25,12 @@ package org.geysermc.geyser.registry; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.PotionMixData; -import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.RecipeData; import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.pack.ResourcePack; @@ -42,7 +40,7 @@ import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.registry.loader.*; import org.geysermc.geyser.registry.populator.ItemRegistryPopulator; import org.geysermc.geyser.registry.populator.PacketRegistryPopulator; -import org.geysermc.geyser.registry.populator.RecipeRegistryPopulator; +import org.geysermc.geyser.registry.loader.RecipeRegistryLoader; import org.geysermc.geyser.registry.provider.ProviderSupplier; import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.registry.type.ParticleMapping; @@ -95,11 +93,6 @@ public final class Registries { */ public static final SimpleMappedRegistry BLOCK_ENTITIES = SimpleMappedRegistry.create("org.geysermc.geyser.translator.level.block.entity.BlockEntity", BlockEntityRegistryLoader::new); - /** - * A versioned registry which holds a {@link RecipeType} to a corresponding list of {@link RecipeData}. - */ - public static final VersionedRegistry>> CRAFTING_DATA = VersionedRegistry.create(RegistryLoaders.empty(Int2ObjectOpenHashMap::new)); - /** * A map containing all entity types and their respective Geyser definitions */ @@ -147,7 +140,7 @@ public final class Registries { /** * A versioned registry holding all the recipes, with the net ID being the key, and {@link GeyserRecipe} as the value. */ - public static final VersionedRegistry> RECIPES = VersionedRegistry.create(RegistryLoaders.empty(Int2ObjectOpenHashMap::new)); + public static final SimpleMappedRegistry> RECIPES = SimpleMappedRegistry.create("mappings/recipes.nbt", RecipeRegistryLoader::new); /** * A mapped registry holding {@link ResourcePack}'s with the pack uuid as keys. @@ -176,7 +169,7 @@ public final class Registries { static { PacketRegistryPopulator.populate(); ItemRegistryPopulator.populate(); - RecipeRegistryPopulator.populate(); + System.out.println(RECIPES.get()); // Create registries that require other registries to load first POTION_MIXES = VersionedRegistry.create(PotionMixRegistryLoader::new); diff --git a/core/src/main/java/org/geysermc/geyser/registry/loader/RecipeRegistryLoader.java b/core/src/main/java/org/geysermc/geyser/registry/loader/RecipeRegistryLoader.java new file mode 100644 index 000000000..5d1236581 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/registry/loader/RecipeRegistryLoader.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.registry.loader; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import it.unimi.dsi.fastutil.Pair; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.cloudburstmc.nbt.NBTInputStream; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtType; +import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.inventory.recipe.GeyserRecipe; +import org.geysermc.geyser.inventory.recipe.GeyserShapedRecipe; +import org.geysermc.geyser.inventory.recipe.GeyserShapelessRecipe; +import org.geysermc.geyser.text.GeyserLocale; +import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodec; +import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodecHelper; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.Ingredient; +import org.geysermc.mcprotocollib.protocol.data.game.recipe.RecipeType; + +import java.io.DataInputStream; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Base64; +import java.util.List; +import java.util.Map; + +/** + * Populates the recipe registry with some recipes that Java does not send, to ensure they show up as intended + * in the recipe book. + */ +public final class RecipeRegistryLoader implements RegistryLoader>> { + + @Override + public Map> load(String input) { + Map> deserializedRecipes = new Object2ObjectOpenHashMap<>(); + + List recipes; + try (InputStream stream = GeyserImpl.getInstance().getBootstrap().getResourceOrThrow("mappings/recipes.nbt")) { + try (NBTInputStream nbtStream = new NBTInputStream(new DataInputStream(stream))) { + recipes = ((NbtMap) nbtStream.readTag()).getList("recipes", NbtType.COMPOUND); + } + } catch (Exception e) { + throw new AssertionError(GeyserLocale.getLocaleStringLog("geyser.toolbox.fail.runtime_java"), e); + } + + MinecraftCodecHelper helper = MinecraftCodec.CODEC.getHelperFactory().get(); + for (NbtMap recipeCollection : recipes) { + var pair = getRecipes(recipeCollection, helper); + deserializedRecipes.put(pair.key(), pair.value()); + } + return deserializedRecipes; + } + + private static Pair> getRecipes(NbtMap recipes, MinecraftCodecHelper helper) { + List typedRecipes = recipes.getList("recipes", NbtType.COMPOUND); + RecipeType recipeType = RecipeType.from(recipes.getInt("recipe_type", -1)); + if (recipeType == RecipeType.CRAFTING_SPECIAL_TIPPEDARROW) { + return Pair.of(recipeType, getShapedRecipes(typedRecipes, helper)); + } else { + return Pair.of(recipeType, getShapelessRecipes(typedRecipes, helper)); + } + } + + private static List getShapelessRecipes(List recipes, MinecraftCodecHelper helper) { + List deserializedRecipes = new ObjectArrayList<>(recipes.size()); + for (NbtMap recipe : recipes) { + ItemStack output = toItemStack(recipe.getCompound("output"), helper); + List rawInputs = recipe.getList("inputs", NbtType.COMPOUND); + Ingredient[] javaInputs = new Ingredient[rawInputs.size()]; + for (int i = 0; i < rawInputs.size(); i++) { + javaInputs[i] = new Ingredient(new ItemStack[] {toItemStack(rawInputs.get(i), helper)}); + } + deserializedRecipes.add(new GeyserShapelessRecipe(javaInputs, output)); + } + return deserializedRecipes; + } + + private static List getShapedRecipes(List recipes, MinecraftCodecHelper helper) { + List deserializedRecipes = new ObjectArrayList<>(recipes.size()); + for (NbtMap recipe : recipes) { + ItemStack output = toItemStack(recipe.getCompound("output"), helper); + List shape = recipe.getList("shape", NbtType.INT_ARRAY); + + // In the recipes mapping, each recipe is mapped by a number + List letterToRecipe = new ArrayList<>(); + for (NbtMap rawInput : recipe.getList("inputs", NbtType.COMPOUND)) { + letterToRecipe.add(toItemStack(rawInput, helper)); + } + + Ingredient[] inputs = new Ingredient[shape.size() * shape.get(0).length]; + int i = 0; + // Create a linear array of items from the "cube" of the shape + for (int j = 0; i < shape.size() * shape.get(0).length; j++) { + for (int index : shape.get(j)) { + ItemStack stack = letterToRecipe.get(index); + inputs[i++] = new Ingredient(new ItemStack[] {stack}); + } + } + deserializedRecipes.add(new GeyserShapedRecipe(shape.size(), shape.get(0).length, inputs, output)); + } + return deserializedRecipes; + } + + /** + * Converts our serialized NBT into an ItemStack. + * id is the Java item ID as an integer, components is an optional String of the data components serialized + * as bytes in Base64 (so MCProtocolLib can parse the data). + */ + private static ItemStack toItemStack(NbtMap nbt, MinecraftCodecHelper helper) { + int id = nbt.getInt("id"); + int count = nbt.getInt("count"); + String componentsRaw = nbt.getString("components", null); + if (componentsRaw != null) { + byte[] bytes = Base64.getDecoder().decode(componentsRaw); + ByteBuf buf = Unpooled.wrappedBuffer(bytes); + DataComponents components = helper.readDataComponentPatch(buf); + return new ItemStack(id, count, components); + } + return new ItemStack(id, count); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java deleted file mode 100644 index 4c6d53518..000000000 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/RecipeRegistryPopulator.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.geyser.registry.populator; - -import com.fasterxml.jackson.databind.JsonNode; -import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; -import org.geysermc.mcprotocollib.protocol.data.game.recipe.Ingredient; -import org.geysermc.mcprotocollib.protocol.data.game.recipe.RecipeType; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -import it.unimi.dsi.fastutil.objects.ObjectArrayList; -import org.cloudburstmc.nbt.NbtMap; -import org.cloudburstmc.nbt.NbtUtils; -import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; -import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.RecipeUnlockingRequirement; -import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.MultiRecipeData; -import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.RecipeData; -import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapedRecipeData; -import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapelessRecipeData; -import org.cloudburstmc.protocol.bedrock.data.inventory.descriptor.ItemDescriptorWithCount; -import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.inventory.recipe.GeyserRecipe; -import org.geysermc.geyser.inventory.recipe.GeyserShapedRecipe; -import org.geysermc.geyser.inventory.recipe.GeyserShapelessRecipe; -import org.geysermc.geyser.registry.Registries; -import org.geysermc.geyser.registry.type.ItemMapping; -import org.geysermc.geyser.registry.type.ItemMappings; -import org.geysermc.geyser.text.GeyserLocale; -import org.geysermc.geyser.translator.item.ItemTranslator; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.*; - -import static org.geysermc.geyser.util.InventoryUtils.LAST_RECIPE_NET_ID; - -/** - * Populates the recipe registry. - */ -public class RecipeRegistryPopulator { - - public static void populate() { - JsonNode items; - try (InputStream stream = GeyserImpl.getInstance().getBootstrap().getResourceOrThrow("mappings/recipes.json")) { - items = GeyserImpl.JSON_MAPPER.readTree(stream); - } catch (Exception e) { - throw new AssertionError(GeyserLocale.getLocaleStringLog("geyser.toolbox.fail.runtime_java"), e); - } - - int currentRecipeId = LAST_RECIPE_NET_ID; - for (Int2ObjectMap.Entry version : Registries.ITEMS.get().int2ObjectEntrySet()) { - // Make a bit of an assumption here that the last recipe net ID will be equivalent between all versions - LAST_RECIPE_NET_ID = currentRecipeId; - Map> craftingData = new EnumMap<>(RecipeType.class); - Int2ObjectMap recipes = new Int2ObjectOpenHashMap<>(); - - craftingData.put(RecipeType.CRAFTING_SPECIAL_BOOKCLONING, - Collections.singletonList(MultiRecipeData.of(UUID.fromString("d1ca6b84-338e-4f2f-9c6b-76cc8b4bd98d"), ++LAST_RECIPE_NET_ID))); - craftingData.put(RecipeType.CRAFTING_SPECIAL_REPAIRITEM, - Collections.singletonList(MultiRecipeData.of(UUID.fromString("00000000-0000-0000-0000-000000000001"), ++LAST_RECIPE_NET_ID))); - craftingData.put(RecipeType.CRAFTING_SPECIAL_MAPEXTENDING, - Collections.singletonList(MultiRecipeData.of(UUID.fromString("d392b075-4ba1-40ae-8789-af868d56f6ce"), ++LAST_RECIPE_NET_ID))); - craftingData.put(RecipeType.CRAFTING_SPECIAL_MAPCLONING, - Collections.singletonList(MultiRecipeData.of(UUID.fromString("85939755-ba10-4d9d-a4cc-efb7a8e943c4"), ++LAST_RECIPE_NET_ID))); - - // https://github.com/pmmp/PocketMine-MP/blob/stable/src/pocketmine/inventory/MultiRecipe.php - - for (JsonNode entry : items.get("leather_armor")) { - // This won't be perfect, as we can't possibly send every leather input for every kind of color - // But it does display the correct output from a base leather armor, and besides visuals everything works fine - craftingData.computeIfAbsent(RecipeType.CRAFTING_SPECIAL_ARMORDYE, - c -> new ObjectArrayList<>()).add(getCraftingDataFromJsonNode(entry, recipes, version.getValue())); - } - for (JsonNode entry : items.get("firework_rockets")) { - craftingData.computeIfAbsent(RecipeType.CRAFTING_SPECIAL_FIREWORK_ROCKET, - c -> new ObjectArrayList<>()).add(getCraftingDataFromJsonNode(entry, recipes, version.getValue())); - } - for (JsonNode entry : items.get("firework_stars")) { - craftingData.computeIfAbsent(RecipeType.CRAFTING_SPECIAL_FIREWORK_STAR, - c -> new ObjectArrayList<>()).add(getCraftingDataFromJsonNode(entry, recipes, version.getValue())); - } - for (JsonNode entry : items.get("shulker_boxes")) { - craftingData.computeIfAbsent(RecipeType.CRAFTING_SPECIAL_SHULKERBOXCOLORING, - c -> new ObjectArrayList<>()).add(getCraftingDataFromJsonNode(entry, recipes, version.getValue())); - } - for (JsonNode entry : items.get("suspicious_stew")) { - craftingData.computeIfAbsent(RecipeType.CRAFTING_SPECIAL_SUSPICIOUSSTEW, - c -> new ObjectArrayList<>()).add(getCraftingDataFromJsonNode(entry, recipes, version.getValue())); - } - for (JsonNode entry : items.get("tipped_arrows")) { - craftingData.computeIfAbsent(RecipeType.CRAFTING_SPECIAL_TIPPEDARROW, - c -> new ObjectArrayList<>()).add(getCraftingDataFromJsonNode(entry, recipes, version.getValue())); - } - - Registries.CRAFTING_DATA.register(version.getIntKey(), craftingData); - Registries.RECIPES.register(version.getIntKey(), recipes); - } - } - - /** - * Computes a Bedrock crafting recipe from the given JSON data. - * @param node the JSON data to compute - * @param recipes a list of all the recipes - * @return the {@link RecipeData} to send to the Bedrock client. - */ - private static RecipeData getCraftingDataFromJsonNode(JsonNode node, Int2ObjectMap recipes, ItemMappings mappings) { - int netId = ++LAST_RECIPE_NET_ID; - int type = node.get("bedrockRecipeType").asInt(); - JsonNode outputNode = node.get("output"); - ItemMapping outputEntry = mappings.getMapping(outputNode.get("identifier").asText()); - ItemData output = getBedrockItemFromIdentifierJson(outputEntry, outputNode); - UUID uuid = UUID.randomUUID(); - if (type == 1) { - // Shaped recipe - List shape = new ArrayList<>(); - // Get the shape of the recipe - for (JsonNode chars : node.get("shape")) { - shape.add(chars.asText()); - } - - // In recipes.json each recipe is mapped by a letter - Map letterToRecipe = new HashMap<>(); - Iterator> iterator = node.get("inputs").fields(); - while (iterator.hasNext()) { - Map.Entry entry = iterator.next(); - JsonNode inputNode = entry.getValue(); - ItemMapping inputEntry = mappings.getMapping(inputNode.get("identifier").asText()); - letterToRecipe.put(entry.getKey(), getBedrockItemFromIdentifierJson(inputEntry, inputNode)); - } - - List inputs = new ArrayList<>(shape.size() * shape.get(0).length()); - int i = 0; - // Create a linear array of items from the "cube" of the shape - for (int j = 0; i < shape.size() * shape.get(0).length(); j++) { - for (char c : shape.get(j).toCharArray()) { - ItemData data = letterToRecipe.getOrDefault(String.valueOf(c), ItemData.AIR); - inputs.add(data); - i++; - } - } - - /* Convert into a Java recipe class for autocrafting */ - List ingredients = new ArrayList<>(); - for (ItemData input : inputs) { - ingredients.add(new Ingredient(new ItemStack[]{ItemTranslator.translateToJava(input, mappings)})); - } - GeyserRecipe recipe = new GeyserShapedRecipe(shape.get(0).length(), shape.size(), - ingredients.toArray(new Ingredient[0]), ItemTranslator.translateToJava(output, mappings)); - recipes.put(netId, recipe); - /* Convert end */ - - return ShapedRecipeData.shaped(uuid.toString(), shape.get(0).length(), shape.size(), - inputs.stream().map(ItemDescriptorWithCount::fromItem).toList(), Collections.singletonList(output), uuid, "crafting_table", 0, netId, false, RecipeUnlockingRequirement.INVALID); - } - List inputs = new ObjectArrayList<>(); - for (JsonNode entry : node.get("inputs")) { - ItemMapping inputEntry = mappings.getMapping(entry.get("identifier").asText()); - inputs.add(getBedrockItemFromIdentifierJson(inputEntry, entry)); - } - - /* Convert into a Java Recipe class for autocrafting */ - List ingredients = new ArrayList<>(); - for (ItemData input : inputs) { - ingredients.add(new Ingredient(new ItemStack[]{ItemTranslator.translateToJava(input, mappings)})); - } - GeyserRecipe recipe = new GeyserShapelessRecipe(ingredients.toArray(new Ingredient[0]), ItemTranslator.translateToJava(output, mappings)); - recipes.put(netId, recipe); - /* Convert end */ - - if (type == 5) { - // Shulker box - return ShapelessRecipeData.shulkerBox(uuid.toString(), - inputs.stream().map(ItemDescriptorWithCount::fromItem).toList(), Collections.singletonList(output), uuid, "crafting_table", 0, netId); - } - return ShapelessRecipeData.shapeless(uuid.toString(), - inputs.stream().map(ItemDescriptorWithCount::fromItem).toList(), Collections.singletonList(output), uuid, "crafting_table", 0, netId, RecipeUnlockingRequirement.INVALID); - } - - private static ItemData getBedrockItemFromIdentifierJson(ItemMapping mapping, JsonNode itemNode) { - int count = 1; - short damage = 0; - NbtMap tag = null; - JsonNode damageNode = itemNode.get("bedrockDamage"); - if (damageNode != null) { - damage = damageNode.numberValue().shortValue(); - } - JsonNode countNode = itemNode.get("count"); - if (countNode != null) { - count = countNode.asInt(); - } - JsonNode nbtNode = itemNode.get("bedrockNbt"); - if (nbtNode != null) { - byte[] bytes = Base64.getDecoder().decode(nbtNode.asText()); - ByteArrayInputStream bais = new ByteArrayInputStream(bytes); - try { - tag = (NbtMap) NbtUtils.createReaderLE(bais).readTag(); - } catch (IOException e) { - e.printStackTrace(); - } - } - return ItemData.builder() - .definition(mapping.getBedrockDefinition()) - .damage(damage) - .count(count) - .blockDefinition(mapping.getBedrockBlockDefinition()) - .tag(tag) - .build(); - } -} diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index ae5e1d338..836c77379 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -356,8 +356,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { * Stores all Java recipes by recipe identifier, and matches them to all possible Bedrock recipe identifiers. * They are not 1:1, since Bedrock can have multiple recipes for the same Java recipe. */ - @Setter - private Map> javaToBedrockRecipeIds; + private final Map> javaToBedrockRecipeIds; @Setter private Int2ObjectMap craftingRecipes; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java index 18d6a22eb..bc6ff2adf 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java @@ -423,7 +423,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator { } // Reference the creative items list we send to the client to know what it's asking of us ItemData creativeItem = creativeItems[creativeId]; - javaCreativeItem = ItemTranslator.translateToJava(creativeItem, session.getItemMappings()); + javaCreativeItem = ItemTranslator.translateToJava(session, creativeItem); break; } case CRAFT_RESULTS_DEPRECATED: { diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index 251aacba8..8b61e435a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -47,7 +47,6 @@ import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.CustomSkull; import org.geysermc.geyser.registry.type.ItemMapping; -import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.text.MinecraftLocale; @@ -83,25 +82,21 @@ public final class ItemTranslator { private ItemTranslator() { } - /** - * @param mappings item mappings to use while translating. This can't just be a Geyser session as this method is used - * when loading recipes. - */ - public static ItemStack translateToJava(ItemData data, ItemMappings mappings) { + public static ItemStack translateToJava(GeyserSession session, ItemData data) { if (data == null) { return new ItemStack(Items.AIR_ID); } - ItemMapping bedrockItem = mappings.getMapping(data); + ItemMapping bedrockItem = session.getItemMappings().getMapping(data); Item javaItem = bedrockItem.getJavaItem(); - GeyserItemStack itemStack = javaItem.translateToJava(data, bedrockItem, mappings); + GeyserItemStack itemStack = javaItem.translateToJava(data, bedrockItem, session.getItemMappings()); NbtMap nbt = data.getTag(); if (nbt != null && !nbt.isEmpty()) { // translateToJava may have added components DataComponents components = itemStack.getComponents() == null ? new DataComponents(new HashMap<>()) : itemStack.getComponents(); - javaItem.translateNbtToJava(nbt, components, bedrockItem); + javaItem.translateNbtToJava(session, nbt, components, bedrockItem); if (!components.getDataComponents().isEmpty()) { itemStack.setComponents(components); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java index 2a0c38221..886b31e09 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java @@ -103,66 +103,31 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator> recipeTypes = Registries.CRAFTING_DATA.forVersion(session.getUpstream().getProtocolVersion()); - // Get the last known network ID (first used for the pregenerated recipes) and increment from there. - int netId = InventoryUtils.LAST_RECIPE_NET_ID + 1; boolean sendTrimRecipes = false; Map> recipeIDs = session.getJavaToBedrockRecipeIds(); - Int2ObjectMap recipeMap = new Int2ObjectOpenHashMap<>(Registries.RECIPES.forVersion(session.getUpstream().getProtocolVersion())); + recipeIDs.clear(); + Int2ObjectMap recipeMap = new Int2ObjectOpenHashMap<>(); Int2ObjectMap> unsortedStonecutterData = new Int2ObjectOpenHashMap<>(); CraftingDataPacket craftingDataPacket = new CraftingDataPacket(); craftingDataPacket.setCleanRecipes(true); + RecipeContext context = new RecipeContext(session, craftingDataPacket, recipeMap); + for (Recipe recipe : packet.getRecipes()) { switch (recipe.getType()) { case CRAFTING_SHAPELESS -> { ShapelessRecipeData shapelessRecipeData = (ShapelessRecipeData) recipe.getData(); - ItemData output = ItemTranslator.translateToBedrock(session, shapelessRecipeData.getResult()); - if (!output.isValid()) { - // Likely modded item that Bedrock will complain about if it persists - continue; + List bedrockRecipeIDs = context.translateShapelessRecipe(new GeyserShapelessRecipe(shapelessRecipeData)); + if (bedrockRecipeIDs != null) { + context.addRecipeIdentifier(session, recipe.getIdentifier(), bedrockRecipeIDs); } - // Strip NBT - tools won't appear in the recipe book otherwise - output = output.toBuilder().tag(null).build(); - ItemDescriptorWithCount[][] inputCombinations = combinations(session, shapelessRecipeData.getIngredients()); - if (inputCombinations == null) { - continue; - } - - List bedrockRecipeIDs = new ArrayList<>(); - for (ItemDescriptorWithCount[] inputs : inputCombinations) { - UUID uuid = UUID.randomUUID(); - bedrockRecipeIDs.add(uuid.toString()); - craftingDataPacket.getCraftingData().add(org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapelessRecipeData.shapeless(uuid.toString(), - Arrays.asList(inputs), Collections.singletonList(output), uuid, "crafting_table", 0, netId, RecipeUnlockingRequirement.INVALID)); - recipeMap.put(netId++, new GeyserShapelessRecipe(shapelessRecipeData)); - } - addRecipeIdentifier(session, recipe.getIdentifier(), bedrockRecipeIDs); } case CRAFTING_SHAPED -> { ShapedRecipeData shapedRecipeData = (ShapedRecipeData) recipe.getData(); - ItemData output = ItemTranslator.translateToBedrock(session, shapedRecipeData.getResult()); - if (!output.isValid()) { - // Likely modded item that Bedrock will complain about if it persists - continue; + List bedrockRecipeIDs = context.translateShapedRecipe(new GeyserShapedRecipe(shapedRecipeData)); + if (bedrockRecipeIDs != null) { + context.addRecipeIdentifier(session, recipe.getIdentifier(), bedrockRecipeIDs); } - // See above - output = output.toBuilder().tag(null).build(); - ItemDescriptorWithCount[][] inputCombinations = combinations(session, shapedRecipeData.getIngredients()); - if (inputCombinations == null) { - continue; - } - - List bedrockRecipeIDs = new ArrayList<>(); - for (ItemDescriptorWithCount[] inputs : inputCombinations) { - UUID uuid = UUID.randomUUID(); - bedrockRecipeIDs.add(uuid.toString()); - craftingDataPacket.getCraftingData().add(org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapedRecipeData.shaped(uuid.toString(), - shapedRecipeData.getWidth(), shapedRecipeData.getHeight(), Arrays.asList(inputs), - Collections.singletonList(output), uuid, "crafting_table", 0, netId, false, RecipeUnlockingRequirement.INVALID)); - recipeMap.put(netId++, new GeyserShapedRecipe(shapedRecipeData)); - } - addRecipeIdentifier(session, recipe.getIdentifier(), bedrockRecipeIDs); } case STONECUTTING -> { StoneCuttingRecipeData stoneCuttingData = (StoneCuttingRecipeData) recipe.getData(); @@ -198,7 +163,7 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator(Collections.singletonList(id))); } @@ -212,13 +177,48 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator { // Paper 1.20 seems to send only one recipe, which seems to be hardcoded to include all recipes. // We can send the equivalent Bedrock MultiRecipe! :) - craftingDataPacket.getCraftingData().add(MultiRecipeData.of(UUID.fromString("685a742a-c42e-4a4e-88ea-5eb83fc98e5b"), netId++)); + craftingDataPacket.getCraftingData().add(MultiRecipeData.of(UUID.fromString("685a742a-c42e-4a4e-88ea-5eb83fc98e5b"), context.getAndIncrementNetId())); + } + case CRAFTING_SPECIAL_BOOKCLONING -> { + craftingDataPacket.getCraftingData().add(MultiRecipeData.of(UUID.fromString("d1ca6b84-338e-4f2f-9c6b-76cc8b4bd98d"), context.getAndIncrementNetId())); + } + case CRAFTING_SPECIAL_REPAIRITEM -> { + craftingDataPacket.getCraftingData().add(MultiRecipeData.of(UUID.fromString("00000000-0000-0000-0000-000000000001"), context.getAndIncrementNetId())); + } + case CRAFTING_SPECIAL_MAPEXTENDING -> { + craftingDataPacket.getCraftingData().add(MultiRecipeData.of(UUID.fromString("d392b075-4ba1-40ae-8789-af868d56f6ce"), context.getAndIncrementNetId())); + } + case CRAFTING_SPECIAL_MAPCLONING -> { + craftingDataPacket.getCraftingData().add(MultiRecipeData.of(UUID.fromString("85939755-ba10-4d9d-a4cc-efb7a8e943c4"), context.getAndIncrementNetId())); } default -> { - List craftingData = recipeTypes.get(recipe.getType()); - if (craftingData != null) { - addSpecialRecipesIdentifiers(session, recipe, craftingData); - craftingDataPacket.getCraftingData().addAll(craftingData); + List recipes = Registries.RECIPES.get(recipe.getType()); + if (recipes != null) { + List bedrockRecipeIds = new ArrayList<>(); + if (recipe.getType() == RecipeType.CRAFTING_SPECIAL_TIPPEDARROW) { + // Only shaped recipe at this moment + for (GeyserRecipe builtInRecipe : recipes) { + var recipeIds = context.translateShapedRecipe((GeyserShapedRecipe) builtInRecipe); + if (recipeIds != null) { + bedrockRecipeIds.addAll(recipeIds); + } + } + } else if (recipe.getType() == RecipeType.CRAFTING_SPECIAL_SHULKERBOXCOLORING) { + for (GeyserRecipe builtInRecipe : recipes) { + var recipeIds = context.translateShulkerBoxRecipe((GeyserShapelessRecipe) builtInRecipe); + if (recipeIds != null) { + bedrockRecipeIds.addAll(recipeIds); + } + } + } else { + for (GeyserRecipe builtInRecipe : recipes) { + var recipeIds = context.translateShapelessRecipe((GeyserShapelessRecipe) builtInRecipe); + if (recipeIds != null) { + bedrockRecipeIds.addAll(recipeIds); + } + } + } + context.addSpecialRecipesIdentifiers(recipe, bedrockRecipeIds); } } } @@ -250,17 +250,17 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator craftingData) { - String javaRecipeID = recipe.getIdentifier(); - - switch (recipe.getType()) { - case CRAFTING_SPECIAL_BOOKCLONING, CRAFTING_SPECIAL_REPAIRITEM, CRAFTING_SPECIAL_MAPEXTENDING, CRAFTING_SPECIAL_MAPCLONING: - // We do not want to (un)lock these, since BDS does not do it for MultiRecipes - return; - case CRAFTING_SPECIAL_SHULKERBOXCOLORING: - // BDS (un)locks the dyeing with the shulker box recipe, Java never - we want BDS behavior for ease of use - javaRecipeID = "minecraft:shulker_box"; - break; - case CRAFTING_SPECIAL_TIPPEDARROW: - // similar as above - javaRecipeID = "minecraft:arrow"; - break; - } - List bedrockRecipeIDs = new ArrayList<>(); - - // defined in the recipes.json mappings file: Only tipped arrows use shaped recipes, we need the cast for the identifier - if (recipe.getType() == RecipeType.CRAFTING_SPECIAL_TIPPEDARROW) { - for (RecipeData data : craftingData) { - bedrockRecipeIDs.add(((org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapedRecipeData) data).getId()); - } - } else { - for (RecipeData data : craftingData) { - bedrockRecipeIDs.add(((org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapelessRecipeData) data).getId()); - } - } - addRecipeIdentifier(session, javaRecipeID, bedrockRecipeIDs); + System.out.println(craftingDataPacket); } //TODO: rewrite @@ -323,7 +292,7 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator, IntSet> squashedOptions = new HashMap<>(); for (int i = 0; i < ingredients.length; i++) { @@ -407,17 +376,6 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator bedrockIdentifiers) { - session.getJavaToBedrockRecipeIds().computeIfAbsent(javaIdentifier, k -> new ArrayList<>()).addAll(bedrockIdentifiers); - } - - @EqualsAndHashCode - @AllArgsConstructor - private static class GroupedItem { - ItemDefinition id; - int count; - } - private List getSmithingTransformRecipes(GeyserSession session) { List recipes = new ArrayList<>(); ItemMapping template = session.getItemMappings().getStoredItems().upgradeTemplate(); @@ -442,4 +400,120 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator recipeMap; + // Get the last known network ID (first used for some pregenerated recipes) and increment from there. + private int netId = InventoryUtils.LAST_RECIPE_NET_ID + 1; + + private RecipeContext(GeyserSession session, CraftingDataPacket packet, Int2ObjectMap recipeMap) { + this.session = session; + this.packet = packet; + this.recipeMap = recipeMap; + } + + List translateShulkerBoxRecipe(GeyserShapelessRecipe recipe) { + ItemData output = ItemTranslator.translateToBedrock(session, recipe.result()); + if (!output.isValid()) { + // Likely modded item that Bedrock will complain about if it persists + return null; + } + // Strip NBT - tools won't appear in the recipe book otherwise + output = output.toBuilder().tag(null).build(); + ItemDescriptorWithCount[][] inputCombinations = combinations(session, recipe.ingredients()); + if (inputCombinations == null) { + return null; + } + + List bedrockRecipeIDs = new ArrayList<>(); + for (ItemDescriptorWithCount[] inputs : inputCombinations) { + UUID uuid = UUID.randomUUID(); + bedrockRecipeIDs.add(uuid.toString()); + packet.getCraftingData().add(org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapelessRecipeData.shulkerBox(uuid.toString(), + Arrays.asList(inputs), Collections.singletonList(output), uuid, "crafting_table", 0, netId)); + recipeMap.put(netId++, recipe); + } + return bedrockRecipeIDs; + } + + List translateShapelessRecipe(GeyserShapelessRecipe recipe) { + ItemData output = ItemTranslator.translateToBedrock(session, recipe.result()); + if (!output.isValid()) { + // Likely modded item that Bedrock will complain about if it persists + return null; + } + // Strip NBT - tools won't appear in the recipe book otherwise + output = output.toBuilder().tag(null).build(); + ItemDescriptorWithCount[][] inputCombinations = combinations(session, recipe.ingredients()); + if (inputCombinations == null) { + return null; + } + + List bedrockRecipeIDs = new ArrayList<>(); + for (ItemDescriptorWithCount[] inputs : inputCombinations) { + UUID uuid = UUID.randomUUID(); + bedrockRecipeIDs.add(uuid.toString()); + packet.getCraftingData().add(org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapelessRecipeData.shapeless(uuid.toString(), + Arrays.asList(inputs), Collections.singletonList(output), uuid, "crafting_table", 0, netId, RecipeUnlockingRequirement.INVALID)); + recipeMap.put(netId++, recipe); + } + return bedrockRecipeIDs; + } + + List translateShapedRecipe(GeyserShapedRecipe recipe) { + ItemData output = ItemTranslator.translateToBedrock(session, recipe.result()); + if (!output.isValid()) { + // Likely modded item that Bedrock will complain about if it persists + return null; + } + // See above + output = output.toBuilder().tag(null).build(); + ItemDescriptorWithCount[][] inputCombinations = combinations(session, recipe.ingredients()); + if (inputCombinations == null) { + return null; + } + + List bedrockRecipeIDs = new ArrayList<>(); + for (ItemDescriptorWithCount[] inputs : inputCombinations) { + UUID uuid = UUID.randomUUID(); + bedrockRecipeIDs.add(uuid.toString()); + packet.getCraftingData().add(org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapedRecipeData.shaped(uuid.toString(), + recipe.width(), recipe.height(), Arrays.asList(inputs), + Collections.singletonList(output), uuid, "crafting_table", 0, netId, false, RecipeUnlockingRequirement.INVALID)); + recipeMap.put(netId++, recipe); + } + return bedrockRecipeIDs; + } + + void addSpecialRecipesIdentifiers(Recipe recipe, List identifiers) { + String javaRecipeID = switch (recipe.getType()) { + case CRAFTING_SPECIAL_SHULKERBOXCOLORING -> + // BDS (un)locks the dyeing with the shulker box recipe, Java never - we want BDS behavior for ease of use + "minecraft:shulker_box"; + case CRAFTING_SPECIAL_TIPPEDARROW -> + // similar as above + "minecraft:arrow"; + default -> recipe.getIdentifier(); + }; + + addRecipeIdentifier(session, javaRecipeID, identifiers); + } + + void addRecipeIdentifier(GeyserSession session, String javaIdentifier, List bedrockIdentifiers) { + session.getJavaToBedrockRecipeIds().computeIfAbsent(javaIdentifier, k -> new ArrayList<>()).addAll(bedrockIdentifiers); + } + + int getAndIncrementNetId() { + return this.netId++; + } + } } diff --git a/core/src/main/resources/mappings b/core/src/main/resources/mappings index 54705bcd2..8795baeb1 160000 --- a/core/src/main/resources/mappings +++ b/core/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 54705bcd2bcba830267efbb1fbfd4e52972c40f7 +Subproject commit 8795baeb170f7c9832da2def8625f0c5702abd91 From 2ecc4cd841e9902cb0b2ff3128b4d6592b41fb30 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Wed, 12 Jun 2024 20:42:29 -0400 Subject: [PATCH 239/272] Point to right mappings --- core/src/main/resources/mappings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/resources/mappings b/core/src/main/resources/mappings index 8795baeb1..396ea5ff5 160000 --- a/core/src/main/resources/mappings +++ b/core/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 8795baeb170f7c9832da2def8625f0c5702abd91 +Subproject commit 396ea5ff50d8c976fde4e7423e682d21aa0ee350 From 82d0a87020aa9e5621f4d78fbda5a9bb4b0863a0 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Wed, 12 Jun 2024 20:45:47 -0400 Subject: [PATCH 240/272] Remove debug code --- core/src/main/java/org/geysermc/geyser/registry/Registries.java | 1 - .../translator/protocol/java/JavaUpdateRecipesTranslator.java | 1 - 2 files changed, 2 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/registry/Registries.java b/core/src/main/java/org/geysermc/geyser/registry/Registries.java index deafbdf7e..30d3c0763 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/Registries.java +++ b/core/src/main/java/org/geysermc/geyser/registry/Registries.java @@ -169,7 +169,6 @@ public final class Registries { static { PacketRegistryPopulator.populate(); ItemRegistryPopulator.populate(); - System.out.println(RECIPES.get()); // Create registries that require other registries to load first POTION_MIXES = VersionedRegistry.create(PotionMixRegistryLoader::new); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java index 886b31e09..4d207153b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java @@ -282,7 +282,6 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator Date: Wed, 12 Jun 2024 20:56:06 -0400 Subject: [PATCH 241/272] Fix some water plants not being waterlogged --- .../geyser/registry/populator/BlockRegistryPopulator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java index a8fb0001d..272522429 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java @@ -290,7 +290,8 @@ public final class BlockRegistryPopulator { } boolean waterlogged = blockState.getValue(Properties.WATERLOGGED, false) - || block == Blocks.BUBBLE_COLUMN || block == Blocks.KELP || block == Blocks.SEAGRASS; + || block == Blocks.BUBBLE_COLUMN || block == Blocks.KELP || block == Blocks.KELP_PLANT + || block == Blocks.SEAGRASS || block == Blocks.TALL_SEAGRASS; if (waterlogged) { BlockRegistries.WATERLOGGED.get().set(javaRuntimeId); From 52a93ecc187cd1fdc2bcc0ab66d6c86734ccbbaa Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Wed, 12 Jun 2024 22:16:14 -0400 Subject: [PATCH 242/272] Implement breeze --- .../java/org/geysermc/geyser/entity/EntityDefinitions.java | 5 +++++ .../geyser/entity/type/living/monster/BreezeEntity.java | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index a7c2d6ca6..1496f8a82 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -66,6 +66,7 @@ public final class EntityDefinitions { public static final EntityDefinition BLAZE; public static final EntityDefinition BOAT; public static final EntityDefinition BOGGED; + public static final EntityDefinition BREEZE; public static final EntityDefinition BREEZE_WIND_CHARGE; public static final EntityDefinition CAMEL; public static final EntityDefinition CAT; @@ -530,6 +531,10 @@ public final class EntityDefinitions { .height(1.8f).width(0.6f) .addTranslator(MetadataType.BYTE, BlazeEntity::setBlazeFlags) .build(); + BREEZE = EntityDefinition.inherited(BreezeEntity::new, mobEntityBase) + .type(EntityType.BREEZE) + .height(1.77f).width(0.6f) + .build(); CREEPER = EntityDefinition.inherited(CreeperEntity::new, mobEntityBase) .type(EntityType.CREEPER) .height(1.7f).width(0.6f) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BreezeEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BreezeEntity.java index 25d466aaf..251a77fb9 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BreezeEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BreezeEntity.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.entity.type.living.monster; import org.cloudburstmc.math.vector.Vector3f; +import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; @@ -39,6 +40,9 @@ public class BreezeEntity extends MonsterEntity { @Override public void setPose(Pose pose) { + // TODO Test + setFlag(EntityFlag.FACING_TARGET_TO_RANGE_ATTACK, pose == Pose.SHOOTING); + setFlag(EntityFlag.JUMP_GOAL_JUMP, pose == Pose.INHALING); super.setPose(pose); } } From 3528b1d692b8c19cf8bca187dbc086647f5399ed Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Wed, 12 Jun 2024 22:47:47 -0400 Subject: [PATCH 243/272] Allow recipes to default count as 1 --- .../geysermc/geyser/registry/loader/RecipeRegistryLoader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/registry/loader/RecipeRegistryLoader.java b/core/src/main/java/org/geysermc/geyser/registry/loader/RecipeRegistryLoader.java index 5d1236581..f1d0c456f 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/loader/RecipeRegistryLoader.java +++ b/core/src/main/java/org/geysermc/geyser/registry/loader/RecipeRegistryLoader.java @@ -136,7 +136,7 @@ public final class RecipeRegistryLoader implements RegistryLoader Date: Wed, 12 Jun 2024 23:48:40 -0400 Subject: [PATCH 244/272] Update to latest MCProtocolLib --- .../type/player/SessionPlayerEntity.java | 2 +- .../geyser/inventory/item/BannerPattern.java | 10 +++-- .../geyser/inventory/recipe/TrimRecipe.java | 17 +------- .../geyser/item/enchantment/Enchantment.java | 7 ++-- .../geysermc/geyser/item/type/BannerItem.java | 7 ++-- .../org/geysermc/geyser/item/type/Item.java | 4 +- .../geysermc/geyser/level/PaintingType.java | 8 +++- .../mappings/versions/MappingsReader_v1.java | 20 ++-------- .../geyser/session/GeyserSession.java | 3 +- .../geyser/session/cache/LodestoneCache.java | 9 +++-- .../geyser/session/cache/RegistryCache.java | 16 ++++---- .../geyser/session/cache/TagCache.java | 14 ++++--- .../geyser/session/cache/tags/BlockTag.java | 5 ++- .../session/cache/tags/EnchantmentTag.java | 6 ++- .../geyser/session/cache/tags/ItemTag.java | 6 ++- .../translator/level/BiomeTranslator.java | 2 +- .../BedrockBlockEntityDataTranslator.java | 4 +- ...tionTrackingDBClientRequestTranslator.java | 2 +- .../JavaClientboundRecipesTranslator.java | 1 + .../protocol/java/JavaCommandsTranslator.java | 15 +++---- .../java/JavaCustomPayloadTranslator.java | 4 +- .../java/JavaGameProfileTranslator.java | 3 +- .../protocol/java/JavaLoginTranslator.java | 10 +++-- .../java/JavaUpdateRecipesTranslator.java | 8 ++-- .../player/JavaStoreCookieTranslator.java | 2 +- .../java/level/JavaStopSoundTranslator.java | 2 +- .../geysermc/geyser/util/MinecraftKey.java | 39 +++++++++++++++++++ .../geyser/util/PluginMessageUtils.java | 3 +- gradle/libs.versions.toml | 2 +- 29 files changed, 135 insertions(+), 96 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/util/MinecraftKey.java diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java index ad6729c42..31eb02984 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java @@ -220,7 +220,7 @@ public class SessionPlayerEntity extends PlayerEntity { public void setLastDeathPosition(@Nullable GlobalPos pos) { if (pos != null) { dirtyMetadata.put(EntityDataTypes.PLAYER_LAST_DEATH_POS, pos.getPosition()); - dirtyMetadata.put(EntityDataTypes.PLAYER_LAST_DEATH_DIMENSION, DimensionUtils.javaToBedrock(pos.getDimension())); + dirtyMetadata.put(EntityDataTypes.PLAYER_LAST_DEATH_DIMENSION, DimensionUtils.javaToBedrock(pos.getDimension().asString())); dirtyMetadata.put(EntityDataTypes.PLAYER_HAS_DIED, true); } else { dirtyMetadata.put(EntityDataTypes.PLAYER_HAS_DIED, false); diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java b/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java index b6cc2c206..743fbdc7e 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/BannerPattern.java @@ -26,7 +26,9 @@ package org.geysermc.geyser.inventory.item; import lombok.Getter; +import net.kyori.adventure.key.Key; import org.checkerframework.checker.nullness.qual.Nullable; +import org.geysermc.geyser.util.MinecraftKey; import java.util.Locale; @@ -78,17 +80,17 @@ public enum BannerPattern { private static final BannerPattern[] VALUES = values(); - private final String javaIdentifier; + private final Key javaIdentifier; private final String bedrockIdentifier; BannerPattern(String bedrockIdentifier) { - this.javaIdentifier = "minecraft:" + this.name().toLowerCase(Locale.ROOT); + this.javaIdentifier = MinecraftKey.key(this.name().toLowerCase(Locale.ROOT)); this.bedrockIdentifier = bedrockIdentifier; } - public static @Nullable BannerPattern getByJavaIdentifier(String javaIdentifier) { + public static @Nullable BannerPattern getByJavaIdentifier(Key key) { for (BannerPattern bannerPattern : VALUES) { - if (bannerPattern.javaIdentifier.equals(javaIdentifier)) { + if (bannerPattern.javaIdentifier.equals(key)) { return bannerPattern; } } diff --git a/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java b/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java index 9d9dbe0db..8289813a4 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/recipe/TrimRecipe.java @@ -47,7 +47,7 @@ public final class TrimRecipe { public static final ItemDescriptorWithCount TEMPLATE = tagDescriptor("minecraft:trim_templates"); public static TrimMaterial readTrimMaterial(GeyserSession session, RegistryEntry entry) { - String key = stripMinecraftNamespace(entry.getId()); + String key = entry.getId().asMinimalString(); // Color is used when hovering over the item // Find the nearest legacy color from the RGB Java gives us to work with @@ -67,7 +67,7 @@ public final class TrimRecipe { } public static TrimPattern readTrimPattern(GeyserSession session, RegistryEntry entry) { - String key = stripMinecraftNamespace(entry.getId()); + String key = entry.getId().asMinimalString(); String itemIdentifier = entry.getData().getString("template_item"); ItemMapping itemMapping = session.getItemMappings().getMapping(itemIdentifier); @@ -78,19 +78,6 @@ public final class TrimRecipe { return new TrimPattern(itemMapping.getBedrockIdentifier(), key); } - // TODO find a good place for a stripNamespace util method - private static String stripMinecraftNamespace(String identifier) { - int i = identifier.indexOf(':'); - if (i >= 0) { - String namespace = identifier.substring(0, i); - // Only strip minecraft namespace - if (namespace.equals("minecraft")) { - return identifier.substring(i + 1); - } - } - return identifier; - } - private TrimRecipe() { //no-op } diff --git a/core/src/main/java/org/geysermc/geyser/item/enchantment/Enchantment.java b/core/src/main/java/org/geysermc/geyser/item/enchantment/Enchantment.java index 468b88e87..c5c0d2611 100644 --- a/core/src/main/java/org/geysermc/geyser/item/enchantment/Enchantment.java +++ b/core/src/main/java/org/geysermc/geyser/item/enchantment/Enchantment.java @@ -31,6 +31,7 @@ import org.geysermc.geyser.inventory.item.BedrockEnchantment; import org.geysermc.geyser.session.cache.tags.EnchantmentTag; import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.translator.text.MessageTranslator; +import org.geysermc.geyser.util.MinecraftKey; import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; import java.util.HashSet; @@ -59,11 +60,11 @@ public record Enchantment(String identifier, int maxLevel = data.getInt("max_level"); int anvilCost = data.getInt("anvil_cost"); String exclusiveSet = data.getString("exclusive_set", null); - EnchantmentTag exclusiveSetTag = exclusiveSet == null ? null : EnchantmentTag.ALL_ENCHANTMENT_TAGS.get(exclusiveSet.substring(1)); - BedrockEnchantment bedrockEnchantment = BedrockEnchantment.getByJavaIdentifier(entry.getId()); + EnchantmentTag exclusiveSetTag = exclusiveSet == null ? null : EnchantmentTag.ALL_ENCHANTMENT_TAGS.get(MinecraftKey.key(exclusiveSet.substring(1))); + BedrockEnchantment bedrockEnchantment = BedrockEnchantment.getByJavaIdentifier(entry.getId().asString()); String description = bedrockEnchantment == null ? MessageTranslator.deserializeDescription(data) : null; - return new Enchantment(entry.getId(), effects, ItemTag.ALL_ITEM_TAGS.get(supportedItems), maxLevel, + return new Enchantment(entry.getId().asString(), effects, ItemTag.ALL_ITEM_TAGS.get(MinecraftKey.key(supportedItems)), maxLevel, description, anvilCost, exclusiveSetTag, bedrockEnchantment); } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java index 4af2b4630..6ec0da8ed 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/BannerItem.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.item.type; import it.unimi.dsi.fastutil.Pair; +import net.kyori.adventure.key.Key; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.TextColor; @@ -40,8 +41,8 @@ import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.registry.JavaRegistry; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.geyser.util.MinecraftKey; import org.geysermc.mcprotocollib.protocol.data.game.Holder; -import org.geysermc.mcprotocollib.protocol.data.game.Identifier; import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; @@ -106,7 +107,7 @@ public class BannerItem extends BlockItem { if (color != pair.right()) { return false; } - String id = Identifier.formalize(patternLayer.getString("pattern")); // Ouch + Key id = MinecraftKey.key(patternLayer.getString("pattern")); // Ouch BannerPattern bannerPattern = BannerPattern.getByJavaIdentifier(id); if (bannerPattern != pair.left()) { return false; @@ -166,7 +167,7 @@ public class BannerItem extends BlockItem { */ private static NbtMap getBedrockBannerPattern(NbtMap pattern) { // ViaVersion 1.20.4 -> 1.20.5 can send without the namespace - BannerPattern bannerPattern = BannerPattern.getByJavaIdentifier(Identifier.formalize(pattern.getString("pattern"))); + BannerPattern bannerPattern = BannerPattern.getByJavaIdentifier(MinecraftKey.key(pattern.getString("pattern"))); DyeColor dyeColor = DyeColor.getByJavaIdentifier(pattern.getString("color")); if (bannerPattern == null || dyeColor == null) { return null; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/Item.java b/core/src/main/java/org/geysermc/geyser/item/type/Item.java index 1ebf85065..3014e8116 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/Item.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/Item.java @@ -45,7 +45,7 @@ import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.text.MessageTranslator; -import org.geysermc.mcprotocollib.protocol.data.game.Identifier; +import org.geysermc.geyser.util.MinecraftKey; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DyedItemColor; @@ -65,7 +65,7 @@ public class Item { private final int maxDamage; public Item(String javaIdentifier, Builder builder) { - this.javaIdentifier = Identifier.formalize(javaIdentifier).intern(); + this.javaIdentifier = MinecraftKey.key(javaIdentifier).asString().intern(); this.stackSize = builder.stackSize; this.maxDamage = builder.maxDamage; this.attackDamage = builder.attackDamage; diff --git a/core/src/main/java/org/geysermc/geyser/level/PaintingType.java b/core/src/main/java/org/geysermc/geyser/level/PaintingType.java index de35d97f1..f829b481c 100644 --- a/core/src/main/java/org/geysermc/geyser/level/PaintingType.java +++ b/core/src/main/java/org/geysermc/geyser/level/PaintingType.java @@ -28,6 +28,7 @@ package org.geysermc.geyser.level; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; +import net.kyori.adventure.key.Key; import java.util.Locale; @@ -90,9 +91,12 @@ public enum PaintingType { private final int width; private final int height; - public static PaintingType getByName(String javaName) { + public static PaintingType getByName(Key key) { + if (!key.namespace().equals("minecraft")) { + return null; + } for (PaintingType paintingName : VALUES) { - if (("minecraft:" + paintingName.name().toLowerCase(Locale.ROOT)).equals(javaName)) return paintingName; + if (paintingName.name().toLowerCase(Locale.ROOT).equals(key.value())) return paintingName; } return null; } diff --git a/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java b/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java index d32d5bc09..b5e25a4ba 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java +++ b/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java @@ -27,7 +27,6 @@ package org.geysermc.geyser.registry.mappings.versions; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; -import org.geysermc.mcprotocollib.protocol.data.game.Identifier; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import org.checkerframework.checker.nullness.qual.Nullable; @@ -35,14 +34,9 @@ import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.block.custom.CustomBlockData; import org.geysermc.geyser.api.block.custom.CustomBlockPermutation; import org.geysermc.geyser.api.block.custom.CustomBlockState; -import org.geysermc.geyser.api.block.custom.component.BoxComponent; -import org.geysermc.geyser.api.block.custom.component.CustomBlockComponents; -import org.geysermc.geyser.api.block.custom.component.GeometryComponent; -import org.geysermc.geyser.api.block.custom.component.MaterialInstance; -import org.geysermc.geyser.api.block.custom.component.PlacementConditions; +import org.geysermc.geyser.api.block.custom.component.*; import org.geysermc.geyser.api.block.custom.component.PlacementConditions.BlockFilterType; import org.geysermc.geyser.api.block.custom.component.PlacementConditions.Face; -import org.geysermc.geyser.api.block.custom.component.TransformationComponent; import org.geysermc.geyser.api.item.custom.CustomItemData; import org.geysermc.geyser.api.item.custom.CustomItemOptions; import org.geysermc.geyser.api.util.CreativeCategory; @@ -60,16 +54,10 @@ import org.geysermc.geyser.registry.mappings.util.CustomBlockStateMapping; import org.geysermc.geyser.translator.collision.BlockCollision; import org.geysermc.geyser.util.BlockUtils; import org.geysermc.geyser.util.MathUtils; +import org.geysermc.geyser.util.MinecraftKey; import java.nio.file.Path; -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.function.BiConsumer; import java.util.function.Function; import java.util.function.Predicate; @@ -131,7 +119,7 @@ public class MappingsReader_v1 extends MappingsReader { blocksNode.fields().forEachRemaining(entry -> { if (entry.getValue().isObject()) { try { - String identifier = Identifier.formalize(entry.getKey()); + String identifier = MinecraftKey.key(entry.getKey()).asString(); CustomBlockMapping customBlockMapping = this.readBlockMappingEntry(identifier, entry.getValue()); consumer.accept(identifier, customBlockMapping); } catch (Exception e) { diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 836c77379..e228fc02f 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -40,6 +40,7 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors; +import net.kyori.adventure.key.Key; import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.checker.nullness.qual.NonNull; @@ -290,7 +291,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { * Keeps track of the world name for respawning. */ @Setter - private String worldName = null; + private Key worldName = null; /** * As of Java 1.19.3, the client only uses these for commands. */ diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java index f66daf027..ee8ebb13f 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java @@ -27,6 +27,7 @@ package org.geysermc.geyser.session.cache; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import net.kyori.adventure.key.Key; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.GlobalPos; @@ -64,7 +65,7 @@ public final class LodestoneCache { int x = position.getX(); int y = position.getY(); int z = position.getZ(); - String dim = position.getDimension(); + Key dim = position.getDimension(); for (LodestonePos pos : this.activeLodestones.values()) { if (pos.equals(x, y, z, dim)) { @@ -98,7 +99,7 @@ public final class LodestoneCache { int x = position.getX(); int y = position.getY(); int z = position.getZ(); - String dim = position.getDimension(); + Key dim = position.getDimension(); for (LodestonePos pos : this.activeLodestones.values()) { if (pos.equals(x, y, z, dim)) { @@ -138,8 +139,8 @@ public final class LodestoneCache { this.lodestones.clear(); } - public record LodestonePos(int id, int x, int y, int z, String dimension) { - boolean equals(int x, int y, int z, String dimension) { + public record LodestonePos(int id, int x, int y, int z, Key dimension) { + boolean equals(int x, int y, int z, Key dimension) { return this.x == x && this.y == y && this.z == z && this.dimension.equals(dimension); } } diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java index 266a0a418..02c43939d 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java @@ -30,6 +30,7 @@ import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import lombok.AccessLevel; import lombok.Getter; import lombok.experimental.Accessors; +import net.kyori.adventure.key.Key; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.data.TrimMaterial; @@ -47,6 +48,7 @@ import org.geysermc.geyser.session.cache.registry.JavaRegistry; import org.geysermc.geyser.session.cache.registry.SimpleJavaRegistry; import org.geysermc.geyser.text.TextDecoration; import org.geysermc.geyser.translator.level.BiomeTranslator; +import org.geysermc.geyser.util.MinecraftKey; import org.geysermc.mcprotocollib.protocol.MinecraftProtocol; import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; import org.geysermc.mcprotocollib.protocol.data.game.chat.ChatType; @@ -70,8 +72,8 @@ import java.util.function.ToIntFunction; @Accessors(fluent = true) @Getter public final class RegistryCache { - private static final Map> DEFAULTS; - private static final Map>> REGISTRIES = new HashMap<>(); + private static final Map> DEFAULTS; + private static final Map>> REGISTRIES = new HashMap<>(); static { register("chat_type", cache -> cache.chatTypes, ($, entry) -> TextDecoration.readChatType(entry)); @@ -83,14 +85,14 @@ public final class RegistryCache { register("trim_pattern", cache -> cache.trimPatterns, TrimRecipe::readTrimPattern); register("worldgen/biome", (cache, array) -> cache.biomeTranslations = array, BiomeTranslator::loadServerBiome); register("banner_pattern", cache -> cache.bannerPatterns, ($, entry) -> BannerPattern.getByJavaIdentifier(entry.getId())); - register("wolf_variant", cache -> cache.wolfVariants, ($, entry) -> WolfEntity.BuiltInWolfVariant.getByJavaIdentifier(entry.getId())); + register("wolf_variant", cache -> cache.wolfVariants, ($, entry) -> WolfEntity.BuiltInWolfVariant.getByJavaIdentifier(entry.getId().asString())); // Load from MCProtocolLib's classloader NbtMap tag = MinecraftProtocol.loadNetworkCodec(); - Map> defaults = new HashMap<>(); + Map> defaults = new HashMap<>(); // Don't create a keySet - no need to create the cached object in HashMap if we don't use it again REGISTRIES.forEach((key, $) -> { - List rawValues = tag.getCompound(key) + List rawValues = tag.getCompound(key.asString()) .getList("value", NbtType.COMPOUND); Map values = new HashMap<>(); for (NbtMap value : rawValues) { @@ -148,7 +150,7 @@ public final class RegistryCache { * @param the class that represents these entries. */ private static void register(String registry, Function> localCacheFunction, BiFunction reader) { - String key = "minecraft:" + registry; + Key key = MinecraftKey.key(registry); REGISTRIES.put(key, (registryCache, entries) -> { Map localRegistry = null; JavaRegistry localCache = localCacheFunction.apply(registryCache); @@ -176,7 +178,7 @@ public final class RegistryCache { * @param localCacheFunction the int array to set the final values to. */ private static void register(String registry, BiConsumer localCacheFunction, ToIntFunction reader) { - REGISTRIES.put("minecraft:" + registry, (registryCache, entries) -> { + REGISTRIES.put(MinecraftKey.key(registry), (registryCache, entries) -> { Int2IntMap temp = new Int2IntOpenHashMap(); int greatestId = 0; for (int i = 0; i < entries.size(); i++) { diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java index 656a16cf4..c8bfc7eed 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.session.cache; import it.unimi.dsi.fastutil.ints.IntArrays; +import net.kyori.adventure.key.Key; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserLogger; @@ -36,6 +37,7 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.tags.BlockTag; import org.geysermc.geyser.session.cache.tags.EnchantmentTag; import org.geysermc.geyser.session.cache.tags.ItemTag; +import org.geysermc.geyser.util.MinecraftKey; import org.geysermc.geyser.util.Ordered; import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundUpdateTagsPacket; @@ -58,33 +60,33 @@ public final class TagCache { private final int[][] enchantments = new int[ALL_ENCHANTMENT_TAGS.size()][]; public void loadPacket(GeyserSession session, ClientboundUpdateTagsPacket packet) { - Map blockTags = packet.getTags().get("minecraft:block"); + Map blockTags = packet.getTags().get(MinecraftKey.key("block")); loadTags("Block", blockTags, ALL_BLOCK_TAGS, this.blocks); // Hack btw GeyserLogger logger = session.getGeyser().getLogger(); - int[] convertableToMud = blockTags.get("minecraft:convertable_to_mud"); + int[] convertableToMud = blockTags.get(MinecraftKey.key("convertable_to_mud")); boolean emulatePost1_18Logic = convertableToMud != null && convertableToMud.length != 0; session.setEmulatePost1_18Logic(emulatePost1_18Logic); if (logger.isDebug()) { logger.debug("Emulating post 1.18 block predication logic for " + session.bedrockUsername() + "? " + emulatePost1_18Logic); } - Map itemTags = packet.getTags().get("minecraft:item"); + Map itemTags = packet.getTags().get(MinecraftKey.key("item")); loadTags("Item", itemTags, ALL_ITEM_TAGS, this.items); // Hack btw - boolean emulatePost1_13Logic = itemTags.get("minecraft:signs").length > 1; + boolean emulatePost1_13Logic = itemTags.get(MinecraftKey.key("signs")).length > 1; session.setEmulatePost1_13Logic(emulatePost1_13Logic); if (logger.isDebug()) { logger.debug("Emulating post 1.13 villager logic for " + session.bedrockUsername() + "? " + emulatePost1_13Logic); } - Map enchantmentTags = packet.getTags().get("minecraft:enchantment"); + Map enchantmentTags = packet.getTags().get(MinecraftKey.key("enchantment")); loadTags("Enchantment", enchantmentTags, ALL_ENCHANTMENT_TAGS, this.enchantments); } - private void loadTags(String type, @Nullable Map packetTags, Map allTags, int[][] localValues) { + private void loadTags(String type, @Nullable Map packetTags, Map allTags, int[][] localValues) { if (packetTags == null) { Arrays.fill(localValues, IntArrays.EMPTY_ARRAY); GeyserImpl.getInstance().getLogger().debug("Not loading " + type + " tags; they do not exist here."); diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/tags/BlockTag.java b/core/src/main/java/org/geysermc/geyser/session/cache/tags/BlockTag.java index 5a85efc84..1dca7843a 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/tags/BlockTag.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/tags/BlockTag.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.session.cache.tags; +import net.kyori.adventure.key.Key; import org.geysermc.geyser.util.Ordered; import java.util.HashMap; @@ -32,7 +33,7 @@ import java.util.Map; @SuppressWarnings("unused") public final class BlockTag implements Ordered { - public static final Map ALL_BLOCK_TAGS = new HashMap<>(); + public static final Map ALL_BLOCK_TAGS = new HashMap<>(); public static final BlockTag WOOL = new BlockTag("wool"); public static final BlockTag PLANKS = new BlockTag("planks"); @@ -232,6 +233,6 @@ public final class BlockTag implements Ordered { } private static void register(String name, BlockTag tag) { - ALL_BLOCK_TAGS.put(("minecraft:" + name).intern(), tag); + ALL_BLOCK_TAGS.put(Key.key(name), tag); } } diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/tags/EnchantmentTag.java b/core/src/main/java/org/geysermc/geyser/session/cache/tags/EnchantmentTag.java index 3c5446adc..0af690abd 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/tags/EnchantmentTag.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/tags/EnchantmentTag.java @@ -25,6 +25,8 @@ package org.geysermc.geyser.session.cache.tags; +import net.kyori.adventure.key.Key; +import org.geysermc.geyser.util.MinecraftKey; import org.geysermc.geyser.util.Ordered; import java.util.HashMap; @@ -32,7 +34,7 @@ import java.util.Map; @SuppressWarnings("unused") public final class EnchantmentTag implements Ordered { - public static final Map ALL_ENCHANTMENT_TAGS = new HashMap<>(); + public static final Map ALL_ENCHANTMENT_TAGS = new HashMap<>(); public static final EnchantmentTag TOOLTIP_ORDER = new EnchantmentTag("tooltip_order"); public static final EnchantmentTag EXCLUSIVE_SET_ARMOR = new EnchantmentTag("exclusive_set/armor"); @@ -84,6 +86,6 @@ public final class EnchantmentTag implements Ordered { } private static void register(String name, EnchantmentTag tag) { - ALL_ENCHANTMENT_TAGS.put(("minecraft:" + name).intern(), tag); + ALL_ENCHANTMENT_TAGS.put(MinecraftKey.key(name), tag); } } diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/tags/ItemTag.java b/core/src/main/java/org/geysermc/geyser/session/cache/tags/ItemTag.java index e1fbf4634..a2e861dd6 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/tags/ItemTag.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/tags/ItemTag.java @@ -25,6 +25,8 @@ package org.geysermc.geyser.session.cache.tags; +import net.kyori.adventure.key.Key; +import org.geysermc.geyser.util.MinecraftKey; import org.geysermc.geyser.util.Ordered; import java.util.HashMap; @@ -32,7 +34,7 @@ import java.util.Map; @SuppressWarnings("unused") public final class ItemTag implements Ordered { - public static final Map ALL_ITEM_TAGS = new HashMap<>(); + public static final Map ALL_ITEM_TAGS = new HashMap<>(); public static final ItemTag WOOL = new ItemTag("wool"); public static final ItemTag PLANKS = new ItemTag("planks"); @@ -195,6 +197,6 @@ public final class ItemTag implements Ordered { } private static void register(String name, ItemTag tag) { - ALL_ITEM_TAGS.put(("minecraft:" + name).intern(), tag); + ALL_ITEM_TAGS.put(MinecraftKey.key(name), tag); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java index d70f53e2c..166089b6b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java @@ -45,7 +45,7 @@ import org.geysermc.geyser.session.GeyserSession; public class BiomeTranslator { public static int loadServerBiome(RegistryEntry entry) { - String javaIdentifier = entry.getId(); + String javaIdentifier = entry.getId().asString(); return Registries.BIOME_IDENTIFIERS.get().getOrDefault(javaIdentifier, 0); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockEntityDataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockEntityDataTranslator.java index b5e923ee6..a7e4bc656 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockEntityDataTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockEntityDataTranslator.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.translator.protocol.bedrock; +import org.geysermc.geyser.util.MinecraftKey; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSetJigsawBlockPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.level.ServerboundSignUpdatePacket; import org.cloudburstmc.math.vector.Vector3i; @@ -119,7 +120,8 @@ public class BedrockBlockEntityDataTranslator extends PacketTranslator { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java index 1ecc5bf82..ecfb2d220 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java @@ -34,6 +34,7 @@ import it.unimi.dsi.fastutil.ints.IntSet; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap; import lombok.Getter; import lombok.ToString; +import net.kyori.adventure.key.Key; import net.kyori.adventure.text.format.NamedTextColor; import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.cloudburstmc.protocol.bedrock.data.command.*; @@ -66,7 +67,7 @@ public class JavaCommandsTranslator extends PacketTranslator ALL_BLOCK_NAMES = Suppliers.memoize(() -> BlockRegistries.JAVA_BLOCKS.get().stream().map(block -> block.javaIdentifier().toString()).toArray(String[]::new)); private static final String[] ALL_EFFECT_IDENTIFIERS = EntityUtils.getAllEffectIdentifiers(); - private static final String[] ATTRIBUTES = AttributeType.Builtin.BUILTIN.values().stream().map(AttributeType::getIdentifier).toList().toArray(new String[0]); + private static final String[] ATTRIBUTES = AttributeType.Builtin.BUILTIN.values().stream().map(type -> type.getIdentifier().asString()).toList().toArray(new String[0]); private static final String[] ENUM_BOOLEAN = {"true", "false"}; private static final String[] VALID_COLORS; private static final String[] VALID_SCOREBOARD_SLOTS; @@ -264,8 +265,8 @@ public class JavaCommandsTranslator extends PacketTranslator ATTRIBUTES; case "minecraft:enchantment" -> context.getEnchantments(); case "minecraft:entity_type" -> context.getEntityTypes(); @@ -476,12 +477,8 @@ public class JavaCommandsTranslator extends PacketTranslator { @@ -98,7 +101,7 @@ public class JavaLoginTranslator extends PacketTranslator bedrockRecipeIDs = context.translateShapelessRecipe(new GeyserShapelessRecipe(shapelessRecipeData)); if (bedrockRecipeIDs != null) { - context.addRecipeIdentifier(session, recipe.getIdentifier(), bedrockRecipeIDs); + context.addRecipeIdentifier(session, recipe.getIdentifier().asString(), bedrockRecipeIDs); } } case CRAFTING_SHAPED -> { ShapedRecipeData shapedRecipeData = (ShapedRecipeData) recipe.getData(); List bedrockRecipeIDs = context.translateShapedRecipe(new GeyserShapedRecipe(shapedRecipeData)); if (bedrockRecipeIDs != null) { - context.addRecipeIdentifier(session, recipe.getIdentifier(), bedrockRecipeIDs); + context.addRecipeIdentifier(session, recipe.getIdentifier().asString(), bedrockRecipeIDs); } } case STONECUTTING -> { @@ -160,7 +160,7 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator // similar as above "minecraft:arrow"; - default -> recipe.getIdentifier(); + default -> recipe.getIdentifier().asString(); }; addRecipeIdentifier(session, javaRecipeID, identifiers); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java index 342618ff8..7c8374500 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaStoreCookieTranslator.java @@ -35,6 +35,6 @@ public class JavaStoreCookieTranslator extends PacketTranslator Date: Wed, 12 Jun 2024 23:53:02 -0400 Subject: [PATCH 245/272] Fix compilation for modded --- .../geyser/platform/mod/world/GeyserModWorldManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java index 5543dbcee..ef8c3ec0a 100644 --- a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/world/GeyserModWorldManager.java @@ -47,6 +47,7 @@ import org.geysermc.geyser.level.GeyserWorldManager; import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.platform.mod.GeyserModBootstrap; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.util.MinecraftKey; import org.geysermc.mcprotocollib.protocol.data.game.Holder; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer; @@ -173,7 +174,7 @@ public class GeyserModWorldManager extends GeyserWorldManager { return patternLayers.layers().stream() .map(layer -> { BannerPatternLayer.BannerPattern pattern = new BannerPatternLayer.BannerPattern( - layer.pattern().value().assetId().toString(), layer.pattern().value().translationKey() + MinecraftKey.key(layer.pattern().value().assetId().toString()), layer.pattern().value().translationKey() ); return new BannerPatternLayer(Holder.ofCustom(pattern), layer.color().getId()); }) From d00cab18fdc0eeb15381cc17c384fd2f5a6faa88 Mon Sep 17 00:00:00 2001 From: chris Date: Thu, 13 Jun 2024 14:14:57 +0200 Subject: [PATCH 246/272] Only translate double chest tags if we are dealing with a double chest (#4736) --- .../block/entity/DoubleChestBlockEntityTranslator.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java index 988d94073..9f111788b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java @@ -42,9 +42,11 @@ public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator impl @Override public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) { - int x = (int) bedrockNbt.get("x"); - int z = (int) bedrockNbt.get("z"); - translateChestValue(bedrockNbt, blockState, x, z); + if (blockState.getValue(Properties.CHEST_TYPE) != ChestType.SINGLE) { + int x = (int) bedrockNbt.get("x"); + int z = (int) bedrockNbt.get("z"); + translateChestValue(bedrockNbt, blockState, x, z); + } } /** From db5a5289659d8b07abdcca83e5549672ddc0e272 Mon Sep 17 00:00:00 2001 From: chris Date: Thu, 13 Jun 2024 16:53:01 +0200 Subject: [PATCH 247/272] Fix: Improper detection of virtual double chests (#4738) --- .../inventory/chest/DoubleChestInventoryTranslator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java index 06531eff2..856cc1876 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/chest/DoubleChestInventoryTranslator.java @@ -64,7 +64,7 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator { if (session.getLastInteractionPlayerPosition().equals(session.getPlayerEntity().getPosition())) { BlockState state = session.getGeyser().getWorldManager().blockAt(session, session.getLastInteractionBlockPosition()); if (!BlockRegistries.CUSTOM_BLOCK_STATE_OVERRIDES.get().containsKey(state.javaId())) { - if (state.block() == Blocks.CHEST || state.block() == Blocks.TRAPPED_CHEST + if ((state.block() == Blocks.CHEST || state.block() == Blocks.TRAPPED_CHEST) && state.getValue(Properties.CHEST_TYPE) != ChestType.SINGLE) { inventory.setHolderPosition(session.getLastInteractionBlockPosition()); ((Container) inventory).setUsingRealBlock(true, state.block()); From ce3083b9b83b65ffc041326e45f14aa040c9dd7b Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Thu, 13 Jun 2024 11:24:16 -0400 Subject: [PATCH 248/272] Fix key regression with pre-built registries --- .../geysermc/geyser/session/cache/RegistryCache.java | 10 +++++----- .../java/JavaClientboundRecipesTranslator.java | 1 - 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java index 02c43939d..3121af369 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/RegistryCache.java @@ -72,7 +72,7 @@ import java.util.function.ToIntFunction; @Accessors(fluent = true) @Getter public final class RegistryCache { - private static final Map> DEFAULTS; + private static final Map> DEFAULTS; private static final Map>> REGISTRIES = new HashMap<>(); static { @@ -89,14 +89,14 @@ public final class RegistryCache { // Load from MCProtocolLib's classloader NbtMap tag = MinecraftProtocol.loadNetworkCodec(); - Map> defaults = new HashMap<>(); + Map> defaults = new HashMap<>(); // Don't create a keySet - no need to create the cached object in HashMap if we don't use it again REGISTRIES.forEach((key, $) -> { List rawValues = tag.getCompound(key.asString()) .getList("value", NbtType.COMPOUND); - Map values = new HashMap<>(); + Map values = new HashMap<>(); for (NbtMap value : rawValues) { - String name = value.getString("name"); + Key name = MinecraftKey.key(value.getString("name")); values.put(name, value.getCompound("element")); } // Can make these maps immutable and as efficient as possible after initialization @@ -152,7 +152,7 @@ public final class RegistryCache { private static void register(String registry, Function> localCacheFunction, BiFunction reader) { Key key = MinecraftKey.key(registry); REGISTRIES.put(key, (registryCache, entries) -> { - Map localRegistry = null; + Map localRegistry = null; JavaRegistry localCache = localCacheFunction.apply(registryCache); // Clear each local cache every time a new registry entry is given to us // (e.g. proxy server switches) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaClientboundRecipesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaClientboundRecipesTranslator.java index 06abbbac0..9eb69183d 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaClientboundRecipesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaClientboundRecipesTranslator.java @@ -39,7 +39,6 @@ public class JavaClientboundRecipesTranslator extends PacketTranslator { From 746be566a2a341498b27ace99a079f6db4adb5d5 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Thu, 13 Jun 2024 13:53:20 -0400 Subject: [PATCH 249/272] Sanity check for BlockState being chest --- .../level/block/entity/DoubleChestBlockEntityTranslator.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java index 9f111788b..6fea10e2e 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java @@ -27,6 +27,7 @@ package org.geysermc.geyser.translator.level.block.entity; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; +import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.level.block.property.ChestType; import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.type.BlockState; @@ -42,6 +43,9 @@ public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator impl @Override public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) { + if (!(blockState.is(Blocks.CHEST) || blockState.is(Blocks.TRAPPED_CHEST))) { + return; + } if (blockState.getValue(Properties.CHEST_TYPE) != ChestType.SINGLE) { int x = (int) bedrockNbt.get("x"); int z = (int) bedrockNbt.get("z"); From b6653acc294e21778d09bfa155528bf116eea70c Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Thu, 13 Jun 2024 19:53:47 +0200 Subject: [PATCH 250/272] Catch Throwable when trying to load world adapter --- .../org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java index d138ad074..fdef77bbe 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java @@ -265,7 +265,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { this.geyserWorldManager = new GeyserSpigotNativeWorldManager(this, isPaper); } geyserLogger.debug("Using world manager of type: " + this.geyserWorldManager.getClass().getSimpleName()); - } catch (Exception e) { + } catch (Throwable e) { if (geyserConfig.isDebugMode()) { geyserLogger.debug("Error while attempting to find NMS adapter. Most likely, this can be safely ignored. :)"); e.printStackTrace(); From a5ecee73ef0f4382420ffd252eb2097ba70d4e3b Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Thu, 13 Jun 2024 20:12:45 +0200 Subject: [PATCH 251/272] Update Bungee warning for outdated proxy checks --- .../geysermc/geyser/platform/bungeecord/GeyserBungeePlugin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeePlugin.java b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeePlugin.java index 062ef6f76..cd6b59f64 100644 --- a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeePlugin.java +++ b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeePlugin.java @@ -81,7 +81,7 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap { // Copied from ViaVersion. // https://github.com/ViaVersion/ViaVersion/blob/b8072aad86695cc8ec6f5e4103e43baf3abf6cc5/bungee/src/main/java/us/myles/ViaVersion/BungeePlugin.java#L43 try { - ProtocolConstants.class.getField("MINECRAFT_1_20_5"); + ProtocolConstants.class.getField("MINECRAFT_1_21"); } catch (NoSuchFieldException e) { geyserLogger.error(" / \\"); geyserLogger.error(" / \\"); From 4a334a2c8d7068c84fc9d41ada97a86f77c85c1f Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Thu, 13 Jun 2024 14:58:39 -0400 Subject: [PATCH 252/272] Bed block sanity check for villagers --- .../type/living/merchant/VillagerEntity.java | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/VillagerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/VillagerEntity.java index fb07572e6..d7efa9f1d 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/VillagerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/merchant/VillagerEntity.java @@ -34,6 +34,7 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.MoveEntityAbsolutePacket; import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.level.block.property.Properties; +import org.geysermc.geyser.level.block.type.BedBlock; import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; @@ -125,22 +126,24 @@ public class VillagerEntity extends AbstractMerchantEntity { int bedRotation = 0; float xOffset = 0; float zOffset = 0; - switch (state.getValue(Properties.HORIZONTAL_FACING)) { - case SOUTH -> { - bedRotation = 180; - zOffset = -.5f; - } - case EAST -> { - bedRotation = 90; - xOffset = -.5f; - } - case WEST -> { - bedRotation = 270; - xOffset = .5f; - } - case NORTH -> { - // rotation does not change because north is 0 - zOffset = .5f; + if (state.block() instanceof BedBlock) { + switch (state.getValue(Properties.HORIZONTAL_FACING)) { + case SOUTH -> { + bedRotation = 180; + zOffset = -.5f; + } + case EAST -> { + bedRotation = 90; + xOffset = -.5f; + } + case WEST -> { + bedRotation = 270; + xOffset = .5f; + } + case NORTH -> { + // rotation does not change because north is 0 + zOffset = .5f; + } } } From 6a715770e21d0569d00e50b8ab4eea7a9c8518be Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Thu, 13 Jun 2024 23:20:43 +0200 Subject: [PATCH 253/272] Update mod dependencies to their official 1.21 releases --- .../mod/fabric/src/main/resources/fabric.mod.json | 4 ++-- .../src/main/resources/META-INF/neoforge.mods.toml | 4 ++-- .../main/kotlin/geyser.modded-conventions.gradle.kts | 10 ++-------- gradle/libs.versions.toml | 4 ++-- 4 files changed, 8 insertions(+), 14 deletions(-) diff --git a/bootstrap/mod/fabric/src/main/resources/fabric.mod.json b/bootstrap/mod/fabric/src/main/resources/fabric.mod.json index 93f48b73c..262f9833a 100644 --- a/bootstrap/mod/fabric/src/main/resources/fabric.mod.json +++ b/bootstrap/mod/fabric/src/main/resources/fabric.mod.json @@ -23,8 +23,8 @@ "geyser.mixins.json" ], "depends": { - "fabricloader": ">=0.15.10", + "fabricloader": ">=0.15.11", "fabric": "*", - "minecraft": ">=1.20.5" + "minecraft": ">=1.21" } } diff --git a/bootstrap/mod/neoforge/src/main/resources/META-INF/neoforge.mods.toml b/bootstrap/mod/neoforge/src/main/resources/META-INF/neoforge.mods.toml index 3a25f6119..fa01bb6ec 100644 --- a/bootstrap/mod/neoforge/src/main/resources/META-INF/neoforge.mods.toml +++ b/bootstrap/mod/neoforge/src/main/resources/META-INF/neoforge.mods.toml @@ -14,12 +14,12 @@ config = "geyser.mixins.json" [[dependencies.geyser_neoforge]] modId="neoforge" type="required" - versionRange="[20.5.0-beta,)" + versionRange="[21.0.0-beta,)" ordering="NONE" side="BOTH" [[dependencies.geyser_neoforge]] modId="minecraft" type="required" - versionRange="[1.20.5,)" + versionRange="[1.21,)" ordering="NONE" side="BOTH" \ No newline at end of file diff --git a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts index 6472e4312..86c2a2f6a 100644 --- a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts @@ -110,7 +110,7 @@ afterEvaluate { } dependencies { - minecraft("com.mojang:minecraft:1.21-rc1") + minecraft("com.mojang:minecraft:1.21") mappings(loom.officialMojangMappings()) } @@ -121,12 +121,6 @@ repositories { maven("https://oss.sonatype.org/content/repositories/snapshots/") maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") maven("https://maven.neoforged.net/releases") - maven("https://prmaven.neoforged.net/NeoForge/pr1076") { - name = "Maven for 1.21 PR" - content { - includeModule("net.neoforged", "neoforge") - } - } } modrinth { @@ -139,6 +133,6 @@ modrinth { syncBodyFrom.set(rootProject.file("README.md").readText()) uploadFile.set(tasks.getByPath("remapModrinthJar")) - gameVersions.addAll("1.20.5", "1.20.6") + gameVersions.addAll("1.21") failSilently.set(true) } \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 10a94c3db..5e55aa117 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -28,11 +28,11 @@ commodore = "2.2" bungeecord = "a7c6ede" velocity = "3.3.0-SNAPSHOT" viaproxy = "3.2.1" -fabric-minecraft = "1.21-rc1" +fabric-minecraft = "1.21" fabric-loader = "0.15.11" fabric-api = "0.100.1+1.21" fabric-permissions = "0.2-SNAPSHOT" -neoforge-minecraft = "21.0.0-alpha.1.21-rc1.20240611.001314" +neoforge-minecraft = "21.0.0-beta" mixin = "0.8.5" # plugin versions From 09c0ada50216e1a163b22cccdce5b0657085ebd6 Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Thu, 13 Jun 2024 19:53:47 +0200 Subject: [PATCH 254/272] Catch Throwable when trying to load world adapter --- .../org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java index d138ad074..fdef77bbe 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java @@ -265,7 +265,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { this.geyserWorldManager = new GeyserSpigotNativeWorldManager(this, isPaper); } geyserLogger.debug("Using world manager of type: " + this.geyserWorldManager.getClass().getSimpleName()); - } catch (Exception e) { + } catch (Throwable e) { if (geyserConfig.isDebugMode()) { geyserLogger.debug("Error while attempting to find NMS adapter. Most likely, this can be safely ignored. :)"); e.printStackTrace(); From 138c7b4eee97670d36ec36f5bc0dc6cfcbab56fa Mon Sep 17 00:00:00 2001 From: chris Date: Fri, 14 Jun 2024 17:27:30 +0200 Subject: [PATCH 255/272] Catch EOFExceptions while pinging Java servers when it is misconfigured/not online (#4746) * Catch EOFExceptions when the remote server is misconfigured/not online --- .../geysermc/geyser/ping/GeyserLegacyPingPassthrough.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/ping/GeyserLegacyPingPassthrough.java b/core/src/main/java/org/geysermc/geyser/ping/GeyserLegacyPingPassthrough.java index 320334ee5..27b405348 100644 --- a/core/src/main/java/org/geysermc/geyser/ping/GeyserLegacyPingPassthrough.java +++ b/core/src/main/java/org/geysermc/geyser/ping/GeyserLegacyPingPassthrough.java @@ -35,10 +35,7 @@ import org.cloudburstmc.nbt.util.VarInts; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.network.GameProtocol; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; +import java.io.*; import java.net.*; import java.util.concurrent.TimeUnit; @@ -139,6 +136,9 @@ public class GeyserLegacyPingPassthrough implements IGeyserPingPassthrough, Runn this.geyser.getLogger().debug("Connection timeout for ping passthrough."); } catch (JsonParseException | JsonMappingException ex) { this.geyser.getLogger().error("Failed to parse json when pinging server!", ex); + } catch (EOFException e) { + this.pingInfo = null; + this.geyser.getLogger().warning("Failed to ping the remote Java server! Is it online and configured in Geyser's config?"); } catch (UnknownHostException ex) { // Don't reset pingInfo, as we want to keep the last known value this.geyser.getLogger().warning("Unable to resolve remote host! Is the remote server down or invalid?"); From 28e4661fcf68f572c8ea5a60c7acb152f13b2ca4 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Fri, 14 Jun 2024 14:02:11 -0400 Subject: [PATCH 256/272] Fix incoming player chat --- .../main/java/org/geysermc/geyser/text/TextDecoration.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java b/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java index cf2071173..ab9e2b5ed 100644 --- a/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java +++ b/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java @@ -50,13 +50,13 @@ public record TextDecoration(String translationKey, List parameters, NbtMap tag = entry.getData(); NbtMap chat = tag.getCompound("chat", null); if (chat != null) { - String translationKey = tag.getString("translation_key"); + String translationKey = chat.getString("translation_key"); - NbtMap styleTag = tag.getCompound("style"); + NbtMap styleTag = chat.getCompound("style"); Style style = deserializeStyle(styleTag); List parameters = new ArrayList<>(); - List parametersNbt = tag.getList("parameters", NbtType.STRING); + List parametersNbt = chat.getList("parameters", NbtType.STRING); for (String parameter : parametersNbt) { parameters.add(ChatTypeDecoration.Parameter.valueOf(parameter.toUpperCase(Locale.ROOT))); } From a9ba1ad603d819695c2aca7c6c83f2912d03ec98 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Fri, 14 Jun 2024 15:44:00 -0400 Subject: [PATCH 257/272] Properly translate ominous items --- .../java/org/geysermc/geyser/item/Items.java | 2 +- .../geysermc/geyser/item/type/ArrowItem.java | 5 ++ .../geyser/item/type/FireworkStarItem.java | 5 ++ .../geyser/item/type/GoatHornItem.java | 5 ++ .../org/geysermc/geyser/item/type/Item.java | 8 +++ .../geyser/item/type/OminousBottleItem.java | 72 +++++++++++++++++++ .../geysermc/geyser/item/type/PotionItem.java | 5 ++ .../registry/populator/Conversion685_671.java | 6 ++ .../geyser/registry/type/ItemMappings.java | 9 +-- core/src/main/resources/mappings | 2 +- 10 files changed, 111 insertions(+), 8 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/item/type/OminousBottleItem.java diff --git a/core/src/main/java/org/geysermc/geyser/item/Items.java b/core/src/main/java/org/geysermc/geyser/item/Items.java index 5ae69fa4e..1ddd14982 100644 --- a/core/src/main/java/org/geysermc/geyser/item/Items.java +++ b/core/src/main/java/org/geysermc/geyser/item/Items.java @@ -1368,7 +1368,7 @@ public final class Items { public static final Item TRIAL_KEY = register(new Item("trial_key", builder())); public static final Item OMINOUS_TRIAL_KEY = register(new Item("ominous_trial_key", builder())); public static final Item VAULT = register(new BlockItem(builder(), Blocks.VAULT)); - public static final Item OMINOUS_BOTTLE = register(new Item("ominous_bottle", builder())); + public static final Item OMINOUS_BOTTLE = register(new OminousBottleItem("ominous_bottle", builder())); public static final Item BREEZE_ROD = register(new Item("breeze_rod", builder())); public static final int AIR_ID = AIR.javaId(); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java index c06a143ac..4e4f1830e 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArrowItem.java @@ -51,4 +51,9 @@ public class ArrowItem extends Item { } return itemStack; } + + @Override + public boolean ignoreDamage() { + return true; + } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java index 2ba9b4258..5ac0f475c 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/FireworkStarItem.java @@ -90,4 +90,9 @@ public class FireworkStarItem extends Item { components.put(DataComponentType.FIREWORK_EXPLOSION, newExplosion); } } + + @Override + public boolean ignoreDamage() { + return true; + } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java index cd21c0b6e..d0e85ec52 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/GoatHornItem.java @@ -62,4 +62,9 @@ public class GoatHornItem extends Item { return itemStack; } + + @Override + public boolean ignoreDamage() { + return true; + } } diff --git a/core/src/main/java/org/geysermc/geyser/item/type/Item.java b/core/src/main/java/org/geysermc/geyser/item/type/Item.java index 3014e8116..0b2521a3e 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/Item.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/Item.java @@ -226,6 +226,14 @@ public class Item { } } + /** + * Override if the Bedrock equivalent of an item uses damage for extra data, and should not be tracked + * when translating an item. + */ + public boolean ignoreDamage() { + return false; + } + /* Translation methods end */ public GeyserItemStack newItemStack(int count, DataComponents components) { diff --git a/core/src/main/java/org/geysermc/geyser/item/type/OminousBottleItem.java b/core/src/main/java/org/geysermc/geyser/item/type/OminousBottleItem.java new file mode 100644 index 000000000..815f71419 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/item/type/OminousBottleItem.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.item.type; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; +import org.geysermc.geyser.inventory.GeyserItemStack; +import org.geysermc.geyser.registry.type.ItemMapping; +import org.geysermc.geyser.registry.type.ItemMappings; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; + +public class OminousBottleItem extends Item { + public OminousBottleItem(String javaIdentifier, Builder builder) { + super(javaIdentifier, builder); + } + + @Override + public ItemData.Builder translateToBedrock(int count, @Nullable DataComponents components, ItemMapping mapping, ItemMappings mappings) { + var builder = super.translateToBedrock(count, components, mapping, mappings); + if (components == null) { + // Level 1 ominous bottle is null components - Java 1.21. + return builder; + } + Integer amplifier = components.get(DataComponentType.OMINOUS_BOTTLE_AMPLIFIER); + if (amplifier != null) { + builder.damage(amplifier); + } + return builder; + } + + @Override + public @NonNull GeyserItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { + // This item can be pulled from the creative inventory with amplifiers. + GeyserItemStack itemStack = super.translateToJava(itemData, mapping, mappings); + int damage = itemData.getDamage(); + if (damage == 0) { + return itemStack; + } + itemStack.getOrCreateComponents().put(DataComponentType.OMINOUS_BOTTLE_AMPLIFIER, damage); + return itemStack; + } + + @Override + public boolean ignoreDamage() { + return true; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java index e9889c882..f8fe2b4ee 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PotionItem.java @@ -76,4 +76,9 @@ public class PotionItem extends Item { } return itemStack; } + + @Override + public boolean ignoreDamage() { + return true; + } } diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion685_671.java b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion685_671.java index 41a8af826..58886ca57 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion685_671.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/Conversion685_671.java @@ -50,6 +50,12 @@ public class Conversion685_671 { if (NEW_MUSIC_DISCS.contains(item)) { return mapping.withBedrockIdentifier("minecraft:music_disc_otherside"); } + if (item == Items.OMINOUS_TRIAL_KEY) { + return mapping.withBedrockIdentifier("minecraft:trial_key"); + } + if (item == Items.OMINOUS_BOTTLE) { + return mapping.withBedrockIdentifier("minecraft:glass_bottle"); + } if (!NEW_BLOCKS.contains(identifer)) { return mapping; diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java b/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java index 94c863660..189474238 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java +++ b/core/src/main/java/org/geysermc/geyser/registry/type/ItemMappings.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.registry.type; -import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2ObjectMap; import lombok.Builder; @@ -41,7 +40,7 @@ import org.geysermc.geyser.api.block.custom.CustomBlockData; import org.geysermc.geyser.inventory.item.StoredItemMappings; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.type.Item; -import org.geysermc.geyser.item.type.PotionItem; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import java.util.List; import java.util.Map; @@ -148,10 +147,8 @@ public class ItemMappings implements DefinitionRegistry { } } else { if (!(mapping.getBedrockData() == data.getDamage() || - // Make exceptions for potions, tipped arrows, firework stars, goat horns, and suspicious stews, whose damage values can vary - (mapping.getJavaItem() instanceof PotionItem || mapping.getJavaItem() == Items.ARROW - || mapping.getJavaItem() == Items.FIREWORK_STAR || mapping.getJavaItem() == Items.GOAT_HORN - || mapping.getJavaItem() == Items.SUSPICIOUS_STEW))) { + // Make exceptions for items whose damage values can vary + (mapping.getJavaItem().ignoreDamage() || mapping.getJavaItem() == Items.SUSPICIOUS_STEW))) { continue; } } diff --git a/core/src/main/resources/mappings b/core/src/main/resources/mappings index 396ea5ff5..5f892d04d 160000 --- a/core/src/main/resources/mappings +++ b/core/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 396ea5ff50d8c976fde4e7423e682d21aa0ee350 +Subproject commit 5f892d04d2212a13fad3f517b3f516d6526833f2 From 7e87af718bab6e858fa8a6793a400c407edea9cf Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Fri, 14 Jun 2024 16:48:46 -0400 Subject: [PATCH 258/272] Fix item attribute modifiers --- .../org/geysermc/geyser/translator/item/ItemTranslator.java | 2 +- gradle/libs.versions.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index 8b61e435a..672d2d7a5 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -247,7 +247,7 @@ public final class ItemTranslator { return null; } - String name = modifier.getName().replace("minecraft:", ""); + String name = modifier.getId().asMinimalString(); // the namespace does not need to be present, but if it is, the java client ignores it as of pre-1.20.5 ModifierOperation operation = modifier.getOperation(); diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5e55aa117..1677d46fa 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,7 +13,7 @@ websocket = "1.5.1" protocol = "3.0.0.Beta2-20240606.172607-7" raknet = "1.0.0.CR3-20240416.144209-1" mcauthlib = "e5b0bcc" -mcprotocollib = "f9cc9ee6" +mcprotocollib = "dcf9d02" adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From be83fe7220f6679d0c558a3c0db78a4dabd54c7d Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Fri, 14 Jun 2024 19:36:10 -0400 Subject: [PATCH 259/272] Re-enable crafter inventory --- .../geysermc/geyser/inventory/Container.java | 2 +- .../geyser/inventory/CrafterContainer.java | 40 ++++++++++++++++++- .../inventory/InventoryTranslator.java | 2 +- .../JavaContainerSetContentTranslator.java | 3 +- core/src/main/resources/mappings | 2 +- 5 files changed, 43 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/inventory/Container.java b/core/src/main/java/org/geysermc/geyser/inventory/Container.java index 81818613f..e78a4d2c6 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/Container.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/Container.java @@ -38,7 +38,7 @@ import org.jetbrains.annotations.Range; */ @Getter public class Container extends Inventory { - private final PlayerInventory playerInventory; + protected final PlayerInventory playerInventory; private final int containerSize; /** diff --git a/core/src/main/java/org/geysermc/geyser/inventory/CrafterContainer.java b/core/src/main/java/org/geysermc/geyser/inventory/CrafterContainer.java index 41452bed6..fb118252d 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/CrafterContainer.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/CrafterContainer.java @@ -25,13 +25,19 @@ package org.geysermc.geyser.inventory; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.inventory.CrafterInventoryTranslator; +import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import lombok.Getter; import lombok.Setter; import org.geysermc.geyser.GeyserImpl; +import org.jetbrains.annotations.Range; @Getter public class CrafterContainer extends Container { + private GeyserItemStack resultItem = GeyserItemStack.EMPTY; @Setter private boolean triggered = false; @@ -46,8 +52,36 @@ public class CrafterContainer extends Container { super(title, id, size, containerType, playerInventory); } + @Override + public GeyserItemStack getItem(int slot) { + if (slot == CrafterInventoryTranslator.JAVA_RESULT_SLOT) { + return this.resultItem; + } else if (isCraftingGrid(slot)) { + return super.getItem(slot); + } else { + return playerInventory.getItem(slot - CrafterInventoryTranslator.GRID_SIZE + InventoryTranslator.PLAYER_INVENTORY_OFFSET); + } + } + + @Override + public int getOffsetForHotbar(@Range(from = 0, to = 8) int slot) { + return playerInventory.getOffsetForHotbar(slot) - InventoryTranslator.PLAYER_INVENTORY_OFFSET + CrafterInventoryTranslator.GRID_SIZE; + } + + @Override + public void setItem(int slot, @NonNull GeyserItemStack newItem, GeyserSession session) { + if (slot == CrafterInventoryTranslator.JAVA_RESULT_SLOT) { + // Result item probably won't be an item that needs to worry about net ID or lodestone compasses + this.resultItem = newItem; + } else if (isCraftingGrid(slot)) { + super.setItem(slot, newItem, session); + } else { + playerInventory.setItem(slot - CrafterInventoryTranslator.GRID_SIZE + InventoryTranslator.PLAYER_INVENTORY_OFFSET, newItem, session); + } + } + public void setSlot(int slot, boolean enabled) { - if (slot < 0 || slot > 8) { + if (!isCraftingGrid(slot)) { GeyserImpl.getInstance().getLogger().warning("Crafter slot out of bounds: " + slot); return; } @@ -58,4 +92,8 @@ public class CrafterContainer extends Container { disabledSlotsMask = (short) (disabledSlotsMask | (1 << slot)); } } + + private static boolean isCraftingGrid(int slot) { + return slot >= 0 && slot <= 8; + } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java index 5e4ffcafd..4c426b410 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java @@ -86,7 +86,7 @@ public abstract class InventoryTranslator { put(ContainerType.BEACON, new BeaconInventoryTranslator()); put(ContainerType.BREWING_STAND, new BrewingInventoryTranslator()); put(ContainerType.CARTOGRAPHY, new CartographyInventoryTranslator()); - //put(ContainerType.CRAFTER_3x3, new CrafterInventoryTranslator()); todo Output slot is currently broken + put(ContainerType.CRAFTER_3x3, new CrafterInventoryTranslator()); put(ContainerType.CRAFTING, new CraftingInventoryTranslator()); put(ContainerType.ENCHANTMENT, new EnchantingInventoryTranslator()); put(ContainerType.HOPPER, new HopperInventoryTranslator()); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetContentTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetContentTranslator.java index 44bd7171f..36d382d69 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetContentTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetContentTranslator.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.translator.protocol.java.inventory; -import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundContainerSetContentPacket; -import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.inventory.Inventory; @@ -36,6 +34,7 @@ import org.geysermc.geyser.translator.inventory.PlayerInventoryTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.util.InventoryUtils; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundContainerSetContentPacket; @Translator(packet = ClientboundContainerSetContentPacket.class) public class JavaContainerSetContentTranslator extends PacketTranslator { diff --git a/core/src/main/resources/mappings b/core/src/main/resources/mappings index 5f892d04d..2ac0c1415 160000 --- a/core/src/main/resources/mappings +++ b/core/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 5f892d04d2212a13fad3f517b3f516d6526833f2 +Subproject commit 2ac0c1415cb9063c405dbd7e14f2d426a0ba1180 From b1d319bb7eb394c208b91ffbf91d3a20198fa271 Mon Sep 17 00:00:00 2001 From: onebeastchris Date: Sat, 15 Jun 2024 18:39:09 +0200 Subject: [PATCH 260/272] Add Spigot 1.21 world adapter --- .../org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java | 1 + gradle/libs.versions.toml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java index fdef77bbe..2d13155f2 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java @@ -251,6 +251,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { SpigotAdapters.registerWorldAdapter(nmsVersion); geyserLogger.debug("Using spigot NMS adapter for nms version: " + nmsVersion); } catch (Exception e) { // Likely running on Paper 1.20.5+ + geyserLogger.debug("Unable to find spigot world manager: " + e.getMessage()); //noinspection deprecation int protocolVersion = Bukkit.getUnsafe().getProtocolVersion(); PaperAdapters.registerClosestWorldAdapter(protocolVersion); diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1677d46fa..648d5eb03 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -23,7 +23,7 @@ jline = "3.21.0" terminalconsoleappender = "1.2.0" folia = "1.19.4-R0.1-SNAPSHOT" viaversion = "4.9.2" -adapters = "1.12-SNAPSHOT" +adapters = "1.13-SNAPSHOT" commodore = "2.2" bungeecord = "a7c6ede" velocity = "3.3.0-SNAPSHOT" From 851ed36244b733dcf1c24374a4a747740f2251aa Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 15 Jun 2024 16:52:09 -0400 Subject: [PATCH 261/272] Translate vault block entity --- .../entity/VaultBlockEntityTranslator.java | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 core/src/main/java/org/geysermc/geyser/translator/level/block/entity/VaultBlockEntityTranslator.java diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/VaultBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/VaultBlockEntityTranslator.java new file mode 100644 index 000000000..5f39451ac --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/VaultBlockEntityTranslator.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.translator.level.block.entity; + +import it.unimi.dsi.fastutil.longs.LongArrayList; +import it.unimi.dsi.fastutil.longs.LongList; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.cloudburstmc.nbt.NbtMap; +import org.cloudburstmc.nbt.NbtMapBuilder; +import org.cloudburstmc.nbt.NbtType; +import org.geysermc.geyser.entity.type.player.PlayerEntity; +import org.geysermc.geyser.level.block.type.BlockState; +import org.geysermc.geyser.registry.type.ItemMapping; +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; + +import java.util.List; +import java.util.UUID; + +@BlockEntity(type = BlockEntityType.VAULT) +public class VaultBlockEntityTranslator extends BlockEntityTranslator { + // Bedrock 1.21 does not send the position nor ID in the tag. + @Override + public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, @Nullable NbtMap javaNbt, BlockState blockState) { + NbtMapBuilder builder = NbtMap.builder(); + if (javaNbt != null) { + translateTag(session, builder, javaNbt, blockState); + } + return builder.build(); + } + + @Override + public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) { + NbtMap sharedData = javaNbt.getCompound("shared_data"); + + NbtMap item = sharedData.getCompound("display_item"); + ItemMapping mapping = session.getItemMappings().getMapping(item.getString("id")); + if (mapping == null) { + bedrockNbt.putCompound("display_item", NbtMap.builder() + .putByte("Count", (byte) 0) + .putShort("Damage", (short) 0) + .putString("Name", "") + .putByte("WasPickedUp", (byte) 0).build()); + } else { + int count = item.getInt("count"); + NbtMapBuilder bedrockItem = BedrockItemBuilder.createItemNbt(mapping, count, mapping.getBedrockData()); + // TODO handle components... + bedrockNbt.putCompound("display_item", bedrockItem.build()); + } + + List connectedPlayers = sharedData.getList("connected_players", NbtType.INT_ARRAY); + LongList bedrockPlayers = new LongArrayList(connectedPlayers.size()); + for (int[] player : connectedPlayers) { + UUID uuid = uuidFromIntArray(player); + PlayerEntity playerEntity = session.getEntityCache().getPlayerEntity(uuid); + if (playerEntity != null) { + bedrockPlayers.add(playerEntity.getGeyserId()); + } + } + bedrockNbt.putList("connected_players", NbtType.LONG, bedrockPlayers); + + // Fill this in, since as of Java 1.21, Bedrock always seems to include it, but Java assumes the default + // if it is not sent over the network + bedrockNbt.putFloat("connected_particle_range", (float) sharedData.getDouble("connected_particles_range", 4.5d)); + } + + // From ViaVersion! thank u!! + private static UUID uuidFromIntArray(int[] parts) { + return new UUID((long) parts[0] << 32 | (parts[1] & 0xFFFFFFFFL), (long) parts[2] << 32 | (parts[3] & 0xFFFFFFFFL)); + } +} From 6025931c7d7728f104676f3bacfd898f3d64fcb2 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 15 Jun 2024 22:40:29 -0400 Subject: [PATCH 262/272] Properly translate player entity UUID for vaults --- .../level/block/entity/VaultBlockEntityTranslator.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/VaultBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/VaultBlockEntityTranslator.java index 5f39451ac..50fd64202 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/VaultBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/VaultBlockEntityTranslator.java @@ -76,9 +76,13 @@ public class VaultBlockEntityTranslator extends BlockEntityTranslator { LongList bedrockPlayers = new LongArrayList(connectedPlayers.size()); for (int[] player : connectedPlayers) { UUID uuid = uuidFromIntArray(player); - PlayerEntity playerEntity = session.getEntityCache().getPlayerEntity(uuid); - if (playerEntity != null) { - bedrockPlayers.add(playerEntity.getGeyserId()); + if (uuid.equals(session.getPlayerEntity().getUuid())) { + bedrockPlayers.add(session.getPlayerEntity().getGeyserId()); + } else { + PlayerEntity playerEntity = session.getEntityCache().getPlayerEntity(uuid); + if (playerEntity != null) { + bedrockPlayers.add(playerEntity.getGeyserId()); + } } } bedrockNbt.putList("connected_players", NbtType.LONG, bedrockPlayers); From bd30b34600938f7dbea91ce36889a6605959543c Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Sun, 16 Jun 2024 01:06:17 -0400 Subject: [PATCH 263/272] Bump MCPL --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 648d5eb03..6beae8f8d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,7 +13,7 @@ websocket = "1.5.1" protocol = "3.0.0.Beta2-20240606.172607-7" raknet = "1.0.0.CR3-20240416.144209-1" mcauthlib = "e5b0bcc" -mcprotocollib = "dcf9d02" +mcprotocollib = "4f5f650" adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From d9f9fcf39a784b1ccb642712668acec5741e729b Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sun, 16 Jun 2024 12:26:31 -0400 Subject: [PATCH 264/272] Bump Protocol --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6beae8f8d..1456a7e34 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -10,7 +10,7 @@ netty-io-uring = "0.0.25.Final-SNAPSHOT" guava = "29.0-jre" gson = "2.3.1" # Provided by Spigot 1.8.8 websocket = "1.5.1" -protocol = "3.0.0.Beta2-20240606.172607-7" +protocol = "3.0.0.Beta2-20240616.144648-10" raknet = "1.0.0.CR3-20240416.144209-1" mcauthlib = "e5b0bcc" mcprotocollib = "4f5f650" From 6cda7c2202716525f525dff7f8efa00b5e0949ea Mon Sep 17 00:00:00 2001 From: YHDiamond <47502993+YHDiamond@users.noreply.github.com> Date: Sun, 16 Jun 2024 15:01:21 -0400 Subject: [PATCH 265/272] Partially implement handling of "hide_tooltip" and fix attribute modifiers in "Armor" category not showing (#4731) * Skip lore creation if hide tooltips exists * Fix not showing attributes for "Armor" category * Minor refactor --------- Co-authored-by: chris --- .../org/geysermc/geyser/item/type/Item.java | 2 +- .../translator/item/ItemTranslator.java | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/type/Item.java b/core/src/main/java/org/geysermc/geyser/item/type/Item.java index 0b2521a3e..362b760c7 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/Item.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/Item.java @@ -125,7 +125,7 @@ public class Item { */ public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { List loreComponents = components.get(DataComponentType.LORE); - if (loreComponents != null) { + if (loreComponents != null && components.get(DataComponentType.HIDE_TOOLTIP) == null) { List lore = builder.getOrCreateLore(); for (Component loreComponent : loreComponents) { lore.add(MessageTranslator.convertMessage(loreComponent, session.locale())); diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index 672d2d7a5..7572f5e61 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -65,6 +65,12 @@ public final class ItemTranslator { * The order of these slots is their display order on Java Edition clients */ private static final EnumMap SLOT_NAMES; + private static final ItemAttributeModifiers.EquipmentSlotGroup[] ARMOR_SLOT_NAMES = new ItemAttributeModifiers.EquipmentSlotGroup[] { + ItemAttributeModifiers.EquipmentSlotGroup.HEAD, + ItemAttributeModifiers.EquipmentSlotGroup.CHEST, + ItemAttributeModifiers.EquipmentSlotGroup.LEGS, + ItemAttributeModifiers.EquipmentSlotGroup.FEET + }; private static final DecimalFormat ATTRIBUTE_FORMAT = new DecimalFormat("0.#####"); static { @@ -132,8 +138,10 @@ public final class ItemTranslator { private static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, Item javaItem, ItemMapping bedrockItem, int count, @Nullable DataComponents components) { BedrockItemBuilder nbtBuilder = new BedrockItemBuilder(); + boolean hideTooltips = false; if (components != null) { javaItem.translateComponentsToBedrock(session, components, nbtBuilder); + if (components.get(DataComponentType.HIDE_TOOLTIP) != null) hideTooltips = true; } String customName = getCustomName(session, components, bedrockItem); @@ -143,13 +151,13 @@ public final class ItemTranslator { if (components != null) { ItemAttributeModifiers attributeModifiers = components.get(DataComponentType.ATTRIBUTE_MODIFIERS); - if (attributeModifiers != null && attributeModifiers.isShowInTooltip()) { + if (attributeModifiers != null && attributeModifiers.isShowInTooltip() && !hideTooltips) { // only add if attribute modifiers do not indicate to hide them addAttributeLore(attributeModifiers, nbtBuilder, session.locale()); } } - if (session.isAdvancedTooltips()) { + if (session.isAdvancedTooltips() && !hideTooltips) { addAdvancedTooltips(components, nbtBuilder, javaItem, session.locale()); } @@ -207,7 +215,12 @@ public final class ItemTranslator { } ItemAttributeModifiers.EquipmentSlotGroup slotGroup = entry.getSlot(); - if (slotGroup == ItemAttributeModifiers.EquipmentSlotGroup.ANY) { + if (slotGroup == ItemAttributeModifiers.EquipmentSlotGroup.ARMOR) { + // modifier applies to all armor slots + for (ItemAttributeModifiers.EquipmentSlotGroup slot : ARMOR_SLOT_NAMES) { + slotsToModifiers.computeIfAbsent(slot, s -> new ArrayList<>()).add(loreEntry); + } + } else if (slotGroup == ItemAttributeModifiers.EquipmentSlotGroup.ANY) { // modifier applies to all slots implicitly for (var slot : SLOT_NAMES.keySet()) { slotsToModifiers.computeIfAbsent(slot, s -> new ArrayList<>()).add(loreEntry); From 1efb633723f601ce4130df8a0ca9dc3a4fe321e6 Mon Sep 17 00:00:00 2001 From: basaigh <53559772+basaigh@users.noreply.github.com> Date: Sun, 16 Jun 2024 22:05:28 +0100 Subject: [PATCH 266/272] Bump MCPL (#4756) --- .../java/level/JavaLevelEventTranslator.java | 52 +++++++++---------- core/src/main/resources/mappings | 2 +- gradle/libs.versions.toml | 4 +- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelEventTranslator.java index 2d3bca0d4..d4e317af4 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelEventTranslator.java @@ -57,7 +57,7 @@ public class JavaLevelEventTranslator extends PacketTranslator { + case PARTICLES_AND_SOUND_BRUSH_BLOCK_COMPLETE -> { effectPacket.setType(ParticleType.BRUSH_DUST); session.playSoundEvent(SoundEvent.BRUSH_COMPLETED, pos); // todo 1.20.2 verify this } - case COMPOSTER -> { + case COMPOSTER_FILL -> { effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_CROP_GROWTH); ComposterEventData composterEventData = (ComposterEventData) packet.getData(); @@ -146,7 +146,7 @@ public class JavaLevelEventTranslator extends PacketTranslator { + case LAVA_FIZZ -> { effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_EVAPORATE); effectPacket.setPosition(pos.add(-0.5f, 0.7f, -0.5f)); @@ -159,7 +159,7 @@ public class JavaLevelEventTranslator extends PacketTranslator { + case REDSTONE_TORCH_BURNOUT -> { effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_EVAPORATE); effectPacket.setPosition(pos.add(-0.5f, 0, -0.5f)); @@ -172,7 +172,7 @@ public class JavaLevelEventTranslator extends PacketTranslator { + case END_PORTAL_FRAME_FILL -> { effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_EVAPORATE); effectPacket.setPosition(pos.add(-0.5f, 0.3125f, -0.5f)); @@ -185,8 +185,8 @@ public class JavaLevelEventTranslator extends PacketTranslator { - if (levelEvent == LevelEventType.SMOKE) { + case PARTICLES_SHOOT_SMOKE, PARTICLES_SHOOT_WHITE_SMOKE -> { + if (levelEvent == LevelEventType.PARTICLES_SHOOT_SMOKE) { effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_SHOOT); } else { effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_SHOOT_WHITE_SMOKE); @@ -225,13 +225,13 @@ public class JavaLevelEventTranslator extends PacketTranslator { + case PARTICLES_DESTROY_BLOCK -> { effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_DESTROY_BLOCK); BreakBlockEventData breakBlockEventData = (BreakBlockEventData) packet.getData(); effectPacket.setData(session.getBlockMappings().getBedrockBlockId(breakBlockEventData.getBlockState())); } - case BREAK_SPLASH_POTION, BREAK_SPLASH_POTION2 -> { + case PARTICLES_SPELL_POTION_SPLASH, PARTICLES_INSTANT_POTION_SPLASH -> { effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_POTION_SPLASH); effectPacket.setPosition(pos.add(0, -0.5f, 0)); @@ -247,16 +247,16 @@ public class JavaLevelEventTranslator extends PacketTranslator effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_EYE_OF_ENDER_DEATH); - case MOB_SPAWN -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_MOB_BLOCK_SPAWN); // TODO: Check, but I don't think I really verified this ever went into effect on Java - case BONEMEAL_GROW_WITH_SOUND, BONEMEAL_GROW -> { - effectPacket.setType(levelEvent == LevelEventType.BONEMEAL_GROW ? org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_TURTLE_EGG : org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_CROP_GROWTH); + case PARTICLES_EYE_OF_ENDER_DEATH -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_EYE_OF_ENDER_DEATH); + case PARTICLES_MOBBLOCK_SPAWN -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_MOB_BLOCK_SPAWN); // TODO: Check, but I don't think I really verified this ever went into effect on Java + case PARTICLES_AND_SOUND_PLANT_GROWTH -> { + effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_CROP_GROWTH); BonemealGrowEventData growEventData = (BonemealGrowEventData) packet.getData(); effectPacket.setData(growEventData.getParticleCount()); } - case EGG_CRACK -> effectPacket.setType(ParticleType.VILLAGER_HAPPY); // both the lil green sparkle - case ENDERDRAGON_FIREBALL_EXPLODE -> { + case PARTICLES_EGG_CRACK -> effectPacket.setType(ParticleType.VILLAGER_HAPPY); // both the lil green sparkle + case PARTICLES_DRAGON_FIREBALL_SPLASH -> { effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_EYE_OF_ENDER_DEATH); // TODO DragonFireballEventData fireballEventData = (DragonFireballEventData) packet.getData(); @@ -271,15 +271,15 @@ public class JavaLevelEventTranslator extends PacketTranslator { + case PARTICLES_DRAGON_BLOCK_BREAK -> { effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_GENERIC_SPAWN); effectPacket.setData(61); } - case EVAPORATE -> { + case PARTICLES_WATER_EVAPORATING -> { effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_EVAPORATE_WATER); effectPacket.setPosition(pos.add(-0.5f, 0.5f, -0.5f)); } - case END_GATEWAY_SPAWN -> { + case ANIMATION_END_GATEWAY_SPAWN -> { effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_EXPLOSION); LevelSoundEventPacket soundEventPacket = new LevelSoundEventPacket(); @@ -292,11 +292,11 @@ public class JavaLevelEventTranslator extends PacketTranslator effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_DRIPSTONE_DRIP); - case ELECTRIC_SPARK -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_ELECTRIC_SPARK); // Matches with a Bedrock server but doesn't seem to match up with Java - case WAX_ON -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_WAX_ON); - case WAX_OFF -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_WAX_OFF); - case SCRAPE -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_SCRAPE); - case SCULK_BLOCK_CHARGE -> { + case PARTICLES_ELECTRIC_SPARK -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_ELECTRIC_SPARK); // Matches with a Bedrock server but doesn't seem to match up with Java + case PARTICLES_AND_SOUND_WAX_ON -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_WAX_ON); + case PARTICLES_WAX_OFF -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_WAX_OFF); + case PARTICLES_SCRAPE -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_SCRAPE); + case PARTICLES_SCULK_CHARGE -> { SculkBlockChargeEventData eventData = (SculkBlockChargeEventData) packet.getData(); LevelEventGenericPacket levelEventPacket = new LevelEventGenericPacket(); // TODO add SCULK_BLOCK_CHARGE sound @@ -324,7 +324,7 @@ public class JavaLevelEventTranslator extends PacketTranslator { + case PARTICLES_SCULK_SHRIEK -> { LevelEventGenericPacket levelEventPacket = new LevelEventGenericPacket(); levelEventPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_SCULK_SHRIEK); levelEventPacket.setTag( @@ -346,7 +346,7 @@ public class JavaLevelEventTranslator extends PacketTranslator { + case SOUND_STOP_JUKEBOX_SONG -> { String bedrockSound = session.getWorldCache().removeActiveRecord(origin); if (bedrockSound == null) { // Vanilla record diff --git a/core/src/main/resources/mappings b/core/src/main/resources/mappings index 2ac0c1415..420cbe173 160000 --- a/core/src/main/resources/mappings +++ b/core/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 2ac0c1415cb9063c405dbd7e14f2d426a0ba1180 +Subproject commit 420cbe173ffa0667d4607715f9e3d43402e1ab77 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1456a7e34..23cd00a97 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,7 +13,7 @@ websocket = "1.5.1" protocol = "3.0.0.Beta2-20240616.144648-10" raknet = "1.0.0.CR3-20240416.144209-1" mcauthlib = "e5b0bcc" -mcprotocollib = "4f5f650" +mcprotocollib = "1.21-20240616.154144-5" adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" @@ -107,7 +107,7 @@ guava = { group = "com.google.guava", name = "guava", version.ref = "guava" } gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" } junit = { group = "org.junit.jupiter", name = "junit-jupiter", version.ref = "junit" } mcauthlib = { group = "com.github.GeyserMC", name = "MCAuthLib", version.ref = "mcauthlib" } -mcprotocollib = { group = "com.github.GeyserMC", name = "mcprotocollib", version.ref = "mcprotocollib" } +mcprotocollib = { group = "org.geysermc.mcprotocollib", name = "protocol", version.ref = "mcprotocollib" } raknet = { group = "org.cloudburstmc.netty", name = "netty-transport-raknet", version.ref = "raknet" } terminalconsoleappender = { group = "net.minecrell", name = "terminalconsoleappender", version.ref = "terminalconsoleappender" } velocity-api = { group = "com.velocitypowered", name = "velocity-api", version.ref = "velocity" } From 63a3da7c564de2786cafedc60dd13e13d8ae6c92 Mon Sep 17 00:00:00 2001 From: Eclipse <116838833+eclipseisoffline@users.noreply.github.com> Date: Sun, 16 Jun 2024 23:35:18 +0000 Subject: [PATCH 267/272] Fix reading custom jukebox songs (#4757) * Read sound event objects properly in jukebox song * Add debug log for unexpected sound event type --- .../java/org/geysermc/geyser/level/JukeboxSong.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/level/JukeboxSong.java b/core/src/main/java/org/geysermc/geyser/level/JukeboxSong.java index fd6ce693d..156a62cd1 100644 --- a/core/src/main/java/org/geysermc/geyser/level/JukeboxSong.java +++ b/core/src/main/java/org/geysermc/geyser/level/JukeboxSong.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.level; import org.cloudburstmc.nbt.NbtMap; +import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; @@ -33,7 +34,16 @@ public record JukeboxSong(String soundEvent, String description) { public static JukeboxSong read(RegistryEntry entry) { NbtMap data = entry.getData(); - String soundEvent = data.getString("sound_event"); + Object soundEventObject = data.get("sound_event"); + String soundEvent; + if (soundEventObject instanceof NbtMap map) { + soundEvent = map.getString("sound_id"); + } else if (soundEventObject instanceof String string) { + soundEvent = string; + } else { + soundEvent = ""; + GeyserImpl.getInstance().getLogger().debug("Sound event for " + entry.getId() + " was of an unexpected type! Expected string or NBT map, got " + soundEventObject); + } String description = MessageTranslator.deserializeDescription(data); return new JukeboxSong(soundEvent, description); } From deb25d7147360285f2753825fb6f8765a406327c Mon Sep 17 00:00:00 2001 From: basaigh <53559772+basaigh@users.noreply.github.com> Date: Mon, 17 Jun 2024 13:17:57 +0100 Subject: [PATCH 268/272] Bump mappings to fix effects error on startup (#4760) --- core/src/main/resources/mappings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/resources/mappings b/core/src/main/resources/mappings index 420cbe173..ff44a3257 160000 --- a/core/src/main/resources/mappings +++ b/core/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 420cbe173ffa0667d4607715f9e3d43402e1ab77 +Subproject commit ff44a32574d0cac242aa99d8f97af0b5c636c0cf From 29928c2d830838cba51a8ba1f6e2d11fff218cd9 Mon Sep 17 00:00:00 2001 From: chris Date: Mon, 17 Jun 2024 18:46:57 +0200 Subject: [PATCH 269/272] Sanity check for shulker boxes (#4762) --- .../org/geysermc/geyser/level/block/type/BlockState.java | 9 +++++++++ .../block/entity/ShulkerBoxBlockEntityTranslator.java | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java b/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java index 36c31f32e..2a4b1774d 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/BlockState.java @@ -73,6 +73,15 @@ public final class BlockState { return (Boolean) value; } + public > T getValue(Property property, T def) { + var value = get(property); + if (value == null) { + return def; + } + //noinspection unchecked + return (T) value; + } + @Nullable private Comparable get(Property property) { Property[] keys = this.block.propertyKeys(); diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/ShulkerBoxBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/ShulkerBoxBlockEntityTranslator.java index e6d19e492..cac40b350 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/ShulkerBoxBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/ShulkerBoxBlockEntityTranslator.java @@ -30,6 +30,7 @@ import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.type.BlockState; +import org.geysermc.geyser.level.physics.Direction; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.inventory.ShulkerInventoryTranslator; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; @@ -42,6 +43,6 @@ public class ShulkerBoxBlockEntityTranslator extends BlockEntityTranslator imple */ @Override public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, @Nullable NbtMap javaNbt, BlockState blockState) { - bedrockNbt.putByte("facing", (byte) blockState.getValue(Properties.FACING).ordinal()); + bedrockNbt.putByte("facing", (byte) blockState.getValue(Properties.FACING, Direction.UP).ordinal()); } } From 77fa37ff828cf31fc09710a5f4c9e57ab2c88944 Mon Sep 17 00:00:00 2001 From: chris Date: Mon, 17 Jun 2024 21:31:54 +0200 Subject: [PATCH 270/272] Fix: readme not being synched to modrinth, publish spigot/bungee/velocity variants to modrinth (#4761) * Fix: readme not being synched to modrinth * use new build_number system env var * also upload bungee/spigot/velocity * change name * undo debug mode, oops --- .github/workflows/build.yml | 11 ++------ bootstrap/bungeecord/build.gradle.kts | 5 ++++ bootstrap/mod/build.gradle.kts | 7 +++++ bootstrap/mod/fabric/build.gradle.kts | 1 + bootstrap/mod/neoforge/build.gradle.kts | 1 + bootstrap/spigot/build.gradle.kts | 5 ++++ bootstrap/velocity/build.gradle.kts | 5 ++++ build-logic/build.gradle.kts | 3 +++ build-logic/src/main/kotlin/LibsAccessor.kt | 6 +++++ .../geyser.modded-conventions.gradle.kts | 27 +++++-------------- ....modrinth-uploading-conventions.gradle.kts | 18 +++++++++++++ build.gradle.kts | 14 ++++++++++ gradle/libs.versions.toml | 5 ++-- 13 files changed, 76 insertions(+), 32 deletions(-) create mode 100644 build-logic/src/main/kotlin/LibsAccessor.kt create mode 100644 build-logic/src/main/kotlin/geyser.modrinth-uploading-conventions.gradle.kts diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0e94ce965..ccc4dd79c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -103,19 +103,12 @@ jobs: bootstrap/viaproxy/build/libs/Geyser-ViaProxy.jar changelog: ${{ steps.metadata.outputs.body }} - - name: Publish to Modrinth (Fabric) + - name: Publish to Modrinth if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} env: BUILD_NUMBER: ${{ steps.release-info.outputs.curentRelease }} MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }} - run: ./gradlew fabric:modrinth - - - name: Publish to Modrinth (NeoForge) - if: ${{ success() && github.repository == 'GeyserMC/Geyser' && github.ref_name == 'master' }} - env: - BUILD_NUMBER: ${{ steps.release-info.outputs.curentRelease }} - MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }} - run: ./gradlew neoforge:modrinth + run: ./gradlew modrinth - name: Notify Discord if: ${{ (success() || failure()) && github.repository == 'GeyserMC/Geyser' }} diff --git a/bootstrap/bungeecord/build.gradle.kts b/bootstrap/bungeecord/build.gradle.kts index e93c096a1..910e50723 100644 --- a/bootstrap/bungeecord/build.gradle.kts +++ b/bootstrap/bungeecord/build.gradle.kts @@ -34,3 +34,8 @@ tasks.withType { exclude(dependency("io.netty:netty-resolver-dns:.*")) } } + +modrinth { + uploadFile.set(tasks.getByPath("shadowJar")) + loaders.add("bungeecord") +} diff --git a/bootstrap/mod/build.gradle.kts b/bootstrap/mod/build.gradle.kts index 7651a2df2..32224d00b 100644 --- a/bootstrap/mod/build.gradle.kts +++ b/bootstrap/mod/build.gradle.kts @@ -6,6 +6,13 @@ loom { mixin.defaultRefmapName.set("geyser-refmap.json") } +afterEvaluate { + // We don't need these + tasks.named("remapModrinthJar").configure { + enabled = false + } +} + dependencies { api(projects.core) compileOnly(libs.mixin) diff --git a/bootstrap/mod/fabric/build.gradle.kts b/bootstrap/mod/fabric/build.gradle.kts index cd513c1e4..25bd0af9d 100644 --- a/bootstrap/mod/fabric/build.gradle.kts +++ b/bootstrap/mod/fabric/build.gradle.kts @@ -63,6 +63,7 @@ tasks { modrinth { loaders.add("fabric") + uploadFile.set(tasks.getByPath("remapModrinthJar")) dependencies { required.project("fabric-api") } diff --git a/bootstrap/mod/neoforge/build.gradle.kts b/bootstrap/mod/neoforge/build.gradle.kts index 92ffae7e5..e0e7c2dfa 100644 --- a/bootstrap/mod/neoforge/build.gradle.kts +++ b/bootstrap/mod/neoforge/build.gradle.kts @@ -55,4 +55,5 @@ tasks { modrinth { loaders.add("neoforge") + uploadFile.set(tasks.getByPath("remapModrinthJar")) } \ No newline at end of file diff --git a/bootstrap/spigot/build.gradle.kts b/bootstrap/spigot/build.gradle.kts index 7ccb50484..fcb85f100 100644 --- a/bootstrap/spigot/build.gradle.kts +++ b/bootstrap/spigot/build.gradle.kts @@ -76,3 +76,8 @@ tasks.withType { exclude(dependency("com.mojang:.*")) } } + +modrinth { + uploadFile.set(tasks.getByPath("shadowJar")) + loaders.addAll("spigot", "paper") +} diff --git a/bootstrap/velocity/build.gradle.kts b/bootstrap/velocity/build.gradle.kts index da826803c..4daad9784 100644 --- a/bootstrap/velocity/build.gradle.kts +++ b/bootstrap/velocity/build.gradle.kts @@ -69,4 +69,9 @@ tasks.withType { exclude(dependency("net.kyori:adventure-text-serializer-legacy:.*")) exclude(dependency("net.kyori:adventure-nbt:.*")) } +} + +modrinth { + uploadFile.set(tasks.getByPath("shadowJar")) + loaders.addAll("velocity") } \ No newline at end of file diff --git a/build-logic/build.gradle.kts b/build-logic/build.gradle.kts index b7aab2bf0..190386667 100644 --- a/build-logic/build.gradle.kts +++ b/build-logic/build.gradle.kts @@ -12,6 +12,9 @@ repositories { } dependencies { + // this is OK as long as the same version catalog is used in the main build and build-logic + // see https://github.com/gradle/gradle/issues/15383#issuecomment-779893192 + implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location)) implementation(libs.indra) implementation(libs.shadow) implementation(libs.architectury.plugin) diff --git a/build-logic/src/main/kotlin/LibsAccessor.kt b/build-logic/src/main/kotlin/LibsAccessor.kt new file mode 100644 index 000000000..2a0c09eb6 --- /dev/null +++ b/build-logic/src/main/kotlin/LibsAccessor.kt @@ -0,0 +1,6 @@ +import org.gradle.accessors.dm.LibrariesForLibs +import org.gradle.api.Project +import org.gradle.kotlin.dsl.getByType + +val Project.libs: LibrariesForLibs + get() = rootProject.extensions.getByType() \ No newline at end of file diff --git a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts index 86c2a2f6a..7952bcf14 100644 --- a/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/geyser.modded-conventions.gradle.kts @@ -8,7 +8,6 @@ plugins { id("geyser.publish-conventions") id("architectury-plugin") id("dev.architectury.loom") - id("com.modrinth.minotaur") } // These are provided by Minecraft/modded platforms already, no need to include them @@ -39,7 +38,7 @@ provided("io.netty", "netty-resolver-dns-native-macos") provided("org.ow2.asm", "asm") architectury { - minecraft = "1.20.5" + minecraft = libs.minecraft.get().version as String } loom { @@ -83,7 +82,7 @@ tasks { register("remapModrinthJar", RemapJarTask::class) { dependsOn(shadowJar) inputFile.set(shadowJar.get().archiveFile) - archiveVersion.set(project.version.toString() + "+build." + System.getenv("GITHUB_RUN_NUMBER")) + archiveVersion.set(project.version.toString() + "+build." + System.getenv("BUILD_NUMBER")) archiveClassifier.set("") } } @@ -93,7 +92,7 @@ afterEvaluate { // These are shaded, no need to JiJ them configurations["shadow"].dependencies.forEach {shadowed -> - println("Not including shadowed dependency: ${shadowed.group}:${shadowed.name}") + //println("Not including shadowed dependency: ${shadowed.group}:${shadowed.name}") providedDependencies.add("${shadowed.group}:${shadowed.name}") } @@ -101,16 +100,16 @@ afterEvaluate { configurations["includeTransitive"].resolvedConfiguration.resolvedArtifacts.forEach { dep -> if (!providedDependencies.contains("${dep.moduleVersion.id.group}:${dep.moduleVersion.id.name}") and !providedDependencies.contains("${dep.moduleVersion.id.group}:.*")) { - println("Including dependency via JiJ: ${dep.id}") + //println("Including dependency via JiJ: ${dep.id}") dependencies.add("include", dep.moduleVersion.id.toString()) } else { - println("Not including ${dep.id} for ${project.name}!") + //println("Not including ${dep.id} for ${project.name}!") } } } dependencies { - minecraft("com.mojang:minecraft:1.21") + minecraft(libs.minecraft) mappings(loom.officialMojangMappings()) } @@ -121,18 +120,4 @@ repositories { maven("https://oss.sonatype.org/content/repositories/snapshots/") maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") maven("https://maven.neoforged.net/releases") -} - -modrinth { - token.set(System.getenv("MODRINTH_TOKEN")) // Even though this is the default value, apparently this prevents GitHub Actions caching the token? - projectId.set("wKkoqHrH") - versionNumber.set(project.version as String + "-" + System.getenv("GITHUB_RUN_NUMBER")) - versionType.set("beta") - changelog.set("A changelog can be found at https://github.com/GeyserMC/Geyser/commits") - - syncBodyFrom.set(rootProject.file("README.md").readText()) - - uploadFile.set(tasks.getByPath("remapModrinthJar")) - gameVersions.addAll("1.21") - failSilently.set(true) } \ No newline at end of file diff --git a/build-logic/src/main/kotlin/geyser.modrinth-uploading-conventions.gradle.kts b/build-logic/src/main/kotlin/geyser.modrinth-uploading-conventions.gradle.kts new file mode 100644 index 000000000..a4a8cd7d6 --- /dev/null +++ b/build-logic/src/main/kotlin/geyser.modrinth-uploading-conventions.gradle.kts @@ -0,0 +1,18 @@ +plugins { + id("com.modrinth.minotaur") +} + +// Ensure that the readme is synched +tasks.modrinth.get().dependsOn(tasks.modrinthSyncBody) + +modrinth { + token.set(System.getenv("MODRINTH_TOKEN") ?: "") // Even though this is the default value, apparently this prevents GitHub Actions caching the token? + projectId.set("geyser") + versionNumber.set(project.version as String + "-" + System.getenv("BUILD_NUMBER")) + versionType.set("beta") + changelog.set("A changelog can be found at https://github.com/GeyserMC/Geyser/commits") + gameVersions.add(libs.minecraft.get().version as String) + failSilently.set(true) + + syncBodyFrom.set(rootProject.file("README.md").readText()) +} \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index dfdff2187..dfbf9837f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -26,6 +26,14 @@ val moddedPlatforms = setOf( projects.mod ).map { it.dependencyProject } +val modrinthPlatforms = setOf( + projects.bungeecord, + projects.fabric, + projects.neoforge, + projects.spigot, + projects.velocity +).map { it.dependencyProject } + subprojects { apply { plugin("java-library") @@ -38,4 +46,10 @@ subprojects { in moddedPlatforms -> plugins.apply("geyser.modded-conventions") else -> plugins.apply("geyser.base-conventions") } + + // Not combined with platform-conventions as that also contains + // platforms which we cant publish to modrinth + if (modrinthPlatforms.contains(this)) { + plugins.apply("geyser.modrinth-uploading-conventions") + } } \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 23cd00a97..784f30053 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -28,12 +28,12 @@ commodore = "2.2" bungeecord = "a7c6ede" velocity = "3.3.0-SNAPSHOT" viaproxy = "3.2.1" -fabric-minecraft = "1.21" fabric-loader = "0.15.11" fabric-api = "0.100.1+1.21" fabric-permissions = "0.2-SNAPSHOT" neoforge-minecraft = "21.0.0-beta" mixin = "0.8.5" +minecraft = "1.21" # plugin versions indra = "3.1.3" @@ -90,8 +90,9 @@ paper-mojangapi = { group = "io.papermc.paper", name = "paper-mojangapi", versio mixin = { group = "org.spongepowered", name = "mixin", version.ref = "mixin" } +minecraft = { group = "com.mojang", name = "minecraft", version.ref = "minecraft" } + # Check these on https://modmuss50.me/fabric.html -fabric-minecraft = { group = "com.mojang", name = "minecraft", version.ref = "fabric-minecraft" } fabric-loader = { group = "net.fabricmc", name = "fabric-loader", version.ref = "fabric-loader" } fabric-api = { group = "net.fabricmc.fabric-api", name = "fabric-api", version.ref = "fabric-api" } fabric-permissions = { group = "me.lucko", name = "fabric-permissions-api", version.ref = "fabric-permissions" } From a9300fb1ab0a0cf281be6a777eeab16354520f95 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Tue, 18 Jun 2024 15:30:19 -0400 Subject: [PATCH 271/272] Vault: show some components in block entity (enchantments, potion types) --- .../geyser/inventory/item/Potion.java | 9 +++ .../translator/item/ItemTranslator.java | 2 +- .../entity/VaultBlockEntityTranslator.java | 57 ++++++++++++++++++- 3 files changed, 64 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java b/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java index c4d20c623..129c365a9 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/item/Potion.java @@ -102,6 +102,15 @@ public enum Potion { return new PotionContents(this.ordinal(), -1, Collections.emptyList()); } + public static Potion getByJavaIdentifier(String javaIdentifier) { + for (Potion potion : VALUES) { + if (potion.javaIdentifier.equals(javaIdentifier)) { + return potion; + } + } + return null; + } + public static @Nullable Potion getByJavaId(int javaId) { if (javaId >= 0 && javaId < VALUES.length) { return VALUES[javaId]; diff --git a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java index 7572f5e61..a8d29c465 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/item/ItemTranslator.java @@ -135,7 +135,7 @@ public final class ItemTranslator { .build(); } - private static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, Item javaItem, ItemMapping bedrockItem, int count, @Nullable DataComponents components) { + public static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, Item javaItem, ItemMapping bedrockItem, int count, @Nullable DataComponents components) { BedrockItemBuilder nbtBuilder = new BedrockItemBuilder(); boolean hideTooltips = false; diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/VaultBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/VaultBlockEntityTranslator.java index 50fd64202..81be5b33a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/VaultBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/VaultBlockEntityTranslator.java @@ -25,20 +25,32 @@ package org.geysermc.geyser.translator.level.block.entity; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.LongArrayList; import it.unimi.dsi.fastutil.longs.LongList; import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; +import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; +import org.cloudburstmc.protocol.common.util.TriConsumer; import org.geysermc.geyser.entity.type.player.PlayerEntity; +import org.geysermc.geyser.inventory.item.Potion; +import org.geysermc.geyser.item.enchantment.Enchantment; import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.item.BedrockItemBuilder; +import org.geysermc.geyser.translator.item.ItemTranslator; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.UUID; @BlockEntity(type = BlockEntityType.VAULT) @@ -67,9 +79,25 @@ public class VaultBlockEntityTranslator extends BlockEntityTranslator { .putByte("WasPickedUp", (byte) 0).build()); } else { int count = item.getInt("count"); - NbtMapBuilder bedrockItem = BedrockItemBuilder.createItemNbt(mapping, count, mapping.getBedrockData()); - // TODO handle components... - bedrockNbt.putCompound("display_item", bedrockItem.build()); + NbtMap componentsTag = item.getCompound("components"); + NbtMapBuilder itemAsNbt; + if (!componentsTag.isEmpty()) { + DataComponents components = new DataComponents(new HashMap<>()); + for (Map.Entry entry : componentsTag.entrySet()) { + var consumer = DATA_COMPONENT_DECODERS.get(entry.getKey()); + if (consumer != null) { + consumer.accept(session, (NbtMap) entry.getValue(), components); + } + } + ItemData bedrockItem = ItemTranslator.translateToBedrock(session, mapping.getJavaItem(), mapping, count, components).build(); + itemAsNbt = BedrockItemBuilder.createItemNbt(mapping, bedrockItem.getCount(), bedrockItem.getDamage()); + if (bedrockItem.getTag() != null) { + itemAsNbt.putCompound("tag", bedrockItem.getTag()); + } + } else { + itemAsNbt = BedrockItemBuilder.createItemNbt(mapping, count, mapping.getBedrockData()); + } + bedrockNbt.putCompound("display_item", itemAsNbt.build()); } List connectedPlayers = sharedData.getList("connected_players", NbtType.INT_ARRAY); @@ -96,4 +124,27 @@ public class VaultBlockEntityTranslator extends BlockEntityTranslator { private static UUID uuidFromIntArray(int[] parts) { return new UUID((long) parts[0] << 32 | (parts[1] & 0xFFFFFFFFL), (long) parts[2] << 32 | (parts[3] & 0xFFFFFFFFL)); } + + // This might be easier to maintain in the long run so items don't have two translate methods. + // Also, it's not out of the question that block entities get the data component treatment, likely rendering this useless. + // The goal is to just translate the basics so clients know what potion is roughly present, and that any enchantment even exists. + private static final Map> DATA_COMPONENT_DECODERS = Map.of( + "minecraft:potion_contents", (session, tag, components) -> { + String potionId = tag.getString("potion"); + Potion potion = Potion.getByJavaIdentifier(potionId); + components.put(DataComponentType.POTION_CONTENTS, potion.toComponent()); + }, + "minecraft:enchantments", (session, tag, components) -> { // Enchanted books already have glint. Translating them doesn't matter. + NbtMap levels = tag.getCompound("levels"); + List enchantmentRegistry = session.getRegistryCache().enchantments().values(); + Int2ObjectMap enchantments = new Int2ObjectOpenHashMap<>(levels.size()); + for (Map.Entry entry : levels.entrySet()) { + for (int i = 0; i < enchantmentRegistry.size(); i++) { + if (enchantmentRegistry.get(i).identifier().equals(entry.getKey())) { + enchantments.put(i, (Integer) entry.getValue()); + } + } + } + components.put(DataComponentType.ENCHANTMENTS, new ItemEnchantments(enchantments, true)); + }); } From 6884a0f7db8a0edd078f1367cda0600402aac198 Mon Sep 17 00:00:00 2001 From: chris Date: Wed, 19 Jun 2024 02:37:34 +0200 Subject: [PATCH 272/272] Fix: norwegian locale handling (#4716) --- .../main/java/org/geysermc/geyser/text/GeyserLocale.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/src/main/java/org/geysermc/geyser/text/GeyserLocale.java b/core/src/main/java/org/geysermc/geyser/text/GeyserLocale.java index cfe950409..28fd6f9a4 100644 --- a/core/src/main/java/org/geysermc/geyser/text/GeyserLocale.java +++ b/core/src/main/java/org/geysermc/geyser/text/GeyserLocale.java @@ -259,6 +259,13 @@ public class GeyserLocale { // Invalid locale return locale; } + + // See https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes - covers the special case that is norwegian + String lowerCaseLocale = locale.toLowerCase(Locale.ROOT); + if (lowerCaseLocale.equals("nn_no") || lowerCaseLocale.equals("no_no")) { + locale = "nb_NO"; + } + String language = locale.substring(0, 2); String country = locale.substring(3); return language.toLowerCase(Locale.ENGLISH) + "_" + country.toUpperCase(Locale.ENGLISH);